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