diff options
author | Hakan Olsson <ho@cvs.openbsd.org> | 2002-05-16 22:00:38 +0000 |
---|---|---|
committer | Hakan Olsson <ho@cvs.openbsd.org> | 2002-05-16 22:00:38 +0000 |
commit | 1ce174a7b8b5dd10f45feb4c736912e3d1a76763 (patch) | |
tree | cac3a4ccb98a9b668c6a1bea47ac6f3fa5632ac1 /usr.sbin/rdate | |
parent | 0d67e121e15c91c0eeadeb9414f463fd0f103cc4 (diff) |
More careful with select(). deraadt@ ok.
Diffstat (limited to 'usr.sbin/rdate')
-rw-r--r-- | usr.sbin/rdate/ntp.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/usr.sbin/rdate/ntp.c b/usr.sbin/rdate/ntp.c index 8878eefc298..78cf29a7ca0 100644 --- a/usr.sbin/rdate/ntp.c +++ b/usr.sbin/rdate/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.5 2002/05/16 21:05:24 jakob Exp $ */ +/* $OpenBSD: ntp.c,v 1.6 2002/05/16 22:00:37 ho Exp $ */ /* * Copyright (c) 1996, 1997 by N.M. Maclaren. All rights reserved. @@ -257,22 +257,34 @@ read_packet(int fd, struct ntp_data *data, double *off, double *error, { u_char receive[NTP_PACKET_MAX+1]; double delay1, delay2, x, y; - int length; - fd_set rfds; + int length, r; + fd_set *rfds; struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 1000000 * MAX_DELAY / MAX_QUERIES; + rfds = (fd_set *)calloc(howmany(fd + 1, NFDBITS), sizeof(fd_mask)); + if (!rfds) { + warnx("calloc() failed"); + return 1; + } - /* XXX potential fdset overflow */ - FD_ZERO(&rfds); - FD_SET(fd, &rfds); + FD_SET(fd, rfds); - if (select (fd + 1, &rfds, NULL, NULL, &tv) < 1) - return 1; /* failure or timeout */ - /* XXX does not deal with all possible return values */ +retry: + tv.tv_sec = 0; + tv.tv_usec = 1000000 * MAX_DELAY / MAX_QUERIES; - /* XXX assumes fd was ready */ + r = select(fd + 1, rfds, NULL, NULL, &tv); + if (r < 1 || !FD_ISSET(fd, rfds)) { + if (r < 0) { + if (errno == EINTR) + goto retry; + else + warnx("select() failed"); + } + free(rfds); + return 1; + } + free(rfds); length = recvfrom(fd, receive, NTP_PACKET_MAX + 1, 0, NULL, 0); if (length < 0) { |