1 /* $OpenBSD: child.c,v 1.16 2011/04/18 12:29:59 krw Exp $ */ 2 3 /* 4 * Copyright (c) 1983 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include "defs.h" 33 34 /* 35 * Functions for rdist related to children 36 */ 37 38 #include <sys/types.h> 39 #include <sys/wait.h> 40 #if defined(NEED_SYS_SELECT_H) 41 #include <sys/select.h> 42 #endif /* NEED_SYS_SELECT_H */ 43 44 typedef enum _PROCSTATE { 45 PSrunning, 46 PSdead 47 } PROCSTATE; 48 49 /* 50 * Structure for child rdist processes mainted by the parent 51 */ 52 struct _child { 53 char *c_name; /* Name of child */ 54 int c_readfd; /* Read file descriptor */ 55 pid_t c_pid; /* Process ID */ 56 PROCSTATE c_state; /* Running? */ 57 struct _child *c_next; /* Next entry */ 58 }; 59 typedef struct _child CHILD; 60 61 static CHILD *childlist = NULL; /* List of children */ 62 int activechildren = 0; /* Number of active children */ 63 extern int maxchildren; /* Max active children */ 64 static int needscan = FALSE; /* Need to scan children */ 65 66 static void removechild(CHILD *); 67 static CHILD *copychild(CHILD *); 68 static void addchild(CHILD *); 69 static void readchild(CHILD *); 70 static pid_t waitproc(int *, int); 71 static void reap(int); 72 static void childscan(void); 73 74 /* 75 * Remove a child that has died (exited) 76 * from the list of active children 77 */ 78 static void 79 removechild(CHILD *child) 80 { 81 CHILD *pc, *prevpc; 82 83 debugmsg(DM_CALL, "removechild(%s, %d, %d) start", 84 child->c_name, child->c_pid, child->c_readfd); 85 86 /* 87 * Find the child in the list 88 */ 89 for (pc = childlist, prevpc = NULL; pc != NULL; 90 prevpc = pc, pc = pc->c_next) 91 if (pc == child) 92 break; 93 94 if (pc == NULL) 95 error("RemoveChild called with bad child %s %d %d", 96 child->c_name, child->c_pid, child->c_readfd); 97 else { 98 /* 99 * Remove the child 100 */ 101 #if defined(POSIX_SIGNALS) 102 sigset_t set; 103 104 sigemptyset(&set); 105 sigaddset(&set, SIGCHLD); 106 sigprocmask(SIG_BLOCK, &set, NULL); 107 #else /* !POSIX_SIGNALS */ 108 int oldmask; 109 110 oldmask = sigblock(sigmask(SIGCHLD)); 111 #endif /* POSIX_SIGNALS */ 112 113 if (prevpc != NULL) 114 prevpc->c_next = pc->c_next; 115 else 116 childlist = pc->c_next; 117 118 #if defined(POSIX_SIGNALS) 119 sigprocmask(SIG_UNBLOCK, &set, NULL); 120 #else 121 sigsetmask(oldmask); 122 #endif /* POSIX_SIGNALS */ 123 124 (void) free(child->c_name); 125 --activechildren; 126 (void) close(child->c_readfd); 127 (void) free(pc); 128 } 129 130 debugmsg(DM_CALL, "removechild() end"); 131 } 132 133 /* 134 * Create a totally new copy of a child. 135 */ 136 static CHILD * 137 copychild(CHILD *child) 138 { 139 CHILD *newc; 140 141 newc = (CHILD *) xmalloc(sizeof(CHILD)); 142 143 newc->c_name = xstrdup(child->c_name); 144 newc->c_readfd = child->c_readfd; 145 newc->c_pid = child->c_pid; 146 newc->c_state = child->c_state; 147 newc->c_next = NULL; 148 149 return(newc); 150 } 151 152 /* 153 * Add a child to the list of children. 154 */ 155 static void 156 addchild(CHILD *child) 157 { 158 CHILD *pc; 159 160 debugmsg(DM_CALL, "addchild() start\n"); 161 162 pc = copychild(child); 163 pc->c_next = childlist; 164 childlist = pc; 165 166 ++activechildren; 167 168 debugmsg(DM_MISC, 169 "addchild() created '%s' pid %d fd %d (active=%d)\n", 170 child->c_name, child->c_pid, child->c_readfd, activechildren); 171 } 172 173 /* 174 * Read input from a child process. 175 */ 176 static void 177 readchild(CHILD *child) 178 { 179 char rbuf[BUFSIZ]; 180 ssize_t amt; 181 182 debugmsg(DM_CALL, "[readchild(%s, %d, %d) start]", 183 child->c_name, child->c_pid, child->c_readfd); 184 185 /* 186 * Check that this is a valid child. 187 */ 188 if (child->c_name == NULL || child->c_readfd <= 0) { 189 debugmsg(DM_MISC, "[readchild(%s, %d, %d) bad child]", 190 child->c_name, child->c_pid, child->c_readfd); 191 return; 192 } 193 194 /* 195 * Read from child and display the result. 196 */ 197 while ((amt = read(child->c_readfd, rbuf, sizeof(rbuf))) > 0) { 198 /* XXX remove these debug calls */ 199 debugmsg(DM_MISC, "[readchild(%s, %d, %d) got %zd bytes]", 200 child->c_name, child->c_pid, child->c_readfd, amt); 201 202 (void) xwrite(fileno(stdout), rbuf, amt); 203 204 debugmsg(DM_MISC, "[readchild(%s, %d, %d) write done]", 205 child->c_name, child->c_pid, child->c_readfd); 206 } 207 208 debugmsg(DM_MISC, "readchild(%s, %d, %d) done: amt = %zd errno = %d\n", 209 child->c_name, child->c_pid, child->c_readfd, amt, errno); 210 211 /* 212 * See if we've reached EOF 213 */ 214 if (amt == 0) 215 debugmsg(DM_MISC, "readchild(%s, %d, %d) at EOF\n", 216 child->c_name, child->c_pid, child->c_readfd); 217 } 218 219 /* 220 * Wait for processes to exit. If "block" is true, then we block 221 * until a process exits. Otherwise, we return right away. If 222 * a process does exit, then the pointer "statval" is set to the 223 * exit status of the exiting process, if statval is not NULL. 224 */ 225 static pid_t 226 waitproc(int *statval, int block) 227 { 228 WAIT_ARG_TYPE status; 229 pid_t pid; 230 int exitval; 231 232 debugmsg(DM_CALL, "waitproc() %s, active children = %d...\n", 233 (block) ? "blocking" : "nonblocking", activechildren); 234 235 #if WAIT_TYPE == WAIT_WAITPID 236 pid = waitpid(-1, &status, (block) ? 0 : WNOHANG); 237 #else 238 #if WAIT_TYPE == WAIT_WAIT3 239 pid = wait3(&status, (block) ? 0 : WNOHANG, NULL); 240 #endif /* WAIT_WAIT3 */ 241 #endif /* WAIT_WAITPID */ 242 243 #if defined(WEXITSTATUS) 244 exitval = WEXITSTATUS(status); 245 #else 246 exitval = status.w_retcode; 247 #endif /* defined(WEXITSTATUS) */ 248 249 if (pid > 0 && exitval != 0) { 250 nerrs++; 251 debugmsg(DM_MISC, 252 "Child process %d exited with status %d.\n", 253 pid, exitval); 254 } 255 256 if (statval) 257 *statval = exitval; 258 259 debugmsg(DM_CALL, "waitproc() done (activechildren = %d)\n", 260 activechildren); 261 262 return(pid); 263 } 264 265 /* 266 * Check to see if any children have exited, and if so, read any unread 267 * input and then remove the child from the list of children. 268 */ 269 static void 270 reap(int dummy) 271 { 272 CHILD *pc; 273 int save_errno = errno; 274 int status = 0; 275 pid_t pid; 276 277 debugmsg(DM_CALL, "reap() called\n"); 278 279 /* 280 * Reap every child that has exited. Break out of the 281 * loop as soon as we run out of children that have 282 * exited so far. 283 */ 284 for ( ; ; ) { 285 /* 286 * Do a non-blocking check for exiting processes 287 */ 288 pid = waitproc(&status, FALSE); 289 debugmsg(DM_MISC, 290 "reap() pid = %d status = %d activechildren=%d\n", 291 pid, status, activechildren); 292 293 /* 294 * See if a child really exited 295 */ 296 if (pid == 0) 297 break; 298 if (pid < 0) { 299 if (errno != ECHILD) 300 error("Wait failed: %s", SYSERR); 301 break; 302 } 303 304 /* 305 * Find the process (pid) and mark it as dead. 306 */ 307 for (pc = childlist; pc; pc = pc->c_next) 308 if (pc->c_pid == pid) { 309 needscan = TRUE; 310 pc->c_state = PSdead; 311 } 312 313 } 314 315 /* 316 * Reset signals 317 */ 318 (void) signal(SIGCHLD, reap); 319 320 debugmsg(DM_CALL, "reap() done\n"); 321 errno = save_errno; 322 } 323 324 /* 325 * Scan the children list to find the child that just exited, 326 * read any unread input, then remove it from the list of active children. 327 */ 328 static void 329 childscan(void) 330 { 331 CHILD *pc, *nextpc; 332 333 debugmsg(DM_CALL, "childscan() start"); 334 335 for (pc = childlist; pc; pc = nextpc) { 336 nextpc = pc->c_next; 337 if (pc->c_state == PSdead) { 338 readchild(pc); 339 removechild(pc); 340 } 341 } 342 343 needscan = FALSE; 344 debugmsg(DM_CALL, "childscan() end"); 345 } 346 347 /* 348 #if defined HAVE_SELECT 349 * 350 * Wait for children to send output for us to read. 351 * 352 #else !HAVE_SELECT 353 * 354 * Wait up for children to exit. 355 * 356 #endif 357 */ 358 void 359 waitup(void) 360 { 361 #if defined(HAVE_SELECT) 362 int count; 363 CHILD *pc; 364 fd_set *rchildfdsp = NULL; 365 int rchildfdsn = 0; 366 size_t bytes; 367 368 debugmsg(DM_CALL, "waitup() start\n"); 369 370 if (needscan) 371 childscan(); 372 373 if (activechildren <= 0) 374 return; 375 376 /* 377 * Settup which children we want to select() on. 378 */ 379 for (pc = childlist; pc; pc = pc->c_next) 380 if (pc->c_readfd > rchildfdsn) 381 rchildfdsn = pc->c_readfd; 382 bytes = howmany(rchildfdsn+1, NFDBITS) * sizeof(fd_mask); 383 if ((rchildfdsp = (fd_set *)malloc(bytes)) == NULL) 384 return; 385 386 memset(rchildfdsp, 0, bytes); 387 for (pc = childlist; pc; pc = pc->c_next) 388 if (pc->c_readfd > 0) { 389 debugmsg(DM_MISC, "waitup() select on %d (%s)\n", 390 pc->c_readfd, pc->c_name); 391 FD_SET(pc->c_readfd, rchildfdsp); 392 } 393 394 /* 395 * Actually call select() 396 */ 397 /* XXX remove debugmsg() calls */ 398 debugmsg(DM_MISC, "waitup() Call select(), activechildren=%d\n", 399 activechildren); 400 401 count = select(rchildfdsn+1, (SELECT_FD_TYPE *) rchildfdsp, 402 NULL, NULL, NULL); 403 404 debugmsg(DM_MISC, "waitup() select returned %d activechildren = %d\n", 405 count, activechildren); 406 407 /* 408 * select() will return count < 0 and errno == EINTR when 409 * there are no active children left. 410 */ 411 if (count < 0) { 412 if (errno != EINTR) 413 error("Select failed reading children input: %s", 414 SYSERR); 415 free(rchildfdsp); 416 return; 417 } 418 419 /* 420 * This should never happen. 421 */ 422 if (count == 0) { 423 error("Select returned an unexpected count of 0."); 424 free(rchildfdsp); 425 return; 426 } 427 428 /* 429 * Go through the list of children and read from each child 430 * which select() detected as ready for reading. 431 */ 432 for (pc = childlist; pc && count > 0; pc = pc->c_next) { 433 /* 434 * Make sure child still exists 435 */ 436 if (pc->c_name && kill(pc->c_pid, 0) < 0 && 437 errno == ESRCH) { 438 debugmsg(DM_MISC, 439 "waitup() proc %d (%s) died unexpectedly!", 440 pc->c_pid, pc->c_name); 441 pc->c_state = PSdead; 442 needscan = TRUE; 443 } 444 445 if (pc->c_name == NULL || 446 !FD_ISSET(pc->c_readfd, rchildfdsp)) 447 continue; 448 449 readchild(pc); 450 --count; 451 } 452 free(rchildfdsp); 453 454 #else /* !defined(HAVE_SELECT) */ 455 456 /* 457 * The non-select() version of waitproc() 458 */ 459 debugmsg(DM_CALL, "waitup() start\n"); 460 461 if (waitproc(NULL, TRUE) > 0) 462 --activechildren; 463 464 #endif /* defined(HAVE_SELECT) */ 465 debugmsg(DM_CALL, "waitup() end\n"); 466 } 467 468 /* 469 * Spawn (create) a new child process for "cmd". 470 */ 471 int 472 spawn(struct cmd *cmd, struct cmd *cmdlist) 473 { 474 pid_t pid; 475 int fildes[2]; 476 char *childname = cmd->c_name; 477 478 if (pipe(fildes) < 0) { 479 error("Cannot create pipe for %s: %s", childname, SYSERR); 480 return(-1); 481 } 482 483 pid = fork(); 484 if (pid == (pid_t)-1) { 485 error("Cannot spawn child for %s: fork failed: %s", 486 childname, SYSERR); 487 return(-1); 488 } else if (pid > 0) { 489 /* 490 * Parent 491 */ 492 static CHILD newchild; 493 494 #if defined(FORK_MISSES) 495 /* 496 * XXX Some OS's have a bug where fork does not 497 * always return properly to the parent 498 * when a number of forks are done very quicky. 499 */ 500 sleep(2); 501 #endif /* FORK_MISSES */ 502 503 /* Receive notification when the child exits */ 504 (void) signal(SIGCHLD, reap); 505 506 /* Settup the new child */ 507 newchild.c_next = NULL; 508 newchild.c_name = childname; 509 newchild.c_readfd = fildes[PIPE_READ]; 510 newchild.c_pid = pid; 511 newchild.c_state = PSrunning; 512 513 /* We're not going to write to the child */ 514 (void) close(fildes[PIPE_WRITE]); 515 516 /* Set non-blocking I/O */ 517 if (setnonblocking(newchild.c_readfd, TRUE) < 0) { 518 error("Set nonblocking I/O failed: %s", SYSERR); 519 return(-1); 520 } 521 522 /* Add new child to child list */ 523 addchild(&newchild); 524 525 /* Mark all other entries for this host as assigned */ 526 markassigned(cmd, cmdlist); 527 528 debugmsg(DM_CALL, 529 "spawn() Forked child %d for host %s active = %d\n", 530 pid, childname, activechildren); 531 return(pid); 532 } else { 533 /* 534 * Child 535 */ 536 537 /* We're not going to read from our parent */ 538 (void) close(fildes[PIPE_READ]); 539 540 /* Make stdout and stderr go to PIPE_WRITE (our parent) */ 541 if (dup2(fildes[PIPE_WRITE], (int)fileno(stdout)) < 0) { 542 error("Cannot duplicate stdout file descriptor: %s", 543 SYSERR); 544 return(-1); 545 } 546 if (dup2(fildes[PIPE_WRITE], (int)fileno(stderr)) < 0) { 547 error("Cannot duplicate stderr file descriptor: %s", 548 SYSERR); 549 return(-1); 550 } 551 552 return(0); 553 } 554 } 555 556 557 /* 558 * Enable or disable non-blocking I/O mode. 559 * 560 * Code is from INN by Rich Salz. 561 */ 562 #if NBIO_TYPE == NBIO_IOCTL 563 #include <sys/ioctl.h> 564 565 int 566 setnonblocking(int fd, int flag) 567 { 568 int state; 569 570 state = flag ? 1 : 0; 571 return(ioctl(fd, FIONBIO, (char *)&state)); 572 } 573 574 #endif /* NBIO_IOCTL */ 575 576 577 #if NBIO_TYPE == NBIO_FCNTL 578 int 579 setnonblocking(int fd, int flag) 580 { 581 int mode; 582 583 if ((mode = fcntl(fd, F_GETFL, 0)) < 0) 584 return(-1); 585 if (flag) 586 mode |= FNDELAY; 587 else 588 mode &= ~FNDELAY; 589 return(fcntl(fd, F_SETFL, mode)); 590 } 591 #endif /* NBIO_FCNTL */ 592