154359Sroberto/* 2132451Sroberto * iosignal.c - input/output routines for ntpd. The socket-opening code 354359Sroberto * was shamelessly stolen from ntpd. 454359Sroberto */ 554359Sroberto 6182007Sroberto/* 7182007Sroberto * [Bug 158] 8182007Sroberto * Do the #includes differently, as under some versions of Linux 9182007Sroberto * sys/param.h has a #undef CONFIG_PHONE line in it. 10182007Sroberto * 11182007Sroberto * As we have ~40 CONFIG_ variables, I don't feel like renaming them 12182007Sroberto * every time somebody adds a new macro to some system header. 13182007Sroberto */ 1454359Sroberto 15182007Sroberto#ifdef HAVE_CONFIG_H 16182007Sroberto# include <config.h> 17182007Sroberto#endif 18182007Sroberto 1954359Sroberto#include <stdio.h> 2054359Sroberto#include <signal.h> 2154359Sroberto#ifdef HAVE_SYS_PARAM_H 2254359Sroberto# include <sys/param.h> 2354359Sroberto#endif /* HAVE_SYS_PARAM_H */ 2454359Sroberto#ifdef HAVE_SYS_IOCTL_H 2554359Sroberto# include <sys/ioctl.h> 2654359Sroberto#endif 2782498Sroberto 2854359Sroberto#include <arpa/inet.h> 2954359Sroberto 3054359Sroberto#if _BSDI_VERSION >= 199510 3154359Sroberto# include <ifaddrs.h> 3254359Sroberto#endif 3354359Sroberto 34182007Sroberto# ifdef __QNXNTO__ 35182007Sroberto# include <fcntl.h> 36182007Sroberto# include <unix.h> 37182007Sroberto# define FNDELAY O_NDELAY 38182007Sroberto# endif 39182007Sroberto 40182007Sroberto#include "ntp_machine.h" 41182007Sroberto#include "ntpd.h" 42182007Sroberto#include "ntp_io.h" 43182007Sroberto#include "ntp_if.h" 44182007Sroberto#include "ntp_stdlib.h" 45182007Sroberto#include "iosignal.h" 46182007Sroberto 4754359Sroberto#if defined(HAVE_SIGNALED_IO) 48280849Scystatic RETSIGTYPE sigio_handler (int); 49280849Scy 50280849Scy/* consistency safegurad to catch BLOCK/UNBLOCK oversights */ 5154359Srobertostatic int sigio_block_count = 0; 52280849Scy 53280849Scy/* main inputhandler to be called on SIGIO */ 54280849Scystatic input_handler_t *input_handler_callback = NULL; 55280849Scy 56106163Sroberto# if defined(HAVE_SIGACTION) 57106163Sroberto/* 58106163Sroberto * If sigaction() is used for signal handling and a signal is 59106163Sroberto * pending then the kernel blocks the signal before it calls 60106163Sroberto * the signal handler. 61106163Sroberto * 62106163Sroberto * The variable below is used to take care that the SIGIO signal 63106163Sroberto * is not unintentionally unblocked inside the sigio_handler() 64106163Sroberto * if the handler executes a piece of code that is normally 65106163Sroberto * bracketed by BLOCKIO()/UNBLOCKIO() calls. 66106163Sroberto */ 67106163Srobertostatic int sigio_handler_active = 0; 68106163Sroberto# endif 6954359Sroberto 7054359Sroberto/* 7154359Sroberto * SIGPOLL and SIGIO ROUTINES. 7254359Sroberto */ 7354359Sroberto 7454359Sroberto 7554359Sroberto 7654359Sroberto/* 7754359Sroberto * TTY initialization routines. 7854359Sroberto */ 7954359Srobertoint 8054359Srobertoinit_clock_sig( 8154359Sroberto struct refclockio *rio 8254359Sroberto ) 8354359Sroberto{ 8454359Sroberto# ifdef USE_TTY_SIGPOLL 8554359Sroberto { 8654359Sroberto /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 8754359Sroberto if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0) 8854359Sroberto { 8954359Sroberto msyslog(LOG_ERR, 9054359Sroberto "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m"); 9154359Sroberto return 1; 9254359Sroberto } 9354359Sroberto return 0; 9454359Sroberto } 9554359Sroberto# else 9654359Sroberto /* 9754359Sroberto * Special cases first! 9854359Sroberto */ 9954359Sroberto /* Was: defined(SYS_HPUX) */ 10054359Sroberto# if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT) 10154359Sroberto#define CLOCK_DONE 10254359Sroberto { 10354359Sroberto int pgrp, on = 1; 10454359Sroberto 10554359Sroberto /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 10654359Sroberto pgrp = getpid(); 10754359Sroberto if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1) 10854359Sroberto { 109280849Scy msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m - EXITING"); 11054359Sroberto exit(1); 11154359Sroberto /*NOTREACHED*/ 11254359Sroberto } 11354359Sroberto 11454359Sroberto /* 11554359Sroberto * set non-blocking, async I/O on the descriptor 11654359Sroberto */ 11754359Sroberto if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1) 11854359Sroberto { 119280849Scy msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m - EXITING"); 12054359Sroberto exit(1); 12154359Sroberto /*NOTREACHED*/ 12254359Sroberto } 12354359Sroberto 12454359Sroberto if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1) 12554359Sroberto { 126280849Scy msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m - EXITING"); 12754359Sroberto exit(1); 12854359Sroberto /*NOTREACHED*/ 12954359Sroberto } 13054359Sroberto return 0; 13154359Sroberto } 13254359Sroberto# endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */ 13354359Sroberto /* Was: defined(SYS_AIX) && !defined(_BSD) */ 13454359Sroberto# if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN) 13554359Sroberto /* 13654359Sroberto * SYSV compatibility mode under AIX. 13754359Sroberto */ 13854359Sroberto#define CLOCK_DONE 13954359Sroberto { 14054359Sroberto int pgrp, on = 1; 14154359Sroberto 14254359Sroberto /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 14354359Sroberto if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1) 14454359Sroberto { 14554359Sroberto msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m"); 14654359Sroberto return 1; 14754359Sroberto } 14854359Sroberto pgrp = -getpid(); 14954359Sroberto if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1) 15054359Sroberto { 15154359Sroberto msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m"); 15254359Sroberto return 1; 15354359Sroberto } 15454359Sroberto 15554359Sroberto if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0) 15654359Sroberto { 15754359Sroberto msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m"); 15854359Sroberto return 1; 15954359Sroberto } 16054359Sroberto return 0; 16154359Sroberto } 16254359Sroberto# endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */ 16354359Sroberto# ifndef CLOCK_DONE 16454359Sroberto { 16554359Sroberto /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 16654359Sroberto# if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY) 16754359Sroberto /* 16854359Sroberto * there are, however, always exceptions to the rules 16954359Sroberto * one is, that OSF accepts SETOWN on TTY fd's only, iff they are 17054359Sroberto * CTTYs. SunOS and HPUX do not semm to have this restriction. 17154359Sroberto * another question is: how can you do multiple SIGIO from several 17254359Sroberto * ttys (as they all should be CTTYs), wondering... 17354359Sroberto * 17454359Sroberto * kd 95-07-16 17554359Sroberto */ 17654359Sroberto if (ioctl(rio->fd, TIOCSCTTY, 0) == -1) 17754359Sroberto { 17854359Sroberto msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m"); 17954359Sroberto return 1; 18054359Sroberto } 18154359Sroberto# endif /* TIOCSCTTY && USE_FSETOWNCTTY */ 18254359Sroberto 18354359Sroberto if (fcntl(rio->fd, F_SETOWN, getpid()) == -1) 18454359Sroberto { 18554359Sroberto msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m"); 18654359Sroberto return 1; 18754359Sroberto } 18854359Sroberto 18954359Sroberto if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0) 19054359Sroberto { 19154359Sroberto msyslog(LOG_ERR, 19254359Sroberto "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m"); 19354359Sroberto return 1; 19454359Sroberto } 19554359Sroberto return 0; 19654359Sroberto } 19754359Sroberto# endif /* CLOCK_DONE */ 19854359Sroberto# endif /* !USE_TTY_SIGPOLL */ 19954359Sroberto} 20054359Sroberto 20154359Sroberto 20254359Sroberto 20354359Srobertovoid 20454359Srobertoinit_socket_sig( 20554359Sroberto int fd 20654359Sroberto ) 20754359Sroberto{ 20854359Sroberto# ifdef USE_UDP_SIGPOLL 20954359Sroberto { 21054359Sroberto if (ioctl(fd, I_SETSIG, S_INPUT) < 0) 21154359Sroberto { 21254359Sroberto msyslog(LOG_ERR, 213280849Scy "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m - EXITING"); 21454359Sroberto exit(1); 21554359Sroberto } 21654359Sroberto } 21754359Sroberto# else /* USE_UDP_SIGPOLL */ 21854359Sroberto { 21954359Sroberto int pgrp; 22054359Sroberto# ifdef FIOASYNC 22154359Sroberto int on = 1; 22254359Sroberto# endif 22354359Sroberto 22454359Sroberto# if defined(FIOASYNC) 22554359Sroberto if (ioctl(fd, FIOASYNC, (char *)&on) == -1) 22654359Sroberto { 227280849Scy msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m - EXITING"); 22854359Sroberto exit(1); 22954359Sroberto /*NOTREACHED*/ 23054359Sroberto } 23154359Sroberto# elif defined(FASYNC) 23254359Sroberto { 23354359Sroberto int flags; 23454359Sroberto 23554359Sroberto if ((flags = fcntl(fd, F_GETFL, 0)) == -1) 23654359Sroberto { 237280849Scy msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m - EXITING"); 23854359Sroberto exit(1); 23954359Sroberto /*NOTREACHED*/ 24054359Sroberto } 24154359Sroberto if (fcntl(fd, F_SETFL, flags|FASYNC) < 0) 24254359Sroberto { 243280849Scy msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m - EXITING"); 24454359Sroberto exit(1); 24554359Sroberto /*NOTREACHED*/ 24654359Sroberto } 24754359Sroberto } 24854359Sroberto# else 24954359Sroberto# include "Bletch: Need asynchronous I/O!" 25054359Sroberto# endif 25154359Sroberto 25254359Sroberto# ifdef UDP_BACKWARDS_SETOWN 25354359Sroberto pgrp = -getpid(); 25454359Sroberto# else 25554359Sroberto pgrp = getpid(); 25654359Sroberto# endif 25754359Sroberto 25854359Sroberto# if defined(SIOCSPGRP) 25954359Sroberto if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1) 26054359Sroberto { 261280849Scy msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m - EXITING"); 26254359Sroberto exit(1); 26354359Sroberto /*NOTREACHED*/ 26454359Sroberto } 26554359Sroberto# elif defined(FIOSETOWN) 26654359Sroberto if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1) 26754359Sroberto { 268280849Scy msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m - EXITING"); 26954359Sroberto exit(1); 27054359Sroberto /*NOTREACHED*/ 27154359Sroberto } 27254359Sroberto# elif defined(F_SETOWN) 27354359Sroberto if (fcntl(fd, F_SETOWN, pgrp) == -1) 27454359Sroberto { 275280849Scy msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m - EXITING"); 27654359Sroberto exit(1); 27754359Sroberto /*NOTREACHED*/ 27854359Sroberto } 27954359Sroberto# else 28054359Sroberto# include "Bletch: Need to set process(group) to receive SIG(IO|POLL)" 28154359Sroberto# endif 28254359Sroberto } 28354359Sroberto# endif /* USE_UDP_SIGPOLL */ 28454359Sroberto} 28554359Sroberto 286280849Scystatic RETSIGTYPE 28754359Srobertosigio_handler( 28854359Sroberto int sig 28954359Sroberto ) 29054359Sroberto{ 29154359Sroberto int saved_errno = errno; 29254359Sroberto l_fp ts; 29354359Sroberto 29454359Sroberto get_systime(&ts); 295106163Sroberto 296106163Sroberto# if defined(HAVE_SIGACTION) 297106163Sroberto sigio_handler_active++; 298106163Sroberto if (sigio_handler_active != 1) /* This should never happen! */ 299106163Sroberto msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 1"); 300106163Sroberto# endif 301106163Sroberto 302280849Scy INSIST(input_handler_callback != NULL); 303280849Scy (*input_handler_callback)(&ts); 304106163Sroberto 305106163Sroberto# if defined(HAVE_SIGACTION) 306106163Sroberto sigio_handler_active--; 307106163Sroberto if (sigio_handler_active != 0) /* This should never happen! */ 308106163Sroberto msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 0"); 309106163Sroberto# endif 310106163Sroberto 31154359Sroberto errno = saved_errno; 31254359Sroberto} 31354359Sroberto 31454359Sroberto/* 31554359Sroberto * Signal support routines. 31654359Sroberto */ 31754359Sroberto# ifdef HAVE_SIGACTION 31854359Srobertovoid 319280849Scyset_signal(input_handler_t *input) 32054359Sroberto{ 321280849Scy INSIST(input != NULL); 322280849Scy 323280849Scy input_handler_callback = input; 324280849Scy 325280849Scy using_sigio = TRUE; 32654359Sroberto# ifdef USE_SIGIO 32754359Sroberto (void) signal_no_reset(SIGIO, sigio_handler); 32854359Sroberto# endif 32954359Sroberto# ifdef USE_SIGPOLL 33054359Sroberto (void) signal_no_reset(SIGPOLL, sigio_handler); 33154359Sroberto# endif 33254359Sroberto} 33354359Sroberto 33454359Srobertovoid 33554359Srobertoblock_io_and_alarm(void) 33654359Sroberto{ 33754359Sroberto sigset_t set; 33854359Sroberto 33954359Sroberto if (sigemptyset(&set)) 34054359Sroberto msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m"); 34154359Sroberto# if defined(USE_SIGIO) 34254359Sroberto if (sigaddset(&set, SIGIO)) 34354359Sroberto msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m"); 34454359Sroberto# endif 34554359Sroberto# if defined(USE_SIGPOLL) 34654359Sroberto if (sigaddset(&set, SIGPOLL)) 34754359Sroberto msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m"); 34854359Sroberto# endif 34954359Sroberto if (sigaddset(&set, SIGALRM)) 35054359Sroberto msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m"); 35154359Sroberto 35254359Sroberto if (sigprocmask(SIG_BLOCK, &set, NULL)) 35354359Sroberto msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m"); 35454359Sroberto} 35554359Sroberto 35654359Srobertovoid 35754359Srobertoblock_sigio(void) 35854359Sroberto{ 359106163Sroberto if ( sigio_handler_active == 0 ) /* not called from within signal handler */ 360106163Sroberto { 361106163Sroberto sigset_t set; 36254359Sroberto 363106163Sroberto ++sigio_block_count; 364106163Sroberto if (sigio_block_count > 1) 365106163Sroberto msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1"); 366106163Sroberto if (sigio_block_count < 1) 367106163Sroberto msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1"); 36854359Sroberto 369106163Sroberto if (sigemptyset(&set)) 370106163Sroberto msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m"); 371106163Sroberto# if defined(USE_SIGIO) 372106163Sroberto if (sigaddset(&set, SIGIO)) 373106163Sroberto msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m"); 374106163Sroberto# endif 375106163Sroberto# if defined(USE_SIGPOLL) 376106163Sroberto if (sigaddset(&set, SIGPOLL)) 377106163Sroberto msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m"); 378106163Sroberto# endif 37954359Sroberto 380106163Sroberto if (sigprocmask(SIG_BLOCK, &set, NULL)) 381106163Sroberto msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m"); 382106163Sroberto } 38354359Sroberto} 38454359Sroberto 38554359Srobertovoid 38654359Srobertounblock_io_and_alarm(void) 38754359Sroberto{ 38854359Sroberto sigset_t unset; 38954359Sroberto 39054359Sroberto if (sigemptyset(&unset)) 39154359Sroberto msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m"); 39254359Sroberto 39354359Sroberto# if defined(USE_SIGIO) 39454359Sroberto if (sigaddset(&unset, SIGIO)) 39554359Sroberto msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m"); 39654359Sroberto# endif 39754359Sroberto# if defined(USE_SIGPOLL) 39854359Sroberto if (sigaddset(&unset, SIGPOLL)) 39954359Sroberto msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m"); 40054359Sroberto# endif 40154359Sroberto if (sigaddset(&unset, SIGALRM)) 40254359Sroberto msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m"); 40354359Sroberto 40454359Sroberto if (sigprocmask(SIG_UNBLOCK, &unset, NULL)) 40554359Sroberto msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m"); 40654359Sroberto} 40754359Sroberto 40854359Srobertovoid 40954359Srobertounblock_sigio(void) 41054359Sroberto{ 411106163Sroberto if ( sigio_handler_active == 0 ) /* not called from within signal handler */ 412106163Sroberto { 413106163Sroberto sigset_t unset; 41454359Sroberto 415106163Sroberto --sigio_block_count; 416106163Sroberto if (sigio_block_count > 0) 417106163Sroberto msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0"); 418106163Sroberto if (sigio_block_count < 0) 419106163Sroberto msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0"); 42054359Sroberto 421106163Sroberto if (sigemptyset(&unset)) 422106163Sroberto msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m"); 42354359Sroberto 424106163Sroberto# if defined(USE_SIGIO) 425106163Sroberto if (sigaddset(&unset, SIGIO)) 426106163Sroberto msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m"); 427106163Sroberto# endif 428106163Sroberto# if defined(USE_SIGPOLL) 429106163Sroberto if (sigaddset(&unset, SIGPOLL)) 430106163Sroberto msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m"); 431106163Sroberto# endif 43254359Sroberto 433106163Sroberto if (sigprocmask(SIG_UNBLOCK, &unset, NULL)) 434106163Sroberto msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m"); 435106163Sroberto } 43654359Sroberto} 43754359Sroberto 43854359Srobertovoid 43954359Srobertowait_for_signal(void) 44054359Sroberto{ 44154359Sroberto sigset_t old; 44254359Sroberto 44354359Sroberto if (sigprocmask(SIG_UNBLOCK, NULL, &old)) 44454359Sroberto msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m"); 44554359Sroberto 44654359Sroberto# if defined(USE_SIGIO) 44754359Sroberto if (sigdelset(&old, SIGIO)) 44854359Sroberto msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m"); 44954359Sroberto# endif 45054359Sroberto# if defined(USE_SIGPOLL) 45154359Sroberto if (sigdelset(&old, SIGPOLL)) 45254359Sroberto msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m"); 45354359Sroberto# endif 45454359Sroberto if (sigdelset(&old, SIGALRM)) 45554359Sroberto msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m"); 45654359Sroberto 45754359Sroberto if (sigsuspend(&old) && (errno != EINTR)) 45854359Sroberto msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m"); 45954359Sroberto} 46054359Sroberto 46154359Sroberto# else /* !HAVE_SIGACTION */ 46254359Sroberto/* 46354359Sroberto * Must be an old bsd system. 46454359Sroberto * We assume there is no SIGPOLL. 46554359Sroberto */ 46654359Sroberto 46754359Srobertovoid 46854359Srobertoblock_io_and_alarm(void) 46954359Sroberto{ 47054359Sroberto int mask; 47154359Sroberto 47254359Sroberto mask = sigmask(SIGIO) | sigmask(SIGALRM); 47354359Sroberto if (sigblock(mask)) 47454359Sroberto msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m"); 47554359Sroberto} 47654359Sroberto 47754359Srobertovoid 47854359Srobertoblock_sigio(void) 47954359Sroberto{ 48054359Sroberto int mask; 48154359Sroberto 48254359Sroberto ++sigio_block_count; 48354359Sroberto if (sigio_block_count > 1) 48454359Sroberto msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1"); 48554359Sroberto if (sigio_block_count < 1) 48654359Sroberto msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1"); 48754359Sroberto 48854359Sroberto mask = sigmask(SIGIO); 48954359Sroberto if (sigblock(mask)) 49054359Sroberto msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m"); 49154359Sroberto} 49254359Sroberto 49354359Srobertovoid 494280849Scyset_signal(input_handler_t *input) 49554359Sroberto{ 496280849Scy INSIST(input != NULL); 497280849Scy 498280849Scy input_handler_callback = input; 499280849Scy 500280849Scy using_sigio = TRUE; 50154359Sroberto (void) signal_no_reset(SIGIO, sigio_handler); 50254359Sroberto} 50354359Sroberto 50454359Srobertovoid 50554359Srobertounblock_io_and_alarm(void) 50654359Sroberto{ 50754359Sroberto int mask, omask; 50854359Sroberto 50954359Sroberto mask = sigmask(SIGIO) | sigmask(SIGALRM); 51054359Sroberto omask = sigblock(0); 51154359Sroberto omask &= ~mask; 51254359Sroberto (void) sigsetmask(omask); 51354359Sroberto} 51454359Sroberto 51554359Srobertovoid 51654359Srobertounblock_sigio(void) 51754359Sroberto{ 51854359Sroberto int mask, omask; 51954359Sroberto 52054359Sroberto --sigio_block_count; 52154359Sroberto if (sigio_block_count > 0) 52254359Sroberto msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0"); 52354359Sroberto if (sigio_block_count < 0) 52454359Sroberto msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0"); 52554359Sroberto mask = sigmask(SIGIO); 52654359Sroberto omask = sigblock(0); 52754359Sroberto omask &= ~mask; 52854359Sroberto (void) sigsetmask(omask); 52954359Sroberto} 53054359Sroberto 53154359Srobertovoid 53254359Srobertowait_for_signal(void) 53354359Sroberto{ 53454359Sroberto int mask, omask; 53554359Sroberto 53654359Sroberto mask = sigmask(SIGIO) | sigmask(SIGALRM); 53754359Sroberto omask = sigblock(0); 53854359Sroberto omask &= ~mask; 53954359Sroberto if (sigpause(omask) && (errno != EINTR)) 54054359Sroberto msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m"); 54154359Sroberto} 54254359Sroberto 54354359Sroberto# endif /* HAVE_SIGACTION */ 54454359Sroberto#else 54554359Srobertoint NotAnEmptyCompilationUnit; 54654359Sroberto#endif 547