Code

proto utils: Added sdb_proto_select().
authorSebastian Harl <sh@tokkee.org>
Thu, 19 Dec 2013 20:41:38 +0000 (21:41 +0100)
committerSebastian Harl <sh@tokkee.org>
Thu, 19 Dec 2013 20:41:38 +0000 (21:41 +0100)
This is a simple wrapper around select(2) to be used in cases where we only
care about a single file-descriptor being ready for a particular operation.

src/include/utils/proto.h
src/utils/proto.c

index 372e34d474b7be20dd5fc13ce6c04025748bc0a8..f3f1a871d83e48c28e96bee92fd8a40ac4e3188a 100644 (file)
 extern "C" {
 #endif
 
+enum {
+       SDB_PROTO_SELECTIN = 0,
+       SDB_PROTO_SELECTOUT,
+       SDB_PROTO_SELECTERR,
+};
+
+/*
+ * sdb_proto_select:
+ * Wait for a file-descriptor to become ready for I/O operations of the
+ * specified type. This is a simple wrapper around the select() system call.
+ * The type argument may be any of the SDB_PROTO_SELECT* constants.
+ *
+ * Returns:
+ *  - the number of file descriptors ready for I/O
+ *  - a negative value on error
+ */
+int
+sdb_proto_select(int fd, int type);
+
 ssize_t
 sdb_proto_send(int fd, size_t msg_len, const char *msg);
 
index 29783efd5aefb3db7cd09037f6f534fa4363b020..404d2a30ec5d2dabd270ab393bd9e262ec429017 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
+#include <sys/select.h>
+
 /*
  * public API
  */
 
+int
+sdb_proto_select(int fd, int type)
+{
+       fd_set fds;
+       fd_set *readfds = NULL;
+       fd_set *writefds = NULL;
+       fd_set *exceptfds = NULL;
+
+       if (fd < 0) {
+               errno = EBADF;
+               return -1;
+       }
+
+       FD_ZERO(&fds);
+
+       switch (type) {
+               case SDB_PROTO_SELECTIN:
+                       readfds = &fds;
+                       break;
+               case SDB_PROTO_SELECTOUT:
+                       writefds = &fds;
+                       break;
+               case SDB_PROTO_SELECTERR:
+                       exceptfds = &fds;
+                       break;
+               default:
+                       errno = EINVAL;
+                       return -1;
+       }
+
+       FD_SET(fd, &fds);
+
+       while (42) {
+               int n;
+               errno = 0;
+               n = select(fd + 1, readfds, writefds, exceptfds, NULL);
+
+               if ((n < 0) && (errno != EINTR))
+                       return (ssize_t)n;
+               if (n > 0)
+                       break;
+       }
+       return 0;
+} /* sdb_proto_select */
+
 ssize_t
 sdb_proto_send(int fd, size_t msg_len, const char *msg)
 {
@@ -56,7 +103,8 @@ sdb_proto_send(int fd, size_t msg_len, const char *msg)
        while (len > 0) {
                ssize_t status;
 
-               /* XXX: use select() */
+               if (sdb_proto_select(fd, SDB_PROTO_SELECTOUT))
+                       return -1;
 
                errno = 0;
                status = write(fd, buf, len);