2 * ntp_io.c - input/output routines for ntpd. The socket-opening code
3 * was shamelessly stolen from ntpd.
6 #include "ntp_machine.h"
10 #include "ntp_stdlib.h"
15 #ifdef HAVE_SYS_PARAM_H
16 # include <sys/param.h>
17 #endif /* HAVE_SYS_PARAM_H */
18 #ifdef HAVE_SYS_IOCTL_H
19 # include <sys/ioctl.h>
22 #include <arpa/inet.h>
24 #if _BSDI_VERSION >= 199510
28 #if defined(HAVE_SIGNALED_IO)
29 static int sigio_block_count = 0;
30 extern void input_handler P((l_fp *));
33 * SIGPOLL and SIGIO ROUTINES.
37 * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
38 * a few have separate SIGIO and SIGPOLL signals. This code checks for the
39 * SIGIO == SIGPOLL case at compile time.
40 * Do not defined USE_SIGPOLL or USE_SIGIO.
41 * these are interal only to ntp_io.c!
43 # if defined(USE_SIGPOLL)
46 # if defined(USE_SIGIO)
50 # if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
54 # if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
58 # if defined(USE_SIGIO) && defined(USE_SIGPOLL)
62 # endif /* SIGIO == SIGPOLL */
63 # endif /* USE_SIGIO && USE_SIGIO */
67 * TTY initialization routines.
71 struct refclockio *rio
74 # ifdef USE_TTY_SIGPOLL
76 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
77 if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
80 "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
87 * Special cases first!
89 /* Was: defined(SYS_HPUX) */
90 # if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
95 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
97 if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
99 msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
105 * set non-blocking, async I/O on the descriptor
107 if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
109 msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
114 if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
116 msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
122 # endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
123 /* Was: defined(SYS_AIX) && !defined(_BSD) */
124 # if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
126 * SYSV compatibility mode under AIX.
132 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
133 if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
135 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
139 if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
141 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
145 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
147 msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
152 # endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
155 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
156 # if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
158 * there are, however, always exceptions to the rules
159 * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
160 * CTTYs. SunOS and HPUX do not semm to have this restriction.
161 * another question is: how can you do multiple SIGIO from several
162 * ttys (as they all should be CTTYs), wondering...
166 if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
168 msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
171 # endif /* TIOCSCTTY && USE_FSETOWNCTTY */
173 if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
175 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
179 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
182 "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
187 # endif /* CLOCK_DONE */
188 # endif /* !USE_TTY_SIGPOLL */
198 # ifdef USE_UDP_SIGPOLL
200 if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
203 "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
207 # else /* USE_UDP_SIGPOLL */
214 # if defined(FIOASYNC)
215 if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
217 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
221 # elif defined(FASYNC)
225 if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
227 msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
231 if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
233 msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
239 # include "Bletch: Need asynchronous I/O!"
242 # ifdef UDP_BACKWARDS_SETOWN
248 # if defined(SIOCSPGRP)
249 if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
251 msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
255 # elif defined(FIOSETOWN)
256 if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
258 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
262 # elif defined(F_SETOWN)
263 if (fcntl(fd, F_SETOWN, pgrp) == -1)
265 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
270 # include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
273 # endif /* USE_UDP_SIGPOLL */
281 int saved_errno = errno;
285 (void)input_handler(&ts);
290 * Signal support routines.
292 # ifdef HAVE_SIGACTION
297 (void) signal_no_reset(SIGIO, sigio_handler);
300 (void) signal_no_reset(SIGPOLL, sigio_handler);
305 block_io_and_alarm(void)
309 if (sigemptyset(&set))
310 msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
311 # if defined(USE_SIGIO)
312 if (sigaddset(&set, SIGIO))
313 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
315 # if defined(USE_SIGPOLL)
316 if (sigaddset(&set, SIGPOLL))
317 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
319 if (sigaddset(&set, SIGALRM))
320 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
322 if (sigprocmask(SIG_BLOCK, &set, NULL))
323 msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
332 if (sigio_block_count > 1)
333 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
334 if (sigio_block_count < 1)
335 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
337 if (sigemptyset(&set))
338 msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
339 # if defined(USE_SIGIO)
340 if (sigaddset(&set, SIGIO))
341 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
343 # if defined(USE_SIGPOLL)
344 if (sigaddset(&set, SIGPOLL))
345 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
348 if (sigprocmask(SIG_BLOCK, &set, NULL))
349 msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
353 unblock_io_and_alarm(void)
357 if (sigemptyset(&unset))
358 msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
360 # if defined(USE_SIGIO)
361 if (sigaddset(&unset, SIGIO))
362 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
364 # if defined(USE_SIGPOLL)
365 if (sigaddset(&unset, SIGPOLL))
366 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
368 if (sigaddset(&unset, SIGALRM))
369 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
371 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
372 msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
381 if (sigio_block_count > 0)
382 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
383 if (sigio_block_count < 0)
384 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
386 if (sigemptyset(&unset))
387 msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
389 # if defined(USE_SIGIO)
390 if (sigaddset(&unset, SIGIO))
391 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
393 # if defined(USE_SIGPOLL)
394 if (sigaddset(&unset, SIGPOLL))
395 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
398 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
399 msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
403 wait_for_signal(void)
407 if (sigprocmask(SIG_UNBLOCK, NULL, &old))
408 msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
410 # if defined(USE_SIGIO)
411 if (sigdelset(&old, SIGIO))
412 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
414 # if defined(USE_SIGPOLL)
415 if (sigdelset(&old, SIGPOLL))
416 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
418 if (sigdelset(&old, SIGALRM))
419 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
421 if (sigsuspend(&old) && (errno != EINTR))
422 msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
425 # else /* !HAVE_SIGACTION */
427 * Must be an old bsd system.
428 * We assume there is no SIGPOLL.
432 block_io_and_alarm(void)
436 mask = sigmask(SIGIO) | sigmask(SIGALRM);
438 msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
447 if (sigio_block_count > 1)
448 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
449 if (sigio_block_count < 1)
450 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
452 mask = sigmask(SIGIO);
454 msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
460 (void) signal_no_reset(SIGIO, sigio_handler);
464 unblock_io_and_alarm(void)
468 mask = sigmask(SIGIO) | sigmask(SIGALRM);
471 (void) sigsetmask(omask);
480 if (sigio_block_count > 0)
481 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
482 if (sigio_block_count < 0)
483 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
484 mask = sigmask(SIGIO);
487 (void) sigsetmask(omask);
491 wait_for_signal(void)
495 mask = sigmask(SIGIO) | sigmask(SIGALRM);
498 if (sigpause(omask) && (errno != EINTR))
499 msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
502 # endif /* HAVE_SIGACTION */
504 int NotAnEmptyCompilationUnit;