+
+/**
+ * paraslash's wrapper for select(2)
+ *
+ * It calls select(2) (with no exceptfds) and starts over if select() was
+ * interrupted by a signal.
+ *
+ * \param n the highest-numbered descriptor in any of the two sets, plus 1
+ * \param readfds fds that should be checked for readability
+ * \param writefds fds that should be checked for writablility
+ * \param timeout upper bound on the amount of time elapsed before select()
+ * returns
+ *
+ * \return The return value of the underlying select() call.
+ *
+ * All arguments are passed verbatim to select(2).
+ * \sa select(2) select_tut(2)
+ */
+int para_select(int n, fd_set *readfds, fd_set *writefds,
+ struct timeval *timeout)
+{
+ int ret, err;
+ do {
+ ret = select(n, readfds, writefds, NULL, timeout);
+ err = errno;
+ } while (ret < 0 && err == EINTR);
+ if (ret < 0)
+ PARA_CRIT_LOG("select error (%s)\n", strerror(err));
+ return ret;
+}
+
+/**
+ * set a file descriptor to non-blocking mode
+ *
+ * \param fd The file descriptor
+ *
+ * \returns 1 on success, -E_F_GETFL, -E_F_SETFL, on errors.
+ */
+int mark_fd_nonblock(int fd)
+{
+ int flags = fcntl(fd, F_GETFL);
+ if (flags < 0)
+ return -E_F_GETFL;
+ if (fcntl(fd, F_SETFL, ((long)flags) | O_NONBLOCK) < 0)
+ return -E_F_SETFL;
+ return 1;
+}
+
+/**
+ * set a file descriptor in a fd_set
+ *
+ * \param fd the file descriptor to be set
+ * \param fds the file descriptor set
+ * \param max_fileno highest-numbered file descriptor
+ *
+ * This wrapper for FD_SET() passes its first two arguments to \p FD_SET. Upon
+ * return, \a max_fileno contains the maximum of the old_value and \a fd.
+*/
+void para_fd_set(int fd, fd_set *fds, int *max_fileno)
+{
+ FD_SET(fd, fds);
+ *max_fileno = PARA_MAX(*max_fileno, fd);
+}