]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - fd.c
interactive: Avoid select(2) in input_available().
[paraslash.git] / fd.c
diff --git a/fd.c b/fd.c
index 33891d2e6c9f1c3568428b1df93b4b92e295ef61..63c0337b348e10705a92f53492d5ff4491ab4ac1 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -6,6 +6,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/mman.h>
+#include <poll.h>
 
 #include "para.h"
 #include "error.h"
@@ -334,8 +335,7 @@ bool file_exists(const char *fn)
  * \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_tv upper bound on the amount of time elapsed before select()
- * returns.
+ * \param timeout Upper bound in milliseconds.
  *
  * \return The return value of the underlying select() call on success, the
  * negative system error code on errors.
@@ -343,12 +343,14 @@ bool file_exists(const char *fn)
  * 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_tv)
+int para_select(int n, fd_set *readfds, fd_set *writefds, int timeout)
 {
        int ret;
+       struct timeval tv;
+
+       ms2tv(timeout, &tv);
        do
-               ret = select(n, readfds, writefds, NULL, timeout_tv);
+               ret = select(n, readfds, writefds, NULL, &tv);
        while (ret < 0 && errno == EINTR);
        if (ret < 0)
                return -ERRNO_TO_PARA_ERROR(errno);
@@ -642,6 +644,33 @@ int para_munmap(void *start, size_t length)
        return -ERRNO_TO_PARA_ERROR(err);
 }
 
+static int xpoll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+       int ret;
+
+       do
+               ret = poll(fds, nfds, timeout);
+       while (ret < 0 && errno == EINTR);
+       return ret < 0? -ERRNO_TO_PARA_ERROR(errno) : ret;
+}
+
+/**
+ * Check a file descriptor for readability.
+ *
+ * \param fd The file descriptor.
+ *
+ * \return positive if fd is ready for reading, zero if it isn't, negative if
+ * an error occurred.
+ *
+ * \sa \ref write_ok().
+ */
+int read_ok(int fd)
+{
+       struct pollfd pfd = {.fd = fd, .events = POLLIN};
+       int ret = xpoll(&pfd, 1, 0);
+       return ret < 0? ret : pfd.revents & POLLIN;
+}
+
 /**
  * Check a file descriptor for writability.
  *
@@ -649,18 +678,14 @@ int para_munmap(void *start, size_t length)
  *
  * \return positive if fd is ready for writing, zero if it isn't, negative if
  * an error occurred.
+ *
+ * \sa \ref read_ok().
  */
-
 int write_ok(int fd)
 {
-       struct timeval tv;
-       fd_set wfds;
-
-       FD_ZERO(&wfds);
-       FD_SET(fd, &wfds);
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-       return para_select(fd + 1, NULL, &wfds, &tv);
+       struct pollfd pfd = {.fd = fd, .events = POLLOUT};
+       int ret = xpoll(&pfd, 1, 0);
+       return ret < 0? ret : pfd.revents & POLLOUT;
 }
 
 /**