1c0b746e5SOllivier Robert /* 29c2daa00SOllivier Robert * iosignal.c - input/output routines for ntpd. The socket-opening code 3c0b746e5SOllivier Robert * was shamelessly stolen from ntpd. 4c0b746e5SOllivier Robert */ 5c0b746e5SOllivier Robert 6ea906c41SOllivier Robert /* 7ea906c41SOllivier Robert * [Bug 158] 8ea906c41SOllivier Robert * Do the #includes differently, as under some versions of Linux 9ea906c41SOllivier Robert * sys/param.h has a #undef CONFIG_PHONE line in it. 10ea906c41SOllivier Robert * 11ea906c41SOllivier Robert * As we have ~40 CONFIG_ variables, I don't feel like renaming them 12ea906c41SOllivier Robert * every time somebody adds a new macro to some system header. 13ea906c41SOllivier Robert */ 14ea906c41SOllivier Robert 15ea906c41SOllivier Robert #ifdef HAVE_CONFIG_H 16ea906c41SOllivier Robert # include <config.h> 17ea906c41SOllivier Robert #endif 18c0b746e5SOllivier Robert 19224ba2bdSOllivier Robert #include <stdio.h> 20224ba2bdSOllivier Robert #include <signal.h> 21224ba2bdSOllivier Robert #ifdef HAVE_SYS_PARAM_H 22224ba2bdSOllivier Robert # include <sys/param.h> 23224ba2bdSOllivier Robert #endif /* HAVE_SYS_PARAM_H */ 24224ba2bdSOllivier Robert #ifdef HAVE_SYS_IOCTL_H 25224ba2bdSOllivier Robert # include <sys/ioctl.h> 26224ba2bdSOllivier Robert #endif 27224ba2bdSOllivier Robert 28224ba2bdSOllivier Robert #include <arpa/inet.h> 29224ba2bdSOllivier Robert 30224ba2bdSOllivier Robert #if _BSDI_VERSION >= 199510 31224ba2bdSOllivier Robert # include <ifaddrs.h> 32224ba2bdSOllivier Robert #endif 33224ba2bdSOllivier Robert 34ea906c41SOllivier Robert # ifdef __QNXNTO__ 35ea906c41SOllivier Robert # include <fcntl.h> 36ea906c41SOllivier Robert # include <unix.h> 37ea906c41SOllivier Robert # define FNDELAY O_NDELAY 38ea906c41SOllivier Robert # endif 39ea906c41SOllivier Robert 40ea906c41SOllivier Robert #include "ntp_machine.h" 41ea906c41SOllivier Robert #include "ntpd.h" 42ea906c41SOllivier Robert #include "ntp_io.h" 43ea906c41SOllivier Robert #include "ntp_if.h" 44ea906c41SOllivier Robert #include "ntp_stdlib.h" 45ea906c41SOllivier Robert #include "iosignal.h" 46ea906c41SOllivier Robert 47c0b746e5SOllivier Robert #if defined(HAVE_SIGNALED_IO) 48*2b15cb3dSCy Schubert static RETSIGTYPE sigio_handler (int); 49*2b15cb3dSCy Schubert 50*2b15cb3dSCy Schubert /* consistency safegurad to catch BLOCK/UNBLOCK oversights */ 51c0b746e5SOllivier Robert static int sigio_block_count = 0; 52*2b15cb3dSCy Schubert 53*2b15cb3dSCy Schubert /* main inputhandler to be called on SIGIO */ 54*2b15cb3dSCy Schubert static input_handler_t *input_handler_callback = NULL; 55*2b15cb3dSCy Schubert 56ce265a54SOllivier Robert # if defined(HAVE_SIGACTION) 57ce265a54SOllivier Robert /* 58ce265a54SOllivier Robert * If sigaction() is used for signal handling and a signal is 59ce265a54SOllivier Robert * pending then the kernel blocks the signal before it calls 60ce265a54SOllivier Robert * the signal handler. 61ce265a54SOllivier Robert * 62ce265a54SOllivier Robert * The variable below is used to take care that the SIGIO signal 63ce265a54SOllivier Robert * is not unintentionally unblocked inside the sigio_handler() 64ce265a54SOllivier Robert * if the handler executes a piece of code that is normally 65ce265a54SOllivier Robert * bracketed by BLOCKIO()/UNBLOCKIO() calls. 66ce265a54SOllivier Robert */ 67ce265a54SOllivier Robert static int sigio_handler_active = 0; 68ce265a54SOllivier Robert # endif 69c0b746e5SOllivier Robert 70c0b746e5SOllivier Robert /* 71c0b746e5SOllivier Robert * SIGPOLL and SIGIO ROUTINES. 72c0b746e5SOllivier Robert */ 73c0b746e5SOllivier Robert 74c0b746e5SOllivier Robert 75c0b746e5SOllivier Robert 76c0b746e5SOllivier Robert /* 77c0b746e5SOllivier Robert * TTY initialization routines. 78c0b746e5SOllivier Robert */ 79c0b746e5SOllivier Robert int 80c0b746e5SOllivier Robert init_clock_sig( 81c0b746e5SOllivier Robert struct refclockio *rio 82c0b746e5SOllivier Robert ) 83c0b746e5SOllivier Robert { 84c0b746e5SOllivier Robert # ifdef USE_TTY_SIGPOLL 85c0b746e5SOllivier Robert { 86c0b746e5SOllivier Robert /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 87c0b746e5SOllivier Robert if (ioctl(rio->fd, I_SETSIG, S_INPUT) < 0) 88c0b746e5SOllivier Robert { 89c0b746e5SOllivier Robert msyslog(LOG_ERR, 90c0b746e5SOllivier Robert "init_clock_sig: ioctl(I_SETSIG, S_INPUT) failed: %m"); 91c0b746e5SOllivier Robert return 1; 92c0b746e5SOllivier Robert } 93c0b746e5SOllivier Robert return 0; 94c0b746e5SOllivier Robert } 95c0b746e5SOllivier Robert # else 96c0b746e5SOllivier Robert /* 97c0b746e5SOllivier Robert * Special cases first! 98c0b746e5SOllivier Robert */ 99c0b746e5SOllivier Robert /* Was: defined(SYS_HPUX) */ 100c0b746e5SOllivier Robert # if defined(FIOSSAIOOWN) && defined(FIOSNBIO) && defined(FIOSSAIOSTAT) 101c0b746e5SOllivier Robert #define CLOCK_DONE 102c0b746e5SOllivier Robert { 103c0b746e5SOllivier Robert int pgrp, on = 1; 104c0b746e5SOllivier Robert 105c0b746e5SOllivier Robert /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 106c0b746e5SOllivier Robert pgrp = getpid(); 107c0b746e5SOllivier Robert if (ioctl(rio->fd, FIOSSAIOOWN, (char *)&pgrp) == -1) 108c0b746e5SOllivier Robert { 109*2b15cb3dSCy Schubert msyslog(LOG_ERR, "ioctl(FIOSSAIOOWN) fails for clock I/O: %m - EXITING"); 110c0b746e5SOllivier Robert exit(1); 111c0b746e5SOllivier Robert /*NOTREACHED*/ 112c0b746e5SOllivier Robert } 113c0b746e5SOllivier Robert 114c0b746e5SOllivier Robert /* 115c0b746e5SOllivier Robert * set non-blocking, async I/O on the descriptor 116c0b746e5SOllivier Robert */ 117c0b746e5SOllivier Robert if (ioctl(rio->fd, FIOSNBIO, (char *)&on) == -1) 118c0b746e5SOllivier Robert { 119*2b15cb3dSCy Schubert msyslog(LOG_ERR, "ioctl(FIOSNBIO) fails for clock I/O: %m - EXITING"); 120c0b746e5SOllivier Robert exit(1); 121c0b746e5SOllivier Robert /*NOTREACHED*/ 122c0b746e5SOllivier Robert } 123c0b746e5SOllivier Robert 124c0b746e5SOllivier Robert if (ioctl(rio->fd, FIOSSAIOSTAT, (char *)&on) == -1) 125c0b746e5SOllivier Robert { 126*2b15cb3dSCy Schubert msyslog(LOG_ERR, "ioctl(FIOSSAIOSTAT) fails for clock I/O: %m - EXITING"); 127c0b746e5SOllivier Robert exit(1); 128c0b746e5SOllivier Robert /*NOTREACHED*/ 129c0b746e5SOllivier Robert } 130c0b746e5SOllivier Robert return 0; 131c0b746e5SOllivier Robert } 132c0b746e5SOllivier Robert # endif /* SYS_HPUX: FIOSSAIOOWN && FIOSNBIO && FIOSSAIOSTAT */ 133c0b746e5SOllivier Robert /* Was: defined(SYS_AIX) && !defined(_BSD) */ 134c0b746e5SOllivier Robert # if !defined(_BSD) && defined(_AIX) && defined(FIOASYNC) && defined(FIOSETOWN) 135c0b746e5SOllivier Robert /* 136c0b746e5SOllivier Robert * SYSV compatibility mode under AIX. 137c0b746e5SOllivier Robert */ 138c0b746e5SOllivier Robert #define CLOCK_DONE 139c0b746e5SOllivier Robert { 140c0b746e5SOllivier Robert int pgrp, on = 1; 141c0b746e5SOllivier Robert 142c0b746e5SOllivier Robert /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 143c0b746e5SOllivier Robert if (ioctl(rio->fd, FIOASYNC, (char *)&on) == -1) 144c0b746e5SOllivier Robert { 145c0b746e5SOllivier Robert msyslog(LOG_ERR, "ioctl(FIOASYNC) fails for clock I/O: %m"); 146c0b746e5SOllivier Robert return 1; 147c0b746e5SOllivier Robert } 148c0b746e5SOllivier Robert pgrp = -getpid(); 149c0b746e5SOllivier Robert if (ioctl(rio->fd, FIOSETOWN, (char*)&pgrp) == -1) 150c0b746e5SOllivier Robert { 151c0b746e5SOllivier Robert msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails for clock I/O: %m"); 152c0b746e5SOllivier Robert return 1; 153c0b746e5SOllivier Robert } 154c0b746e5SOllivier Robert 155c0b746e5SOllivier Robert if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0) 156c0b746e5SOllivier Robert { 157c0b746e5SOllivier Robert msyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m"); 158c0b746e5SOllivier Robert return 1; 159c0b746e5SOllivier Robert } 160c0b746e5SOllivier Robert return 0; 161c0b746e5SOllivier Robert } 162c0b746e5SOllivier Robert # endif /* AIX && !BSD: !_BSD && FIOASYNC && FIOSETOWN */ 163c0b746e5SOllivier Robert # ifndef CLOCK_DONE 164c0b746e5SOllivier Robert { 165c0b746e5SOllivier Robert /* DO NOT ATTEMPT TO MAKE CLOCK-FD A CTTY: not portable, unreliable */ 166c0b746e5SOllivier Robert # if defined(TIOCSCTTY) && defined(USE_FSETOWNCTTY) 167c0b746e5SOllivier Robert /* 168c0b746e5SOllivier Robert * there are, however, always exceptions to the rules 169c0b746e5SOllivier Robert * one is, that OSF accepts SETOWN on TTY fd's only, iff they are 170c0b746e5SOllivier Robert * CTTYs. SunOS and HPUX do not semm to have this restriction. 171c0b746e5SOllivier Robert * another question is: how can you do multiple SIGIO from several 172c0b746e5SOllivier Robert * ttys (as they all should be CTTYs), wondering... 173c0b746e5SOllivier Robert * 174c0b746e5SOllivier Robert * kd 95-07-16 175c0b746e5SOllivier Robert */ 176c0b746e5SOllivier Robert if (ioctl(rio->fd, TIOCSCTTY, 0) == -1) 177c0b746e5SOllivier Robert { 178c0b746e5SOllivier Robert msyslog(LOG_ERR, "ioctl(TIOCSCTTY, 0) fails for clock I/O: %m"); 179c0b746e5SOllivier Robert return 1; 180c0b746e5SOllivier Robert } 181c0b746e5SOllivier Robert # endif /* TIOCSCTTY && USE_FSETOWNCTTY */ 182c0b746e5SOllivier Robert 183c0b746e5SOllivier Robert if (fcntl(rio->fd, F_SETOWN, getpid()) == -1) 184c0b746e5SOllivier Robert { 185c0b746e5SOllivier Robert msyslog(LOG_ERR, "fcntl(F_SETOWN) fails for clock I/O: %m"); 186c0b746e5SOllivier Robert return 1; 187c0b746e5SOllivier Robert } 188c0b746e5SOllivier Robert 189c0b746e5SOllivier Robert if (fcntl(rio->fd, F_SETFL, FNDELAY|FASYNC) < 0) 190c0b746e5SOllivier Robert { 191c0b746e5SOllivier Robert msyslog(LOG_ERR, 192c0b746e5SOllivier Robert "fcntl(FNDELAY|FASYNC) fails for clock I/O: %m"); 193c0b746e5SOllivier Robert return 1; 194c0b746e5SOllivier Robert } 195c0b746e5SOllivier Robert return 0; 196c0b746e5SOllivier Robert } 197c0b746e5SOllivier Robert # endif /* CLOCK_DONE */ 198c0b746e5SOllivier Robert # endif /* !USE_TTY_SIGPOLL */ 199c0b746e5SOllivier Robert } 200c0b746e5SOllivier Robert 201c0b746e5SOllivier Robert 202c0b746e5SOllivier Robert 203c0b746e5SOllivier Robert void 204c0b746e5SOllivier Robert init_socket_sig( 205c0b746e5SOllivier Robert int fd 206c0b746e5SOllivier Robert ) 207c0b746e5SOllivier Robert { 208c0b746e5SOllivier Robert # ifdef USE_UDP_SIGPOLL 209c0b746e5SOllivier Robert { 210c0b746e5SOllivier Robert if (ioctl(fd, I_SETSIG, S_INPUT) < 0) 211c0b746e5SOllivier Robert { 212c0b746e5SOllivier Robert msyslog(LOG_ERR, 213*2b15cb3dSCy Schubert "init_socket_sig: ioctl(I_SETSIG, S_INPUT) failed: %m - EXITING"); 214c0b746e5SOllivier Robert exit(1); 215c0b746e5SOllivier Robert } 216c0b746e5SOllivier Robert } 217c0b746e5SOllivier Robert # else /* USE_UDP_SIGPOLL */ 218c0b746e5SOllivier Robert { 219c0b746e5SOllivier Robert int pgrp; 220c0b746e5SOllivier Robert # ifdef FIOASYNC 221c0b746e5SOllivier Robert int on = 1; 222c0b746e5SOllivier Robert # endif 223c0b746e5SOllivier Robert 224c0b746e5SOllivier Robert # if defined(FIOASYNC) 225c0b746e5SOllivier Robert if (ioctl(fd, FIOASYNC, (char *)&on) == -1) 226c0b746e5SOllivier Robert { 227*2b15cb3dSCy Schubert msyslog(LOG_ERR, "ioctl(FIOASYNC) fails: %m - EXITING"); 228c0b746e5SOllivier Robert exit(1); 229c0b746e5SOllivier Robert /*NOTREACHED*/ 230c0b746e5SOllivier Robert } 231c0b746e5SOllivier Robert # elif defined(FASYNC) 232c0b746e5SOllivier Robert { 233c0b746e5SOllivier Robert int flags; 234c0b746e5SOllivier Robert 235c0b746e5SOllivier Robert if ((flags = fcntl(fd, F_GETFL, 0)) == -1) 236c0b746e5SOllivier Robert { 237*2b15cb3dSCy Schubert msyslog(LOG_ERR, "fcntl(F_GETFL) fails: %m - EXITING"); 238c0b746e5SOllivier Robert exit(1); 239c0b746e5SOllivier Robert /*NOTREACHED*/ 240c0b746e5SOllivier Robert } 241c0b746e5SOllivier Robert if (fcntl(fd, F_SETFL, flags|FASYNC) < 0) 242c0b746e5SOllivier Robert { 243*2b15cb3dSCy Schubert msyslog(LOG_ERR, "fcntl(...|FASYNC) fails: %m - EXITING"); 244c0b746e5SOllivier Robert exit(1); 245c0b746e5SOllivier Robert /*NOTREACHED*/ 246c0b746e5SOllivier Robert } 247c0b746e5SOllivier Robert } 248c0b746e5SOllivier Robert # else 249c0b746e5SOllivier Robert # include "Bletch: Need asynchronous I/O!" 250c0b746e5SOllivier Robert # endif 251c0b746e5SOllivier Robert 252c0b746e5SOllivier Robert # ifdef UDP_BACKWARDS_SETOWN 253c0b746e5SOllivier Robert pgrp = -getpid(); 254c0b746e5SOllivier Robert # else 255c0b746e5SOllivier Robert pgrp = getpid(); 256c0b746e5SOllivier Robert # endif 257c0b746e5SOllivier Robert 258c0b746e5SOllivier Robert # if defined(SIOCSPGRP) 259c0b746e5SOllivier Robert if (ioctl(fd, SIOCSPGRP, (char *)&pgrp) == -1) 260c0b746e5SOllivier Robert { 261*2b15cb3dSCy Schubert msyslog(LOG_ERR, "ioctl(SIOCSPGRP) fails: %m - EXITING"); 262c0b746e5SOllivier Robert exit(1); 263c0b746e5SOllivier Robert /*NOTREACHED*/ 264c0b746e5SOllivier Robert } 265c0b746e5SOllivier Robert # elif defined(FIOSETOWN) 266c0b746e5SOllivier Robert if (ioctl(fd, FIOSETOWN, (char*)&pgrp) == -1) 267c0b746e5SOllivier Robert { 268*2b15cb3dSCy Schubert msyslog(LOG_ERR, "ioctl(FIOSETOWN) fails: %m - EXITING"); 269c0b746e5SOllivier Robert exit(1); 270c0b746e5SOllivier Robert /*NOTREACHED*/ 271c0b746e5SOllivier Robert } 272c0b746e5SOllivier Robert # elif defined(F_SETOWN) 273c0b746e5SOllivier Robert if (fcntl(fd, F_SETOWN, pgrp) == -1) 274c0b746e5SOllivier Robert { 275*2b15cb3dSCy Schubert msyslog(LOG_ERR, "fcntl(F_SETOWN) fails: %m - EXITING"); 276c0b746e5SOllivier Robert exit(1); 277c0b746e5SOllivier Robert /*NOTREACHED*/ 278c0b746e5SOllivier Robert } 279c0b746e5SOllivier Robert # else 280c0b746e5SOllivier Robert # include "Bletch: Need to set process(group) to receive SIG(IO|POLL)" 281c0b746e5SOllivier Robert # endif 282c0b746e5SOllivier Robert } 283c0b746e5SOllivier Robert # endif /* USE_UDP_SIGPOLL */ 284c0b746e5SOllivier Robert } 285c0b746e5SOllivier Robert 286*2b15cb3dSCy Schubert static RETSIGTYPE 287c0b746e5SOllivier Robert sigio_handler( 288c0b746e5SOllivier Robert int sig 289c0b746e5SOllivier Robert ) 290c0b746e5SOllivier Robert { 291c0b746e5SOllivier Robert int saved_errno = errno; 292c0b746e5SOllivier Robert l_fp ts; 293c0b746e5SOllivier Robert 294c0b746e5SOllivier Robert get_systime(&ts); 295ce265a54SOllivier Robert 296ce265a54SOllivier Robert # if defined(HAVE_SIGACTION) 297ce265a54SOllivier Robert sigio_handler_active++; 298ce265a54SOllivier Robert if (sigio_handler_active != 1) /* This should never happen! */ 299ce265a54SOllivier Robert msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 1"); 300ce265a54SOllivier Robert # endif 301ce265a54SOllivier Robert 302*2b15cb3dSCy Schubert INSIST(input_handler_callback != NULL); 303*2b15cb3dSCy Schubert (*input_handler_callback)(&ts); 304ce265a54SOllivier Robert 305ce265a54SOllivier Robert # if defined(HAVE_SIGACTION) 306ce265a54SOllivier Robert sigio_handler_active--; 307ce265a54SOllivier Robert if (sigio_handler_active != 0) /* This should never happen! */ 308ce265a54SOllivier Robert msyslog(LOG_ERR, "sigio_handler: sigio_handler_active != 0"); 309ce265a54SOllivier Robert # endif 310ce265a54SOllivier Robert 311c0b746e5SOllivier Robert errno = saved_errno; 312c0b746e5SOllivier Robert } 313c0b746e5SOllivier Robert 314c0b746e5SOllivier Robert /* 315c0b746e5SOllivier Robert * Signal support routines. 316c0b746e5SOllivier Robert */ 317c0b746e5SOllivier Robert # ifdef HAVE_SIGACTION 318c0b746e5SOllivier Robert void 319*2b15cb3dSCy Schubert set_signal(input_handler_t *input) 320c0b746e5SOllivier Robert { 321*2b15cb3dSCy Schubert INSIST(input != NULL); 322*2b15cb3dSCy Schubert 323*2b15cb3dSCy Schubert input_handler_callback = input; 324*2b15cb3dSCy Schubert 325*2b15cb3dSCy Schubert using_sigio = TRUE; 326c0b746e5SOllivier Robert # ifdef USE_SIGIO 327c0b746e5SOllivier Robert (void) signal_no_reset(SIGIO, sigio_handler); 328c0b746e5SOllivier Robert # endif 329c0b746e5SOllivier Robert # ifdef USE_SIGPOLL 330c0b746e5SOllivier Robert (void) signal_no_reset(SIGPOLL, sigio_handler); 331c0b746e5SOllivier Robert # endif 332c0b746e5SOllivier Robert } 333c0b746e5SOllivier Robert 334c0b746e5SOllivier Robert void 335c0b746e5SOllivier Robert block_io_and_alarm(void) 336c0b746e5SOllivier Robert { 337c0b746e5SOllivier Robert sigset_t set; 338c0b746e5SOllivier Robert 339c0b746e5SOllivier Robert if (sigemptyset(&set)) 340c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_io_and_alarm: sigemptyset() failed: %m"); 341c0b746e5SOllivier Robert # if defined(USE_SIGIO) 342c0b746e5SOllivier Robert if (sigaddset(&set, SIGIO)) 343c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGIO) failed: %m"); 344c0b746e5SOllivier Robert # endif 345c0b746e5SOllivier Robert # if defined(USE_SIGPOLL) 346c0b746e5SOllivier Robert if (sigaddset(&set, SIGPOLL)) 347c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGPOLL) failed: %m"); 348c0b746e5SOllivier Robert # endif 349c0b746e5SOllivier Robert if (sigaddset(&set, SIGALRM)) 350c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_io_and_alarm: sigaddset(SIGALRM) failed: %m"); 351c0b746e5SOllivier Robert 352c0b746e5SOllivier Robert if (sigprocmask(SIG_BLOCK, &set, NULL)) 353c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_io_and_alarm: sigprocmask() failed: %m"); 354c0b746e5SOllivier Robert } 355c0b746e5SOllivier Robert 356c0b746e5SOllivier Robert void 357c0b746e5SOllivier Robert block_sigio(void) 358c0b746e5SOllivier Robert { 359ce265a54SOllivier Robert if ( sigio_handler_active == 0 ) /* not called from within signal handler */ 360ce265a54SOllivier Robert { 361c0b746e5SOllivier Robert sigset_t set; 362c0b746e5SOllivier Robert 363c0b746e5SOllivier Robert ++sigio_block_count; 364c0b746e5SOllivier Robert if (sigio_block_count > 1) 365c0b746e5SOllivier Robert msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1"); 366c0b746e5SOllivier Robert if (sigio_block_count < 1) 367c0b746e5SOllivier Robert msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1"); 368c0b746e5SOllivier Robert 369c0b746e5SOllivier Robert if (sigemptyset(&set)) 370c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_sigio: sigemptyset() failed: %m"); 371c0b746e5SOllivier Robert # if defined(USE_SIGIO) 372c0b746e5SOllivier Robert if (sigaddset(&set, SIGIO)) 373c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_sigio: sigaddset(SIGIO) failed: %m"); 374c0b746e5SOllivier Robert # endif 375c0b746e5SOllivier Robert # if defined(USE_SIGPOLL) 376c0b746e5SOllivier Robert if (sigaddset(&set, SIGPOLL)) 377c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_sigio: sigaddset(SIGPOLL) failed: %m"); 378c0b746e5SOllivier Robert # endif 379c0b746e5SOllivier Robert 380c0b746e5SOllivier Robert if (sigprocmask(SIG_BLOCK, &set, NULL)) 381c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_sigio: sigprocmask() failed: %m"); 382c0b746e5SOllivier Robert } 383ce265a54SOllivier Robert } 384c0b746e5SOllivier Robert 385c0b746e5SOllivier Robert void 386c0b746e5SOllivier Robert unblock_io_and_alarm(void) 387c0b746e5SOllivier Robert { 388c0b746e5SOllivier Robert sigset_t unset; 389c0b746e5SOllivier Robert 390c0b746e5SOllivier Robert if (sigemptyset(&unset)) 391c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_io_and_alarm: sigemptyset() failed: %m"); 392c0b746e5SOllivier Robert 393c0b746e5SOllivier Robert # if defined(USE_SIGIO) 394c0b746e5SOllivier Robert if (sigaddset(&unset, SIGIO)) 395c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGIO) failed: %m"); 396c0b746e5SOllivier Robert # endif 397c0b746e5SOllivier Robert # if defined(USE_SIGPOLL) 398c0b746e5SOllivier Robert if (sigaddset(&unset, SIGPOLL)) 399c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGPOLL) failed: %m"); 400c0b746e5SOllivier Robert # endif 401c0b746e5SOllivier Robert if (sigaddset(&unset, SIGALRM)) 402c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_io_and_alarm: sigaddset(SIGALRM) failed: %m"); 403c0b746e5SOllivier Robert 404c0b746e5SOllivier Robert if (sigprocmask(SIG_UNBLOCK, &unset, NULL)) 405c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_io_and_alarm: sigprocmask() failed: %m"); 406c0b746e5SOllivier Robert } 407c0b746e5SOllivier Robert 408c0b746e5SOllivier Robert void 409c0b746e5SOllivier Robert unblock_sigio(void) 410c0b746e5SOllivier Robert { 411ce265a54SOllivier Robert if ( sigio_handler_active == 0 ) /* not called from within signal handler */ 412ce265a54SOllivier Robert { 413c0b746e5SOllivier Robert sigset_t unset; 414c0b746e5SOllivier Robert 415c0b746e5SOllivier Robert --sigio_block_count; 416c0b746e5SOllivier Robert if (sigio_block_count > 0) 417c0b746e5SOllivier Robert msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0"); 418c0b746e5SOllivier Robert if (sigio_block_count < 0) 419c0b746e5SOllivier Robert msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0"); 420c0b746e5SOllivier Robert 421c0b746e5SOllivier Robert if (sigemptyset(&unset)) 422c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_sigio: sigemptyset() failed: %m"); 423c0b746e5SOllivier Robert 424c0b746e5SOllivier Robert # if defined(USE_SIGIO) 425c0b746e5SOllivier Robert if (sigaddset(&unset, SIGIO)) 426c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGIO) failed: %m"); 427c0b746e5SOllivier Robert # endif 428c0b746e5SOllivier Robert # if defined(USE_SIGPOLL) 429c0b746e5SOllivier Robert if (sigaddset(&unset, SIGPOLL)) 430c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_sigio: sigaddset(SIGPOLL) failed: %m"); 431c0b746e5SOllivier Robert # endif 432c0b746e5SOllivier Robert 433c0b746e5SOllivier Robert if (sigprocmask(SIG_UNBLOCK, &unset, NULL)) 434c0b746e5SOllivier Robert msyslog(LOG_ERR, "unblock_sigio: sigprocmask() failed: %m"); 435c0b746e5SOllivier Robert } 436ce265a54SOllivier Robert } 437c0b746e5SOllivier Robert 438c0b746e5SOllivier Robert void 439c0b746e5SOllivier Robert wait_for_signal(void) 440c0b746e5SOllivier Robert { 441c0b746e5SOllivier Robert sigset_t old; 442c0b746e5SOllivier Robert 443c0b746e5SOllivier Robert if (sigprocmask(SIG_UNBLOCK, NULL, &old)) 444c0b746e5SOllivier Robert msyslog(LOG_ERR, "wait_for_signal: sigprocmask() failed: %m"); 445c0b746e5SOllivier Robert 446c0b746e5SOllivier Robert # if defined(USE_SIGIO) 447c0b746e5SOllivier Robert if (sigdelset(&old, SIGIO)) 448c0b746e5SOllivier Robert msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGIO) failed: %m"); 449c0b746e5SOllivier Robert # endif 450c0b746e5SOllivier Robert # if defined(USE_SIGPOLL) 451c0b746e5SOllivier Robert if (sigdelset(&old, SIGPOLL)) 452c0b746e5SOllivier Robert msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGPOLL) failed: %m"); 453c0b746e5SOllivier Robert # endif 454c0b746e5SOllivier Robert if (sigdelset(&old, SIGALRM)) 455c0b746e5SOllivier Robert msyslog(LOG_ERR, "wait_for_signal: sigdelset(SIGALRM) failed: %m"); 456c0b746e5SOllivier Robert 457c0b746e5SOllivier Robert if (sigsuspend(&old) && (errno != EINTR)) 458c0b746e5SOllivier Robert msyslog(LOG_ERR, "wait_for_signal: sigsuspend() failed: %m"); 459c0b746e5SOllivier Robert } 460c0b746e5SOllivier Robert 461c0b746e5SOllivier Robert # else /* !HAVE_SIGACTION */ 462c0b746e5SOllivier Robert /* 463c0b746e5SOllivier Robert * Must be an old bsd system. 464c0b746e5SOllivier Robert * We assume there is no SIGPOLL. 465c0b746e5SOllivier Robert */ 466c0b746e5SOllivier Robert 467c0b746e5SOllivier Robert void 468c0b746e5SOllivier Robert block_io_and_alarm(void) 469c0b746e5SOllivier Robert { 470c0b746e5SOllivier Robert int mask; 471c0b746e5SOllivier Robert 472c0b746e5SOllivier Robert mask = sigmask(SIGIO) | sigmask(SIGALRM); 473c0b746e5SOllivier Robert if (sigblock(mask)) 474c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_io_and_alarm: sigblock() failed: %m"); 475c0b746e5SOllivier Robert } 476c0b746e5SOllivier Robert 477c0b746e5SOllivier Robert void 478c0b746e5SOllivier Robert block_sigio(void) 479c0b746e5SOllivier Robert { 480c0b746e5SOllivier Robert int mask; 481c0b746e5SOllivier Robert 482c0b746e5SOllivier Robert ++sigio_block_count; 483c0b746e5SOllivier Robert if (sigio_block_count > 1) 484c0b746e5SOllivier Robert msyslog(LOG_INFO, "block_sigio: sigio_block_count > 1"); 485c0b746e5SOllivier Robert if (sigio_block_count < 1) 486c0b746e5SOllivier Robert msyslog(LOG_INFO, "block_sigio: sigio_block_count < 1"); 487c0b746e5SOllivier Robert 488c0b746e5SOllivier Robert mask = sigmask(SIGIO); 489c0b746e5SOllivier Robert if (sigblock(mask)) 490c0b746e5SOllivier Robert msyslog(LOG_ERR, "block_sigio: sigblock() failed: %m"); 491c0b746e5SOllivier Robert } 492c0b746e5SOllivier Robert 493c0b746e5SOllivier Robert void 494*2b15cb3dSCy Schubert set_signal(input_handler_t *input) 495c0b746e5SOllivier Robert { 496*2b15cb3dSCy Schubert INSIST(input != NULL); 497*2b15cb3dSCy Schubert 498*2b15cb3dSCy Schubert input_handler_callback = input; 499*2b15cb3dSCy Schubert 500*2b15cb3dSCy Schubert using_sigio = TRUE; 501c0b746e5SOllivier Robert (void) signal_no_reset(SIGIO, sigio_handler); 502c0b746e5SOllivier Robert } 503c0b746e5SOllivier Robert 504c0b746e5SOllivier Robert void 505c0b746e5SOllivier Robert unblock_io_and_alarm(void) 506c0b746e5SOllivier Robert { 507c0b746e5SOllivier Robert int mask, omask; 508c0b746e5SOllivier Robert 509c0b746e5SOllivier Robert mask = sigmask(SIGIO) | sigmask(SIGALRM); 510c0b746e5SOllivier Robert omask = sigblock(0); 511c0b746e5SOllivier Robert omask &= ~mask; 512c0b746e5SOllivier Robert (void) sigsetmask(omask); 513c0b746e5SOllivier Robert } 514c0b746e5SOllivier Robert 515c0b746e5SOllivier Robert void 516c0b746e5SOllivier Robert unblock_sigio(void) 517c0b746e5SOllivier Robert { 518c0b746e5SOllivier Robert int mask, omask; 519c0b746e5SOllivier Robert 520c0b746e5SOllivier Robert --sigio_block_count; 521c0b746e5SOllivier Robert if (sigio_block_count > 0) 522c0b746e5SOllivier Robert msyslog(LOG_INFO, "unblock_sigio: sigio_block_count > 0"); 523c0b746e5SOllivier Robert if (sigio_block_count < 0) 524c0b746e5SOllivier Robert msyslog(LOG_INFO, "unblock_sigio: sigio_block_count < 0"); 525c0b746e5SOllivier Robert mask = sigmask(SIGIO); 526c0b746e5SOllivier Robert omask = sigblock(0); 527c0b746e5SOllivier Robert omask &= ~mask; 528c0b746e5SOllivier Robert (void) sigsetmask(omask); 529c0b746e5SOllivier Robert } 530c0b746e5SOllivier Robert 531c0b746e5SOllivier Robert void 532c0b746e5SOllivier Robert wait_for_signal(void) 533c0b746e5SOllivier Robert { 534c0b746e5SOllivier Robert int mask, omask; 535c0b746e5SOllivier Robert 536c0b746e5SOllivier Robert mask = sigmask(SIGIO) | sigmask(SIGALRM); 537c0b746e5SOllivier Robert omask = sigblock(0); 538c0b746e5SOllivier Robert omask &= ~mask; 539c0b746e5SOllivier Robert if (sigpause(omask) && (errno != EINTR)) 540c0b746e5SOllivier Robert msyslog(LOG_ERR, "wait_for_signal: sigspause() failed: %m"); 541c0b746e5SOllivier Robert } 542c0b746e5SOllivier Robert 543c0b746e5SOllivier Robert # endif /* HAVE_SIGACTION */ 544c0b746e5SOllivier Robert #else 545c0b746e5SOllivier Robert int NotAnEmptyCompilationUnit; 546c0b746e5SOllivier Robert #endif 547