Code

utils channel: Let channel_select() set errno.
[sysdb.git] / src / utils / channel.c
index 22e31a8b4eb0303e063ca6b3bfae2e0e8dcb19ad..afce6f5d9cc9aa883afb9569aef9a384c433eb01 100644 (file)
 
 #include <assert.h>
 
+#include <errno.h>
+
 #include <stdlib.h>
 #include <string.h>
 
+#include <time.h>
+
 #include <pthread.h>
 
 /*
@@ -165,13 +169,26 @@ int
 sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data,
                int *wantwrite, void *write_data, const struct timespec *timeout)
 {
+       struct timespec abstime;
        int status = 0;
 
-       if (! chan)
+       if (! chan) {
+               errno = EINVAL;
                return -1;
+       }
 
-       if ((! wantread) && (! read_data) && (! wantwrite) && (! write_data))
+       if ((! wantread) && (! read_data) && (! wantwrite) && (! write_data)) {
+               errno = EINVAL;
                return -1;
+       }
+
+       if (timeout) {
+               if (clock_gettime(CLOCK_REALTIME, &abstime))
+                       return -1;
+
+               abstime.tv_sec += timeout->tv_sec;
+               abstime.tv_nsec += timeout->tv_nsec;
+       }
 
        pthread_mutex_lock(&chan->lock);
        while (! status) {
@@ -193,13 +210,17 @@ sdb_channel_select(sdb_channel_t *chan, int *wantread, void *read_data,
 
                if (timeout)
                        status = pthread_cond_timedwait(&chan->cond, &chan->lock,
-                                       timeout);
+                                       &abstime);
                else
                        status = pthread_cond_wait(&chan->cond, &chan->lock);
        }
 
        pthread_mutex_unlock(&chan->lock);
-       return status;
+       if (status) {
+               errno = status;
+               return -1;
+       }
+       return 0;
 } /* sdb_channel_select */
 
 int