From 8d4fd94fc8332b23f757443841a5c19c104a9bb8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Dec 2004 17:33:51 +0000 Subject: move source files to src/ git-svn-id: file:///home/lennart/svn/public/nss-mdns/trunk@51 0ee8848e-81ea-0310-a63a-f631d1a40d77 --- src/util.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/util.c (limited to 'src/util.c') 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 +#include +#include +#include +#include +#include + +#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); + } +} + -- cgit