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