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