summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6204a78)
raw | patch | inline | side by side (parent: 6204a78)
author | Sebastian Harl <sh@tokkee.org> | |
Thu, 19 Dec 2013 20:41:38 +0000 (21:41 +0100) | ||
committer | Sebastian 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.
care about a single file-descriptor being ready for a particular operation.
src/include/utils/proto.h | patch | blob | history | |
src/utils/proto.c | patch | blob | history |
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);
diff --git a/src/utils/proto.c b/src/utils/proto.c
index 29783efd5aefb3db7cd09037f6f534fa4363b020..404d2a30ec5d2dabd270ab393bd9e262ec429017 100644 (file)
--- a/src/utils/proto.c
+++ b/src/utils/proto.c
#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)
{
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);