# check for library functions
AC_FUNC_MALLOC
-AC_CHECK_FUNCS([inet_ntoa memchr memset select socket strcasecmp strdup strtol strtoul])
+AC_CHECK_FUNCS([inet_ntoa memchr memset socket poll strcasecmp strdup strtol strtoul])
+
+AC_CHECK_FUNC([clock_gettime], [
+ AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if you have clock_gettime])
+], [
+ AC_CHECK_LIB([rt], [clock_gettime], [
+ AC_SUBST([RT_LIBS], [-lrt])
+ AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if you have clock_gettime])
+ ], [
+ AC_CHECK_FUNCS([gettimeofday])
+ ])
+])
AC_CONFIG_FILES([
#include "network.h"
-static const struct timeval default_timeout = {.tv_sec = 4, .tv_usec = 0};
+static const struct timespec default_timeout = {.tv_sec = 4, .tv_nsec = 0};
struct ngadmin* ngadmin_init (const char *iface)
}
nga->timeout = default_timeout;
- if (updateTimeout(nga) < 0) {
- free(nga);
- return NULL;
- }
return nga;
if (nga == NULL || tv == NULL)
return ERR_INVARG;
- nga->timeout = *tv;
- if (updateTimeout(nga) < 0)
- ret = ERR_NET;
-
+ nga->timeout.tv_sec = tv->tv_sec;
+ nga->timeout.tv_nsec = tv->tv_usec * 1000;
return ret;
}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <errno.h>
+#include <poll.h>
#include <nsdp/net.h>
#include "encoding.h"
+static inline void timespec_add (struct timespec *tsa, const struct timespec *tsb)
+{
+ tsa->tv_sec += tsb->tv_sec;
+ tsa->tv_nsec += tsb->tv_nsec;
+ while (tsa->tv_nsec >= 1000000000) {
+ tsa->tv_nsec -= 1000000000;
+ tsa->tv_sec++;
+ }
+}
+
+
+static inline int timespec_diff_ms (const struct timespec *tsa, const struct timespec *tsb)
+{
+ int diff = (tsb->tv_sec - tsa->tv_sec) * 1000;
+
+ if (tsb->tv_sec > tsa->tv_sec)
+ diff += (tsb->tv_nsec - tsa->tv_nsec) / 1000000;
+ else
+ diff -= (tsb->tv_nsec - tsa->tv_nsec) / 1000000;
+
+ return diff;
+}
+
+
+static inline void timeval_to_timespec (struct timespec *ts, const struct timeval *tv)
+{
+ ts->tv_sec = tv->tv_sec;
+ ts->tv_nsec = tv->tv_usec * 1000;
+}
+
+
int sendNsdpPacket (int sock, const struct nsdp_cmd *nc, const List *attr)
{
unsigned char buffer[1500];
}
-int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timeval *timeout)
+int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timespec *timeout)
{
unsigned char buffer[1500];
struct nsdp_packet np;
socklen_t slen = sizeof(struct sockaddr_in);
- struct timeval rem;
- fd_set fs;
- int len = -1;
+ int len = -1, timewait;
struct sockaddr_in remote;
+ struct timespec timecurrent, timeend;
+#ifndef HAVE_CLOCK_GETTIME
+ struct timeval tv;
+#endif
+ struct pollfd fds;
if (sock < 0 || nc == NULL || attr == NULL)
np.buffer = buffer;
- if (timeout != NULL)
- rem = *timeout;
-
memset(&remote, 0, sizeof(struct sockaddr_in));
remote.sin_family = AF_INET;
+ if (timeout == NULL) {
+ timewait = -1;
+ } else {
+#ifdef HAVE_CLOCK_GETTIME
+ clock_gettime(CLOCK_MONOTONIC, &timeend);
+#else
+ gettimeofday(&tv, NULL);
+ timeval_to_timespec(&timeend, &tv);
+#endif
+ timespec_add(&timeend, timeout);
+ }
+ fds.fd = sock;
+ fds.events = POLLIN;
+ fds.revents = 0;
+
while (1) {
- FD_ZERO(&fs);
- FD_SET(sock, &fs);
- select(sock + 1, &fs, NULL, NULL, timeout == NULL ? NULL : &rem); /* FIXME: non portable */
+ if (timeout != NULL) {
+#ifdef HAVE_CLOCK_GETTIME
+ clock_gettime(CLOCK_MONOTONIC, &timecurrent);
+#else
+ gettimeofday(&tv, NULL);
+ timeval_to_timespec(&timeend, &tv);
+#endif
+ timewait = timespec_diff_ms(&timecurrent, &timeend);
+ if (timewait <= 0)
+ break;
+ }
+
+ len = poll(&fds, 1, timewait);
+ if (len < 0) {
+ break;
+ } else if (len == 0) {
+ len = -ETIMEDOUT;
+ break;
+ }
len = recvfrom(sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&remote, &slen);
if (len < 0)