README: Kill "obligatory" and "optional" tags.
[paraslash.git] / fd.c
diff --git a/fd.c b/fd.c
index 83c6cd5..ecd87cd 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -281,11 +281,17 @@ int para_mkdir(const char *path, mode_t mode)
 }
 
 /**
 }
 
 /**
- * Map a file into memory.
+ * Open a file and map it into memory.
  *
  * \param path Name of the regular file to map.
  * \param open_mode Either \p O_RDONLY or \p O_RDWR.
  *
  * \param path Name of the regular file to map.
  * \param open_mode Either \p O_RDONLY or \p O_RDWR.
- * \param obj On success, the mapping is returned here.
+ * \param map On success, the mapping is returned here.
+ * \param size size of the mapping.
+ * \param fd_ptr The file descriptor of the mapping.
+ *
+ * If \a fd_ptr is \p NULL, the file descriptor resulting from the underlying
+ * open call is closed after mmap().  Otherwise the file is kept open and the
+ * file descriptor is returned in \a fd_ptr.
  *
  * \return Positive on success, negative on errors. Possible errors include: \p
  * E_FSTAT, any errors returned by para_open(), \p E_EMPTY, \p E_MMAP.
  *
  * \return Positive on success, negative on errors. Possible errors include: \p
  * E_FSTAT, any errors returned by para_open(), \p E_EMPTY, \p E_MMAP.
@@ -332,3 +338,47 @@ out:
                *fd_ptr = fd;
        return ret;
 }
                *fd_ptr = fd;
        return ret;
 }
+
+/**
+ * A wrapper for munmap(2).
+ *
+ * \param start The start address of the memory mapping.
+ * \param length The size of the mapping.
+ *
+ * \return Positive on success, \p -E_MUNMAP on errors.
+ *
+ * \sa munmap(2), mmap_full_file().
+ */
+int para_munmap(void *start, size_t length)
+{
+       if (munmap(start, length) >= 0)
+               return 1;
+       PARA_ERROR_LOG("munmap (%p/%zu) failed: %s\n", start, length,
+               strerror(errno));
+       return -E_MUNMAP;
+}
+
+/**
+ * check a file descriptor for writability
+ *
+ * \param fd the file descriptor
+ *
+ * \return positive if fd is ready for writing, zero if it isn't, negative if
+ * an error occurred.
+ */
+
+int write_ok(int fd)
+{
+       struct timeval tv = {0, 0};
+       fd_set wfds;
+       int ret;
+again:
+       FD_ZERO(&wfds);
+       FD_SET(fd, &wfds);
+       tv.tv_sec = 0;
+       tv.tv_usec = 0;
+       ret = select(fd + 1, NULL, &wfds, NULL, &tv);
+       if (ret < 0 && errno == EINTR)
+               goto again;
+       return ret;
+}