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