Sync usage with man page.
[netbsd-mini2440.git] / dist / ntp / libntp / iosignal.c
blob0400fd6c7fd386b4e6fbd477c53200004daaf62a
1 /* $NetBSD: iosignal.c,v 1.2 2003/12/04 16:23:36 drochner Exp $ */
3 /*
4 * iosignal.c - input/output routines for ntpd. The socket-opening code
5 * was shamelessly stolen from ntpd.
6 */
8 /*
9 * [Bug 158]
10 * Do the #includes differently, as under some versions of Linux
11 * sys/param.h has a #undef CONFIG_PHONE line in it.
13 * As we have ~40 CONFIG_ variables, I don't feel like renaming them
14 * every time somebody adds a new macro to some system header.
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
21 #include <stdio.h>
22 #include <signal.h>
23 #ifdef HAVE_SYS_PARAM_H
24 # include <sys/param.h>
25 #endif /* HAVE_SYS_PARAM_H */
26 #ifdef HAVE_SYS_IOCTL_H
27 # include <sys/ioctl.h>
28 #endif
30 #include <arpa/inet.h>
32 #if _BSDI_VERSION >= 199510
33 # include <ifaddrs.h>
34 #endif
36 # ifdef __QNXNTO__
37 # include <fcntl.h>
38 # include <unix.h>
39 # define FNDELAY O_NDELAY
40 # endif
42 #include "ntp_machine.h"
43 #include "ntpd.h"
44 #include "ntp_io.h"
45 #include "ntp_if.h"
46 #include "ntp_stdlib.h"
47 #include "iosignal.h"
49 #if defined(HAVE_SIGNALED_IO)
50 static int sigio_block_count = 0;
51 # if defined(HAVE_SIGACTION)
53 * If sigaction() is used for signal handling and a signal is
54 * pending then the kernel blocks the signal before it calls
55 * the signal handler.
57 * The variable below is used to take care that the SIGIO signal
58 * is not unintentionally unblocked inside the sigio_handler()
59 * if the handler executes a piece of code that is normally
60 * bracketed by BLOCKIO()/UNBLOCKIO() calls.
62 static int sigio_handler_active = 0;
63 # endif
64 extern void input_handler P((l_fp *));
67 * SIGPOLL and SIGIO ROUTINES.
71 * Some systems (MOST) define SIGPOLL == SIGIO, others SIGIO == SIGPOLL, and
72 * a few have separate SIGIO and SIGPOLL signals. This code checks for the
73 * SIGIO == SIGPOLL case at compile time.
74 * Do not define USE_SIGPOLL or USE_SIGIO.
75 * these are interal only to iosignal.c!
77 # if defined(USE_SIGPOLL)
78 # undef USE_SIGPOLL
79 # endif
80 # if defined(USE_SIGIO)
81 # undef USE_SIGIO
82 # endif
84 # if defined(USE_TTY_SIGPOLL) || defined(USE_UDP_SIGPOLL)
85 # define USE_SIGPOLL
86 # endif
88 # if !defined(USE_TTY_SIGPOLL) || !defined(USE_UDP_SIGPOLL)
89 # define USE_SIGIO
90 # endif
92 # if defined(USE_SIGIO) && defined(USE_SIGPOLL)
93 # if SIGIO == SIGPOLL
94 # define USE_SIGIO
95 # undef USE_SIGPOLL
96 # endif /* SIGIO == SIGPOLL */
97 # endif /* USE_SIGIO && USE_SIGIO */
101 * TTY initialization routines.
104 init_clock_sig(
105 struct refclockio *rio
108 # ifdef USE_TTY_SIGPOLL
110 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
111 if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0)
113 msyslog(LOG_ERR,
114 "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
115 return 1;
117 return 0;
119 # else
121 * Special cases first!
123 /* Was: defined(SYS_HPUX) */
124 # if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT)
125 #define CLOCK_DONE
127 int pgrp, on = 1;
129 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
130 pgrp = getpid();
131 if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1)
133 msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m");
134 exit(1);
135 /*NOTREACHED*/
139 * set non-blocking, async I/O on the descriptor
141 if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1)
143 msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m");
144 exit(1);
145 /*NOTREACHED*/
148 if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1)
150 msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m");
151 exit(1);
152 /*NOTREACHED*/
154 return 0;
156 # endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */
157 /* Was: defined(SYS_AIX) && !defined(_BSD) */
158 # if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN)
160 * SYSV compatibility mode under AIX.
162 #define CLOCK_DONE
164 int pgrp, on = 1;
166 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
167 if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1)
169 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m");
170 return 1;
172 pgrp = -getpid();
173 if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1)
175 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m");
176 return 1;
179 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
181 msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
182 return 1;
184 return 0;
186 # endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */
187 # ifndef CLOCK_DONE
189 /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */
190 # if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY)
192 * there are, however, always exceptions to the rules
193 * one is, that OSF accepts SETOWN on TTY fd's only, iff they are
194 * CTTYs. SunOS and HPUX do not semm to have this restriction.
195 * another question is: how can you do multiple SIGIO from several
196 * ttys (as they all should be CTTYs), wondering...
198 * kd 95-07-16
200 if (ioctl(rio->fd, TIOCSCTTY, 0) == -1)
202 msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m");
203 return 1;
205 # endif /* TIOCSCTTY && USE_FSETOWNCTTY */
207 if (fcntl(rio->fd, F_SETOWN, getpid()) == -1)
209 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m");
210 return 1;
213 if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0)
215 msyslog(LOG_ERR,
216 "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m");
217 return 1;
219 return 0;
221 # endif /* CLOCK_DONE */
222 # endif /* !USE_TTY_SIGPOLL */
227 void
228 init_socket_sig(
229 int fd
232 # ifdef USE_UDP_SIGPOLL
234 if (ioctl(fd, I_SETSIG, S_INPUT) < 0)
236 msyslog(LOG_ERR,
237 "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m");
238 exit(1);
241 # else /* USE_UDP_SIGPOLL */
243 int pgrp;
244 # ifdef FIOASYNC
245 int on = 1;
246 # endif
248 # if defined(FIOASYNC)
249 if (ioctl(fd, FIOASYNC, (char *)&on) == -1)
251 msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m");
252 exit(1);
253 /*NOTREACHED*/
255 # elif defined(FASYNC)
257 int flags;
259 if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
261 msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m");
262 exit(1);
263 /*NOTREACHED*/
265 if (fcntl(fd, F_SETFL, flags|FASYNC) < 0)
267 msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m");
268 exit(1);
269 /*NOTREACHED*/
272 # else
273 # include "Bletch: Need asynchronous I/O!"
274 # endif
276 # ifdef UDP_BACKWARDS_SETOWN
277 pgrp = -getpid();
278 # else
279 pgrp = getpid();
280 # endif
282 # if defined(SIOCSPGRP)
283 if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1)
285 msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m");
286 exit(1);
287 /*NOTREACHED*/
289 # elif defined(FIOSETOWN)
290 if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1)
292 msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m");
293 exit(1);
294 /*NOTREACHED*/
296 # elif defined(F_SETOWN)
297 if (fcntl(fd, F_SETOWN, pgrp) == -1)
299 msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m");
300 exit(1);
301 /*NOTREACHED*/
303 # else
304 # include "Bletch: Need to set process(group) to receive SIG(IO|POLL)"
305 # endif
307 # endif /* USE_UDP_SIGPOLL */
310 RETSIGTYPE
311 sigio_handler(
312 int sig
315 int saved_errno = errno;
316 l_fp ts;
318 get_systime(&ts);
320 # if defined(HAVE_SIGACTION)
321 sigio_handler_active++;
322 if (sigio_handler_active != 1) /* This should never happen! */
323 msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 1");
324 # endif
326 (void)input_handler(&ts);
328 # if defined(HAVE_SIGACTION)
329 sigio_handler_active--;
330 if (sigio_handler_active != 0) /* This should never happen! */
331 msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 0");
332 # endif
334 errno = saved_errno;
338 * Signal support routines.
340 # ifdef HAVE_SIGACTION
341 void
342 set_signal(void)
344 # ifdef USE_SIGIO
345 (void) signal_no_reset(SIGIO, sigio_handler);
346 # endif
347 # ifdef USE_SIGPOLL
348 (void) signal_no_reset(SIGPOLL, sigio_handler);
349 # endif
352 void
353 block_io_and_alarm(void)
355 sigset_t set;
357 if (sigemptyset(&set))
358 msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m");
359 # if defined(USE_SIGIO)
360 if (sigaddset(&set, SIGIO))
361 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m");
362 # endif
363 # if defined(USE_SIGPOLL)
364 if (sigaddset(&set, SIGPOLL))
365 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
366 # endif
367 if (sigaddset(&set, SIGALRM))
368 msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m");
370 if (sigprocmask(SIG_BLOCK, &set, NULL))
371 msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m");
374 void
375 block_sigio(void)
377 if ( sigio_handler_active == 0 ) /* not called from within signal handler */
379 sigset_t set;
381 ++sigio_block_count;
382 if (sigio_block_count > 1)
383 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
384 if (sigio_block_count < 1)
385 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
387 if (sigemptyset(&set))
388 msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m");
389 # if defined(USE_SIGIO)
390 if (sigaddset(&set, SIGIO))
391 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m");
392 # endif
393 # if defined(USE_SIGPOLL)
394 if (sigaddset(&set, SIGPOLL))
395 msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m");
396 # endif
398 if (sigprocmask(SIG_BLOCK, &set, NULL))
399 msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m");
403 void
404 unblock_io_and_alarm(void)
406 sigset_t unset;
408 if (sigemptyset(&unset))
409 msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m");
411 # if defined(USE_SIGIO)
412 if (sigaddset(&unset, SIGIO))
413 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m");
414 # endif
415 # if defined(USE_SIGPOLL)
416 if (sigaddset(&unset, SIGPOLL))
417 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m");
418 # endif
419 if (sigaddset(&unset, SIGALRM))
420 msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m");
422 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
423 msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m");
426 void
427 unblock_sigio(void)
429 if ( sigio_handler_active == 0 ) /* not called from within signal handler */
431 sigset_t unset;
433 --sigio_block_count;
434 if (sigio_block_count > 0)
435 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
436 if (sigio_block_count < 0)
437 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
439 if (sigemptyset(&unset))
440 msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m");
442 # if defined(USE_SIGIO)
443 if (sigaddset(&unset, SIGIO))
444 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m");
445 # endif
446 # if defined(USE_SIGPOLL)
447 if (sigaddset(&unset, SIGPOLL))
448 msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m");
449 # endif
451 if (sigprocmask(SIG_UNBLOCK, &unset, NULL))
452 msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m");
456 void
457 wait_for_signal(void)
459 sigset_t old;
461 if (sigprocmask(SIG_UNBLOCK, NULL, &old))
462 msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m");
464 # if defined(USE_SIGIO)
465 if (sigdelset(&old, SIGIO))
466 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m");
467 # endif
468 # if defined(USE_SIGPOLL)
469 if (sigdelset(&old, SIGPOLL))
470 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m");
471 # endif
472 if (sigdelset(&old, SIGALRM))
473 msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m");
475 if (sigsuspend(&old) && (errno != EINTR))
476 msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m");
479 # else /* !HAVE_SIGACTION */
481 * Must be an old bsd system.
482 * We assume there is no SIGPOLL.
485 void
486 block_io_and_alarm(void)
488 int mask;
490 mask = sigmask(SIGIO) | sigmask(SIGALRM);
491 if (sigblock(mask))
492 msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m");
495 void
496 block_sigio(void)
498 int mask;
500 ++sigio_block_count;
501 if (sigio_block_count > 1)
502 msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1");
503 if (sigio_block_count < 1)
504 msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1");
506 mask = sigmask(SIGIO);
507 if (sigblock(mask))
508 msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m");
511 void
512 set_signal(void)
514 (void) signal_no_reset(SIGIO, sigio_handler);
517 void
518 unblock_io_and_alarm(void)
520 int mask, omask;
522 mask = sigmask(SIGIO) | sigmask(SIGALRM);
523 omask = sigblock(0);
524 omask &= ~mask;
525 (void) sigsetmask(omask);
528 void
529 unblock_sigio(void)
531 int mask, omask;
533 --sigio_block_count;
534 if (sigio_block_count > 0)
535 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0");
536 if (sigio_block_count < 0)
537 msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0");
538 mask = sigmask(SIGIO);
539 omask = sigblock(0);
540 omask &= ~mask;
541 (void) sigsetmask(omask);
544 void
545 wait_for_signal(void)
547 int mask, omask;
549 mask = sigmask(SIGIO) | sigmask(SIGALRM);
550 omask = sigblock(0);
551 omask &= ~mask;
552 if (sigpause(omask) && (errno != EINTR))
553 msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m");
556 # endif /* HAVE_SIGACTION */
557 #else
558 int NotAnEmptyCompilationUnit;
559 #endif