2 * iosignal.c - input/output routines for ntpd. The socket-opening code
3 * was shamelessly stolen from ntpd.
8 * Do the #includes differently, as under some versions of Linux
9 * sys/param.h has a #undef CONFIG_PHONE line in it.
11 * As we have ~40 CONFIG_ variables, I don't feel like renaming them
12 * every time somebody adds a new macro to some system header.
21 #ifdef HAVE_SYS_PARAM_H
22 # include <sys/param.h>
23 #endif /* HAVE_SYS_PARAM_H */
24 #ifdef HAVE_SYS_IOCTL_H
25 # include <sys/ioctl.h>
28 #include <arpa/inet.h>
30 #if _BSDI_VERSION >= 199510
37 # define FNDELAY O_NDELAY
40 #include "ntp_machine.h"
44 #include "ntp_stdlib.h"
47 #if defined(HAVE_SIGNALED_IO)
48 static int sigio_block_count = 0;
49 # if defined(HAVE_SIGACTION)
51 * If sigaction() is used for signal handling and a signal is
52 * pending then the kernel blocks the signal before it calls
55 * The variable below is used to take care that the SIGIO signal
56 * is not unintentionally unblocked inside the sigio_handler()
57 * if the handler executes a piece of code that is normally
58 * bracketed by BLOCKIO()/UNBLOCKIO() calls.
60 static int sigio_handler_active = 0;
62 extern void input_handler P((l_fp *));
65 * SIGPOLL and SIGIO ROUTINES.
69 * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
70 * a few have separate SIGIO and SIGPOLL signals. This code checks for the
71 * SIGIO == SIGPOLL case at compile time.
72 * Do not define USE_SIGPOLL or USE_SIGIO.
73 * these are interal only to iosignal.c!
75 # if defined(USE_SIGPOLL)
78 # if defined(USE_SIGIO)
82 # if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
86 # if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
90 # if defined(USE_SIGIO) && defined(USE_SIGPOLL)
94 # endif /* SIGIO == SIGPOLL */
95 # endif /* USE_SIGIO && USE_SIGIO */
99 * TTY initialization routines.
103 struct refclockio *rio
106 # ifdef USE_TTY_SIGPOLL
108 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
109 if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
112 "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
119 * Special cases first!
121 /* Was: defined(SYS_HPUX) */
122 # if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
127 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
129 if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
131 msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
137 * set non-blocking, async I/O on the descriptor
139 if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
141 msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
146 if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
148 msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
154 # endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
155 /* Was: defined(SYS_AIX) && !defined(_BSD) */
156 # if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
158 * SYSV compatibility mode under AIX.
164 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
165 if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
167 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
171 if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
173 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
177 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
179 msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
184 # endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
187 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
188 # if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
190 * there are, however, always exceptions to the rules
191 * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
192 * CTTYs. SunOS and HPUX do not semm to have this restriction.
193 * another question is: how can you do multiple SIGIO from several
194 * ttys (as they all should be CTTYs), wondering...
198 if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
200 msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
203 # endif /* TIOCSCTTY && USE_FSETOWNCTTY */
205 if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
207 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
211 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
214 "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
219 # endif /* CLOCK_DONE */
220 # endif /* !USE_TTY_SIGPOLL */
230 # ifdef USE_UDP_SIGPOLL
232 if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
235 "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
239 # else /* USE_UDP_SIGPOLL */
246 # if defined(FIOASYNC)
247 if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
249 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
253 # elif defined(FASYNC)
257 if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
259 msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
263 if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
265 msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
271 # include "Bletch: Need asynchronous I/O!"
274 # ifdef UDP_BACKWARDS_SETOWN
280 # if defined(SIOCSPGRP)
281 if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
283 msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
287 # elif defined(FIOSETOWN)
288 if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
290 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
294 # elif defined(F_SETOWN)
295 if (fcntl(fd, F_SETOWN, pgrp) == -1)
297 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
302 # include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
305 # endif /* USE_UDP_SIGPOLL */
313 int saved_errno = errno;
318 # if defined(HAVE_SIGACTION)
319 sigio_handler_active++;
320 if (sigio_handler_active != 1) /* This should never happen! */
321 msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 1");
324 (void)input_handler(&ts);
326 # if defined(HAVE_SIGACTION)
327 sigio_handler_active--;
328 if (sigio_handler_active != 0) /* This should never happen! */
329 msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 0");
336 * Signal support routines.
338 # ifdef HAVE_SIGACTION
343 (void) signal_no_reset(SIGIO, sigio_handler);
346 (void) signal_no_reset(SIGPOLL, sigio_handler);
351 block_io_and_alarm(void)
355 if (sigemptyset(&set))
356 msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
357 # if defined(USE_SIGIO)
358 if (sigaddset(&set, SIGIO))
359 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
361 # if defined(USE_SIGPOLL)
362 if (sigaddset(&set, SIGPOLL))
363 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
365 if (sigaddset(&set, SIGALRM))
366 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
368 if (sigprocmask(SIG_BLOCK, &set, NULL))
369 msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
375 if ( sigio_handler_active == 0 ) /* not called from within signal handler */
380 if (sigio_block_count > 1)
381 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
382 if (sigio_block_count < 1)
383 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
385 if (sigemptyset(&set))
386 msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
387 # if defined(USE_SIGIO)
388 if (sigaddset(&set, SIGIO))
389 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
391 # if defined(USE_SIGPOLL)
392 if (sigaddset(&set, SIGPOLL))
393 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
396 if (sigprocmask(SIG_BLOCK, &set, NULL))
397 msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
402 unblock_io_and_alarm(void)
406 if (sigemptyset(&unset))
407 msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
409 # if defined(USE_SIGIO)
410 if (sigaddset(&unset, SIGIO))
411 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
413 # if defined(USE_SIGPOLL)
414 if (sigaddset(&unset, SIGPOLL))
415 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
417 if (sigaddset(&unset, SIGALRM))
418 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
420 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
421 msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
427 if ( sigio_handler_active == 0 ) /* not called from within signal handler */
432 if (sigio_block_count > 0)
433 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
434 if (sigio_block_count < 0)
435 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
437 if (sigemptyset(&unset))
438 msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
440 # if defined(USE_SIGIO)
441 if (sigaddset(&unset, SIGIO))
442 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
444 # if defined(USE_SIGPOLL)
445 if (sigaddset(&unset, SIGPOLL))
446 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
449 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
450 msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
455 wait_for_signal(void)
459 if (sigprocmask(SIG_UNBLOCK, NULL, &old))
460 msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
462 # if defined(USE_SIGIO)
463 if (sigdelset(&old, SIGIO))
464 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
466 # if defined(USE_SIGPOLL)
467 if (sigdelset(&old, SIGPOLL))
468 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
470 if (sigdelset(&old, SIGALRM))
471 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
473 if (sigsuspend(&old) && (errno != EINTR))
474 msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
477 # else /* !HAVE_SIGACTION */
479 * Must be an old bsd system.
480 * We assume there is no SIGPOLL.
484 block_io_and_alarm(void)
488 mask = sigmask(SIGIO) | sigmask(SIGALRM);
490 msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
499 if (sigio_block_count > 1)
500 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
501 if (sigio_block_count < 1)
502 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
504 mask = sigmask(SIGIO);
506 msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
512 (void) signal_no_reset(SIGIO, sigio_handler);
516 unblock_io_and_alarm(void)
520 mask = sigmask(SIGIO) | sigmask(SIGALRM);
523 (void) sigsetmask(omask);
532 if (sigio_block_count > 0)
533 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
534 if (sigio_block_count < 0)
535 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
536 mask = sigmask(SIGIO);
539 (void) sigsetmask(omask);
543 wait_for_signal(void)
547 mask = sigmask(SIGIO) | sigmask(SIGALRM);
550 if (sigpause(omask) && (errno != EINTR))
551 msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
554 # endif /* HAVE_SIGACTION */
556 int NotAnEmptyCompilationUnit;