summaryrefslogtreecommitdiffstats
path: root/src/util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-12-05 17:33:51 +0000
committerLennart Poettering <lennart@poettering.net>2004-12-05 17:33:51 +0000
commit8d4fd94fc8332b23f757443841a5c19c104a9bb8 (patch)
tree4763b4cdbdd13f28efbe07ebfc0486536713c577 /src/util.c
parenta3b571996ea5cb0227b36a20f3fc0986f7ab1b7d (diff)
move source files to src/
git-svn-id: file:///home/lennart/svn/public/nss-mdns/trunk@51 0ee8848e-81ea-0310-a63a-f631d1a40d77
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..5f89584
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,185 @@
+#include <sys/select.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <fcntl.h>
+
+#include "util.h"
+
+/* Calculate the difference between the two specfified timeval
+ * timestamsps. */
+usec_t timeval_diff(const struct timeval *a, const struct timeval *b) {
+ usec_t r;
+ assert(a && b);
+
+ /* Check which whan is the earlier time and swap the two arguments if reuqired. */
+ if (timeval_cmp(a, b) < 0) {
+ const struct timeval *c;
+ c = a;
+ a = b;
+ b = c;
+ }
+
+ /* Calculate the second difference*/
+ r = ((usec_t) a->tv_sec - b->tv_sec)* 1000000;
+
+ /* Calculate the microsecond difference */
+ if (a->tv_usec > b->tv_usec)
+ r += ((usec_t) a->tv_usec - b->tv_usec);
+ else if (a->tv_usec < b->tv_usec)
+ r -= ((usec_t) b->tv_usec - a->tv_usec);
+
+ return r;
+}
+
+/* Compare the two timeval structs and return 0 when equal, negative when a < b, positive otherwse */
+int timeval_cmp(const struct timeval *a, const struct timeval *b) {
+ assert(a && b);
+
+ if (a->tv_sec < b->tv_sec)
+ return -1;
+
+ if (a->tv_sec > b->tv_sec)
+ return 1;
+
+ if (a->tv_usec < b->tv_usec)
+ return -1;
+
+ if (a->tv_usec > b->tv_usec)
+ return 1;
+
+ return 0;
+}
+
+/* Return the time difference between now and the specified timestamp */
+usec_t timeval_age(const struct timeval *tv) {
+ struct timeval now;
+ assert(tv);
+ gettimeofday(&now, NULL);
+ return timeval_diff(&now, tv);
+}
+
+/* Add the specified time inmicroseconds to the specified timeval structure */
+void timeval_add(struct timeval *tv, usec_t v) {
+ unsigned long secs;
+ assert(tv);
+
+ secs = (v/1000000);
+ tv->tv_sec += (unsigned long) secs;
+ v -= secs*1000000;
+
+ tv->tv_usec += v;
+
+ /* Normalize */
+ while (tv->tv_usec >= 1000000) {
+ tv->tv_sec++;
+ tv->tv_usec -= 1000000;
+ }
+}
+
+int set_cloexec(int fd) {
+ int n;
+ assert(fd >= 0);
+
+ if ((n = fcntl(fd, F_GETFD)) < 0)
+ return -1;
+
+ if (n & FD_CLOEXEC)
+ return 0;
+
+ return fcntl(fd, F_SETFD, n|FD_CLOEXEC);
+}
+
+int set_nonblock(int fd) {
+ int n;
+ assert(fd >= 0);
+
+ if ((n = fcntl(fd, F_GETFL)) < 0)
+ return -1;
+
+ if (n & O_NONBLOCK)
+ return 0;
+
+ return fcntl(fd, F_SETFL, n|O_NONBLOCK);
+}
+
+int wait_for_write(int fd, struct timeval *end) {
+ struct timeval now;
+
+ if (end)
+ gettimeofday(&now, NULL);
+
+ for (;;) {
+ struct timeval tv;
+ fd_set fds;
+ int r;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ if (end) {
+ if (timeval_cmp(&now, end) >= 0)
+ return 1;
+
+ tv.tv_sec = tv.tv_usec = 0;
+ timeval_add(&tv, timeval_diff(end, &now));
+ }
+
+ if ((r = select(fd+1, NULL, &fds, NULL, end ? &tv : NULL)) < 0) {
+ if (errno != EINTR) {
+ fprintf(stderr, "select() failed: %s\n", strerror(errno));
+ return -1;
+ }
+ } else if (r == 0)
+ return 1;
+ else {
+ if (FD_ISSET(fd, &fds))
+ return 0;
+ }
+
+ if (end)
+ gettimeofday(&now, NULL);
+ }
+}
+
+int wait_for_read(int fd, struct timeval *end) {
+ struct timeval now;
+
+ if (end)
+ gettimeofday(&now, NULL);
+
+ for (;;) {
+ struct timeval tv;
+ fd_set fds;
+ int r;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ if (end) {
+ if (timeval_cmp(&now, end) >= 0)
+ return 1;
+
+ tv.tv_sec = tv.tv_usec = 0;
+ timeval_add(&tv, timeval_diff(end, &now));
+ }
+
+ if ((r = select(fd+1, &fds, NULL, NULL, end ? &tv : NULL)) < 0) {
+ if (errno != EINTR) {
+ fprintf(stderr, "select() failed: %s\n", strerror(errno));
+ return -1;
+ }
+ } else if (r == 0)
+ return 1;
+ else {
+
+ if (FD_ISSET(fd, &fds))
+ return 0;
+ }
+
+ if (end)
+ gettimeofday(&now, NULL);
+ }
+}
+