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