2 * iosignal.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 # if defined(HAVE_SIGACTION)
32 * If sigaction() is used for signal handling and a signal is
33 * pending then the kernel blocks the signal before it calls
36 * The variable below is used to take care that the SIGIO signal
37 * is not unintentionally unblocked inside the sigio_handler()
38 * if the handler executes a piece of code that is normally
39 * bracketed by BLOCKIO()/UNBLOCKIO() calls.
41 static int sigio_handler_active = 0;
43 extern void input_handler P((l_fp *));
46 * SIGPOLL and SIGIO ROUTINES.
50 * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
51 * a few have separate SIGIO and SIGPOLL signals. This code checks for the
52 * SIGIO == SIGPOLL case at compile time.
53 * Do not define USE_SIGPOLL or USE_SIGIO.
54 * these are interal only to iosignal.c!
56 # if defined(USE_SIGPOLL)
59 # if defined(USE_SIGIO)
63 # if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
67 # if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
74 # define FNDELAY O_NDELAY
77 # if defined(USE_SIGIO) && defined(USE_SIGPOLL)
81 # endif /* SIGIO == SIGPOLL */
82 # endif /* USE_SIGIO && USE_SIGIO */
86 * TTY initialization routines.
90 struct refclockio *rio
93 # ifdef USE_TTY_SIGPOLL
95 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
96 if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
99 "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
106 * Special cases first!
108 /* Was: defined(SYS_HPUX) */
109 # if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
114 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
116 if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
118 msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
124 * set non-blocking, async I/O on the descriptor
126 if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
128 msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
133 if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
135 msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
141 # endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
142 /* Was: defined(SYS_AIX) && !defined(_BSD) */
143 # if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
145 * SYSV compatibility mode under AIX.
151 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
152 if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
154 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
158 if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
160 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
164 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
166 msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
171 # endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
174 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
175 # if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
177 * there are, however, always exceptions to the rules
178 * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
179 * CTTYs. SunOS and HPUX do not semm to have this restriction.
180 * another question is: how can you do multiple SIGIO from several
181 * ttys (as they all should be CTTYs), wondering...
185 if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
187 msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
190 # endif /* TIOCSCTTY && USE_FSETOWNCTTY */
192 if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
194 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
198 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
201 "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
206 # endif /* CLOCK_DONE */
207 # endif /* !USE_TTY_SIGPOLL */
217 # ifdef USE_UDP_SIGPOLL
219 if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
222 "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
226 # else /* USE_UDP_SIGPOLL */
233 # if defined(FIOASYNC)
234 if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
236 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
240 # elif defined(FASYNC)
244 if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
246 msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
250 if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
252 msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
258 # include "Bletch: Need asynchronous I/O!"
261 # ifdef UDP_BACKWARDS_SETOWN
267 # if defined(SIOCSPGRP)
268 if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
270 msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
274 # elif defined(FIOSETOWN)
275 if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
277 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
281 # elif defined(F_SETOWN)
282 if (fcntl(fd, F_SETOWN, pgrp) == -1)
284 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
289 # include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
292 # endif /* USE_UDP_SIGPOLL */
300 int saved_errno = errno;
305 # if defined(HAVE_SIGACTION)
306 sigio_handler_active++;
307 if (sigio_handler_active != 1) /* This should never happen! */
308 msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 1");
311 (void)input_handler(&ts);
313 # if defined(HAVE_SIGACTION)
314 sigio_handler_active--;
315 if (sigio_handler_active != 0) /* This should never happen! */
316 msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 0");
323 * Signal support routines.
325 # ifdef HAVE_SIGACTION
330 (void) signal_no_reset(SIGIO, sigio_handler);
333 (void) signal_no_reset(SIGPOLL, sigio_handler);
338 block_io_and_alarm(void)
342 if (sigemptyset(&set))
343 msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
344 # if defined(USE_SIGIO)
345 if (sigaddset(&set, SIGIO))
346 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
348 # if defined(USE_SIGPOLL)
349 if (sigaddset(&set, SIGPOLL))
350 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
352 if (sigaddset(&set, SIGALRM))
353 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
355 if (sigprocmask(SIG_BLOCK, &set, NULL))
356 msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
362 if ( sigio_handler_active == 0 ) /* not called from within signal handler */
367 if (sigio_block_count > 1)
368 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
369 if (sigio_block_count < 1)
370 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
372 if (sigemptyset(&set))
373 msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
374 # if defined(USE_SIGIO)
375 if (sigaddset(&set, SIGIO))
376 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
378 # if defined(USE_SIGPOLL)
379 if (sigaddset(&set, SIGPOLL))
380 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
383 if (sigprocmask(SIG_BLOCK, &set, NULL))
384 msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
389 unblock_io_and_alarm(void)
393 if (sigemptyset(&unset))
394 msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
396 # if defined(USE_SIGIO)
397 if (sigaddset(&unset, SIGIO))
398 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
400 # if defined(USE_SIGPOLL)
401 if (sigaddset(&unset, SIGPOLL))
402 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
404 if (sigaddset(&unset, SIGALRM))
405 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
407 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
408 msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
414 if ( sigio_handler_active == 0 ) /* not called from within signal handler */
419 if (sigio_block_count > 0)
420 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
421 if (sigio_block_count < 0)
422 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
424 if (sigemptyset(&unset))
425 msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
427 # if defined(USE_SIGIO)
428 if (sigaddset(&unset, SIGIO))
429 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
431 # if defined(USE_SIGPOLL)
432 if (sigaddset(&unset, SIGPOLL))
433 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
436 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
437 msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
442 wait_for_signal(void)
446 if (sigprocmask(SIG_UNBLOCK, NULL, &old))
447 msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
449 # if defined(USE_SIGIO)
450 if (sigdelset(&old, SIGIO))
451 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
453 # if defined(USE_SIGPOLL)
454 if (sigdelset(&old, SIGPOLL))
455 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
457 if (sigdelset(&old, SIGALRM))
458 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
460 if (sigsuspend(&old) && (errno != EINTR))
461 msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
464 # else /* !HAVE_SIGACTION */
466 * Must be an old bsd system.
467 * We assume there is no SIGPOLL.
471 block_io_and_alarm(void)
475 mask = sigmask(SIGIO) | sigmask(SIGALRM);
477 msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
486 if (sigio_block_count > 1)
487 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
488 if (sigio_block_count < 1)
489 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
491 mask = sigmask(SIGIO);
493 msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
499 (void) signal_no_reset(SIGIO, sigio_handler);
503 unblock_io_and_alarm(void)
507 mask = sigmask(SIGIO) | sigmask(SIGALRM);
510 (void) sigsetmask(omask);
519 if (sigio_block_count > 0)
520 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
521 if (sigio_block_count < 0)
522 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
523 mask = sigmask(SIGIO);
526 (void) sigsetmask(omask);
530 wait_for_signal(void)
534 mask = sigmask(SIGIO) | sigmask(SIGALRM);
537 if (sigpause(omask) && (errno != EINTR))
538 msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
541 # endif /* HAVE_SIGACTION */
543 int NotAnEmptyCompilationUnit;