+
+/**
+ * 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;
+}