From ec4b56789488a76d0dd57bb7e08846e23aba2b3e Mon Sep 17 00:00:00 2001 From: Erik van der Kouwe Date: Thu, 3 Sep 2009 20:35:22 +0000 Subject: [PATCH] Avoid alarm to prevent the setitimer interval from being reset --- lib/ip/res_send.c | 59 ++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/lib/ip/res_send.c b/lib/ip/res_send.c index 1c6dbe4c1..88090f3f1 100755 --- a/lib/ip/res_send.c +++ b/lib/ip/res_send.c @@ -56,6 +56,7 @@ static char sccsid[] = "@(#)res_send.c 6.27 (Berkeley) 2/24/91"; #include #include +#include #include #include #include @@ -87,7 +88,6 @@ static int udp_sendto _ARGS(( int fd, const char *buf, unsigned buflen, ipaddr_t addr, Udpport_t port )); static int udp_receive _ARGS(( int fd, char *buf, unsigned buflen, time_t timeout )); -static void alarm_handler _ARGS(( int sig )); #endif /* !_MINIX */ @@ -843,13 +843,6 @@ udpport_t port; return r; } -static void alarm_handler(sig) -int sig; -{ - signal(SIGALRM, alarm_handler); - alarm(1); -} - static int udp_receive(fd, buf, buflen, timeout) int fd; char *buf; @@ -859,45 +852,49 @@ time_t timeout; char *newbuf; udp_io_hdr_t *udp_io_hdr; int r, terrno; - void (*u_handler) _ARGS(( int sig )); - time_t u_timeout; - - newbuf= malloc(sizeof(*udp_io_hdr) + buflen); + fd_set readfds; + struct timeval timeval; + + /* allocate buffer for packet */ + newbuf = malloc(sizeof(*udp_io_hdr) + buflen); if (newbuf == NULL) { - errno= ENOMEM; + errno = ENOMEM; return -1; } + + /* only read if there is something to be read within timeout seconds */ + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + timeval.tv_sec = timeout; + timeval.tv_usec = 0; + r = select(fd + 1, &readfds, NULL, NULL, &timeval); + if (r >= 0 && !FD_ISSET(fd, &readfds)) + { + errno = EINTR; + r = -1; + } - u_handler= signal(SIGALRM, alarm_handler); - u_timeout= alarm(timeout); - - r= read(fd, newbuf, sizeof(*udp_io_hdr) + buflen); - terrno= errno; + if (r >= 0) + r = read(fd, newbuf, sizeof(*udp_io_hdr) + buflen); + /* clean up in case of failure */ + terrno = errno; if (r < 0 || r <= sizeof(*udp_io_hdr)) { if (r > 0) - r= 0; + r = 0; + free(newbuf); - - - alarm(0); - signal(SIGALRM, u_handler); - alarm(u_timeout); - - errno= terrno; + errno = terrno; return r; } + /* copy packet body to caller-provided buffer */ memcpy(buf, newbuf + sizeof(*udp_io_hdr), r - sizeof(*udp_io_hdr)); free(newbuf); - alarm(0); - signal(SIGALRM, u_handler); - alarm(u_timeout); - - return r-sizeof(*udp_io_hdr); + return r - sizeof(*udp_io_hdr); } #endif