From: Sebastian Harl Date: Thu, 19 Dec 2013 20:41:38 +0000 (+0100) Subject: proto utils: Added sdb_proto_select(). X-Git-Tag: sysdb-0.1.0~306 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=0e9ae0a6da794b4c6f514c123d2a0ab9527ad592;p=sysdb.git proto utils: Added sdb_proto_select(). 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. --- diff --git a/src/include/utils/proto.h b/src/include/utils/proto.h index 372e34d..f3f1a87 100644 --- a/src/include/utils/proto.h +++ b/src/include/utils/proto.h @@ -37,6 +37,25 @@ 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 29783ef..404d2a3 100644 --- a/src/utils/proto.c +++ b/src/utils/proto.c @@ -36,10 +36,57 @@ #include #include +#include + /* * 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);