1 /* $NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1988, 1989 by Adam de Boor 37 * Copyright (c) 1989 by Berkeley Softworks 38 * All rights reserved. 39 * 40 * This code is derived from software contributed to Berkeley by 41 * Adam de Boor. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by the University of 54 * California, Berkeley and its contributors. 55 * 4. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 */ 71 72 #ifndef MAKE_NATIVE 73 static char rcsid[] = "$NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $"; 74 #else 75 #include <sys/cdefs.h> 76 #ifndef lint 77 #if 0 78 static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; 79 #else 80 __RCSID("$NetBSD: job.c,v 1.165 2013/01/26 15:52:59 christos Exp $"); 81 #endif 82 #endif /* not lint */ 83 #endif 84 85 /*- 86 * job.c -- 87 * handle the creation etc. of our child processes. 88 * 89 * Interface: 90 * Job_Make Start the creation of the given target. 91 * 92 * Job_CatchChildren Check for and handle the termination of any 93 * children. This must be called reasonably 94 * frequently to keep the whole make going at 95 * a decent clip, since job table entries aren't 96 * removed until their process is caught this way. 97 * 98 * Job_CatchOutput Print any output our children have produced. 99 * Should also be called fairly frequently to 100 * keep the user informed of what's going on. 101 * If no output is waiting, it will block for 102 * a time given by the SEL_* constants, below, 103 * or until output is ready. 104 * 105 * Job_Init Called to intialize this module. in addition, 106 * any commands attached to the .BEGIN target 107 * are executed before this function returns. 108 * Hence, the makefile must have been parsed 109 * before this function is called. 110 * 111 * Job_End Cleanup any memory used. 112 * 113 * Job_ParseShell Given the line following a .SHELL target, parse 114 * the line as a shell specification. Returns 115 * FAILURE if the spec was incorrect. 116 * 117 * Job_Finish Perform any final processing which needs doing. 118 * This includes the execution of any commands 119 * which have been/were attached to the .END 120 * target. It should only be called when the 121 * job table is empty. 122 * 123 * Job_AbortAll Abort all currently running jobs. It doesn't 124 * handle output or do anything for the jobs, 125 * just kills them. It should only be called in 126 * an emergency, as it were. 127 * 128 * Job_CheckCommands Verify that the commands for a target are 129 * ok. Provide them if necessary and possible. 130 * 131 * Job_Touch Update a target without really updating it. 132 * 133 * Job_Wait Wait for all currently-running jobs to finish. 134 */ 135 136 #ifdef HAVE_CONFIG_H 137 # include "config.h" 138 #endif 139 #include <sys/types.h> 140 #include <sys/stat.h> 141 #include <sys/file.h> 142 #include <sys/time.h> 143 #include "wait.h" 144 145 #include <errno.h> 146 #include <fcntl.h> 147 #if !defined(USE_SELECT) && defined(HAVE_POLL_H) 148 #include <poll.h> 149 #else 150 #ifndef USE_SELECT /* no poll.h */ 151 # define USE_SELECT 152 #endif 153 #if defined(HAVE_SYS_SELECT_H) 154 # include <sys/select.h> 155 #endif 156 #endif 157 #include <signal.h> 158 #include <stdio.h> 159 #include <string.h> 160 #include <utime.h> 161 #if defined(HAVE_SYS_SOCKET_H) 162 # include <sys/socket.h> 163 #endif 164 165 #include "make.h" 166 #include "hash.h" 167 #include "dir.h" 168 #include "job.h" 169 #include "pathnames.h" 170 #include "trace.h" 171 # define STATIC static 172 173 /* 174 * error handling variables 175 */ 176 static int errors = 0; /* number of errors reported */ 177 static int aborting = 0; /* why is the make aborting? */ 178 #define ABORT_ERROR 1 /* Because of an error */ 179 #define ABORT_INTERRUPT 2 /* Because it was interrupted */ 180 #define ABORT_WAIT 3 /* Waiting for jobs to finish */ 181 #define JOB_TOKENS "+EI+" /* Token to requeue for each abort state */ 182 183 /* 184 * this tracks the number of tokens currently "out" to build jobs. 185 */ 186 int jobTokensRunning = 0; 187 int not_parallel = 0; /* set if .NOT_PARALLEL */ 188 189 /* 190 * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file 191 * is a char! So when we go above 127 we turn negative! 192 */ 193 #define FILENO(a) ((unsigned) fileno(a)) 194 195 /* 196 * post-make command processing. The node postCommands is really just the 197 * .END target but we keep it around to avoid having to search for it 198 * all the time. 199 */ 200 static GNode *postCommands = NULL; 201 /* node containing commands to execute when 202 * everything else is done */ 203 static int numCommands; /* The number of commands actually printed 204 * for a target. Should this number be 205 * 0, no shell will be executed. */ 206 207 /* 208 * Return values from JobStart. 209 */ 210 #define JOB_RUNNING 0 /* Job is running */ 211 #define JOB_ERROR 1 /* Error in starting the job */ 212 #define JOB_FINISHED 2 /* The job is already finished */ 213 214 /* 215 * Descriptions for various shells. 216 * 217 * The build environment may set DEFSHELL_INDEX to one of 218 * DEFSHELL_INDEX_SH, DEFSHELL_INDEX_KSH, or DEFSHELL_INDEX_CSH, to 219 * select one of the prefedined shells as the default shell. 220 * 221 * Alternatively, the build environment may set DEFSHELL_CUSTOM to the 222 * name or the full path of a sh-compatible shell, which will be used as 223 * the default shell. 224 * 225 * ".SHELL" lines in Makefiles can choose the default shell from the 226 # set defined here, or add additional shells. 227 */ 228 229 #ifdef DEFSHELL_CUSTOM 230 #define DEFSHELL_INDEX_CUSTOM 0 231 #define DEFSHELL_INDEX_SH 1 232 #define DEFSHELL_INDEX_KSH 2 233 #define DEFSHELL_INDEX_CSH 3 234 #else /* !DEFSHELL_CUSTOM */ 235 #define DEFSHELL_INDEX_SH 0 236 #define DEFSHELL_INDEX_KSH 1 237 #define DEFSHELL_INDEX_CSH 2 238 #endif /* !DEFSHELL_CUSTOM */ 239 240 #ifndef DEFSHELL_INDEX 241 #define DEFSHELL_INDEX 0 /* DEFSHELL_INDEX_CUSTOM or DEFSHELL_INDEX_SH */ 242 #endif /* !DEFSHELL_INDEX */ 243 244 static Shell shells[] = { 245 #ifdef DEFSHELL_CUSTOM 246 /* 247 * An sh-compatible shell with a non-standard name. 248 * 249 * Keep this in sync with the "sh" description below, but avoid 250 * non-portable features that might not be supplied by all 251 * sh-compatible shells. 252 */ 253 { 254 DEFSHELL_CUSTOM, 255 FALSE, "", "", "", 0, 256 FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#', 257 "", 258 "", 259 }, 260 #endif /* DEFSHELL_CUSTOM */ 261 /* 262 * SH description. Echo control is also possible and, under 263 * sun UNIX anyway, one can even control error checking. 264 */ 265 { 266 "sh", 267 FALSE, "", "", "", 0, 268 FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#', 269 #if defined(MAKE_NATIVE) && defined(__NetBSD__) 270 "q", 271 #else 272 "", 273 #endif 274 "", 275 }, 276 /* 277 * KSH description. 278 */ 279 { 280 "ksh", 281 TRUE, "set +v", "set -v", "set +v", 6, 282 FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#', 283 "v", 284 "", 285 }, 286 /* 287 * CSH description. The csh can do echo control by playing 288 * with the setting of the 'echo' shell variable. Sadly, 289 * however, it is unable to do error control nicely. 290 */ 291 { 292 "csh", 293 TRUE, "unset verbose", "set verbose", "unset verbose", 10, 294 FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"\n", "", "'\\\n'", '#', 295 "v", "e", 296 }, 297 /* 298 * UNKNOWN. 299 */ 300 { 301 NULL, 302 FALSE, NULL, NULL, NULL, 0, 303 FALSE, NULL, NULL, NULL, NULL, 0, 304 NULL, NULL, 305 } 306 }; 307 static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to 308 * which we pass all 309 * commands in the Makefile. 310 * It is set by the 311 * Job_ParseShell function */ 312 const char *shellPath = NULL, /* full pathname of 313 * executable image */ 314 *shellName = NULL; /* last component of shell */ 315 static const char *shellArgv = NULL; /* Custom shell args */ 316 317 318 STATIC Job *job_table; /* The structures that describe them */ 319 STATIC Job *job_table_end; /* job_table + maxJobs */ 320 static int wantToken; /* we want a token */ 321 static int lurking_children = 0; 322 static int make_suspended = 0; /* non-zero if we've seen a SIGTSTP (etc) */ 323 324 /* 325 * Set of descriptors of pipes connected to 326 * the output channels of children 327 */ 328 static struct pollfd *fds = NULL; 329 static Job **jobfds = NULL; 330 static int nfds = 0; 331 static void watchfd(Job *); 332 static void clearfd(Job *); 333 static int readyfd(Job *); 334 335 STATIC GNode *lastNode; /* The node for which output was most recently 336 * produced. */ 337 static char *targPrefix = NULL; /* What we print at the start of TARG_FMT */ 338 static Job tokenWaitJob; /* token wait pseudo-job */ 339 340 static Job childExitJob; /* child exit pseudo-job */ 341 #define CHILD_EXIT "." 342 #define DO_JOB_RESUME "R" 343 344 #define TARG_FMT "%s %s ---\n" /* Default format */ 345 #define MESSAGE(fp, gn) \ 346 if (maxJobs != 1) \ 347 (void)fprintf(fp, TARG_FMT, targPrefix, gn->name) 348 349 static sigset_t caught_signals; /* Set of signals we handle */ 350 #if defined(SYSV) 351 #define KILLPG(pid, sig) kill(-(pid), (sig)) 352 #else 353 #define KILLPG(pid, sig) killpg((pid), (sig)) 354 #endif 355 356 static void JobChildSig(int); 357 static void JobContinueSig(int); 358 static Job *JobFindPid(int, int, Boolean); 359 static int JobPrintCommand(void *, void *); 360 static int JobSaveCommand(void *, void *); 361 static void JobClose(Job *); 362 static void JobExec(Job *, char **); 363 static void JobMakeArgv(Job *, char **); 364 static int JobStart(GNode *, int); 365 static char *JobOutput(Job *, char *, char *, int); 366 static void JobDoOutput(Job *, Boolean); 367 static Shell *JobMatchShell(const char *); 368 static void JobInterrupt(int, int) MAKE_ATTR_DEAD; 369 static void JobRestartJobs(void); 370 static void JobTokenAdd(void); 371 static void JobSigLock(sigset_t *); 372 static void JobSigUnlock(sigset_t *); 373 static void JobSigReset(void); 374 375 const char *malloc_options="A"; 376 377 static void 378 job_table_dump(const char *where) 379 { 380 Job *job; 381 382 fprintf(debug_file, "job table @ %s\n", where); 383 for (job = job_table; job < job_table_end; job++) { 384 fprintf(debug_file, "job %d, status %d, flags %d, pid %d\n", 385 (int)(job - job_table), job->job_state, job->flags, job->pid); 386 } 387 } 388 389 /* 390 * JobSigLock/JobSigUnlock 391 * 392 * Signal lock routines to get exclusive access. Currently used to 393 * protect `jobs' and `stoppedJobs' list manipulations. 394 */ 395 static void JobSigLock(sigset_t *omaskp) 396 { 397 if (sigprocmask(SIG_BLOCK, &caught_signals, omaskp) != 0) { 398 Punt("JobSigLock: sigprocmask: %s", strerror(errno)); 399 sigemptyset(omaskp); 400 } 401 } 402 403 static void JobSigUnlock(sigset_t *omaskp) 404 { 405 (void)sigprocmask(SIG_SETMASK, omaskp, NULL); 406 } 407 408 static void 409 JobCreatePipe(Job *job, int minfd) 410 { 411 int i, fd; 412 413 if (pipe(job->jobPipe) == -1) 414 Punt("Cannot create pipe: %s", strerror(errno)); 415 416 /* Set close-on-exec flag for both */ 417 (void)fcntl(job->jobPipe[0], F_SETFD, 1); 418 (void)fcntl(job->jobPipe[1], F_SETFD, 1); 419 420 /* 421 * We mark the input side of the pipe non-blocking; we poll(2) the 422 * pipe when we're waiting for a job token, but we might lose the 423 * race for the token when a new one becomes available, so the read 424 * from the pipe should not block. 425 */ 426 fcntl(job->jobPipe[0], F_SETFL, 427 fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK); 428 429 for (i = 0; i < 2; i++) { 430 /* Avoid using low numbered fds */ 431 fd = fcntl(job->jobPipe[i], F_DUPFD, minfd); 432 if (fd != -1) { 433 close(job->jobPipe[i]); 434 job->jobPipe[i] = fd; 435 } 436 } 437 } 438 439 /*- 440 *----------------------------------------------------------------------- 441 * JobCondPassSig -- 442 * Pass a signal to a job 443 * 444 * Input: 445 * signop Signal to send it 446 * 447 * Side Effects: 448 * None, except the job may bite it. 449 * 450 *----------------------------------------------------------------------- 451 */ 452 static void 453 JobCondPassSig(int signo) 454 { 455 Job *job; 456 457 if (DEBUG(JOB)) { 458 (void)fprintf(debug_file, "JobCondPassSig(%d) called.\n", signo); 459 } 460 461 for (job = job_table; job < job_table_end; job++) { 462 if (job->job_state != JOB_ST_RUNNING) 463 continue; 464 if (DEBUG(JOB)) { 465 (void)fprintf(debug_file, 466 "JobCondPassSig passing signal %d to child %d.\n", 467 signo, job->pid); 468 } 469 KILLPG(job->pid, signo); 470 } 471 } 472 473 /*- 474 *----------------------------------------------------------------------- 475 * JobChldSig -- 476 * SIGCHLD handler. 477 * 478 * Input: 479 * signo The signal number we've received 480 * 481 * Results: 482 * None. 483 * 484 * Side Effects: 485 * Sends a token on the child exit pipe to wake us up from 486 * select()/poll(). 487 * 488 *----------------------------------------------------------------------- 489 */ 490 static void 491 JobChildSig(int signo MAKE_ATTR_UNUSED) 492 { 493 while (write(childExitJob.outPipe, CHILD_EXIT, 1) == -1 && errno == EAGAIN) 494 continue; 495 } 496 497 498 /*- 499 *----------------------------------------------------------------------- 500 * JobContinueSig -- 501 * Resume all stopped jobs. 502 * 503 * Input: 504 * signo The signal number we've received 505 * 506 * Results: 507 * None. 508 * 509 * Side Effects: 510 * Jobs start running again. 511 * 512 *----------------------------------------------------------------------- 513 */ 514 static void 515 JobContinueSig(int signo MAKE_ATTR_UNUSED) 516 { 517 /* 518 * Defer sending to SIGCONT to our stopped children until we return 519 * from the signal handler. 520 */ 521 while (write(childExitJob.outPipe, DO_JOB_RESUME, 1) == -1 && 522 errno == EAGAIN) 523 continue; 524 } 525 526 /*- 527 *----------------------------------------------------------------------- 528 * JobPassSig -- 529 * Pass a signal on to all jobs, then resend to ourselves. 530 * 531 * Input: 532 * signo The signal number we've received 533 * 534 * Results: 535 * None. 536 * 537 * Side Effects: 538 * We die by the same signal. 539 * 540 *----------------------------------------------------------------------- 541 */ 542 MAKE_ATTR_DEAD static void 543 JobPassSig_int(int signo) 544 { 545 /* Run .INTERRUPT target then exit */ 546 JobInterrupt(TRUE, signo); 547 } 548 549 MAKE_ATTR_DEAD static void 550 JobPassSig_term(int signo) 551 { 552 /* Dont run .INTERRUPT target then exit */ 553 JobInterrupt(FALSE, signo); 554 } 555 556 static void 557 JobPassSig_suspend(int signo) 558 { 559 sigset_t nmask, omask; 560 struct sigaction act; 561 562 /* Suppress job started/continued messages */ 563 make_suspended = 1; 564 565 /* Pass the signal onto every job */ 566 JobCondPassSig(signo); 567 568 /* 569 * Send ourselves the signal now we've given the message to everyone else. 570 * Note we block everything else possible while we're getting the signal. 571 * This ensures that all our jobs get continued when we wake up before 572 * we take any other signal. 573 */ 574 sigfillset(&nmask); 575 sigdelset(&nmask, signo); 576 (void)sigprocmask(SIG_SETMASK, &nmask, &omask); 577 578 act.sa_handler = SIG_DFL; 579 sigemptyset(&act.sa_mask); 580 act.sa_flags = 0; 581 (void)sigaction(signo, &act, NULL); 582 583 if (DEBUG(JOB)) { 584 (void)fprintf(debug_file, 585 "JobPassSig passing signal %d to self.\n", signo); 586 } 587 588 (void)kill(getpid(), signo); 589 590 /* 591 * We've been continued. 592 * 593 * A whole host of signals continue to happen! 594 * SIGCHLD for any processes that actually suspended themselves. 595 * SIGCHLD for any processes that exited while we were alseep. 596 * The SIGCONT that actually caused us to wakeup. 597 * 598 * Since we defer passing the SIGCONT on to our children until 599 * the main processing loop, we can be sure that all the SIGCHLD 600 * events will have happened by then - and that the waitpid() will 601 * collect the child 'suspended' events. 602 * For correct sequencing we just need to ensure we process the 603 * waitpid() before passign on the SIGCONT. 604 * 605 * In any case nothing else is needed here. 606 */ 607 608 /* Restore handler and signal mask */ 609 act.sa_handler = JobPassSig_suspend; 610 (void)sigaction(signo, &act, NULL); 611 (void)sigprocmask(SIG_SETMASK, &omask, NULL); 612 } 613 614 /*- 615 *----------------------------------------------------------------------- 616 * JobFindPid -- 617 * Compare the pid of the job with the given pid and return 0 if they 618 * are equal. This function is called from Job_CatchChildren 619 * to find the job descriptor of the finished job. 620 * 621 * Input: 622 * job job to examine 623 * pid process id desired 624 * 625 * Results: 626 * Job with matching pid 627 * 628 * Side Effects: 629 * None 630 *----------------------------------------------------------------------- 631 */ 632 static Job * 633 JobFindPid(int pid, int status, Boolean isJobs) 634 { 635 Job *job; 636 637 for (job = job_table; job < job_table_end; job++) { 638 if ((job->job_state == status) && job->pid == pid) 639 return job; 640 } 641 if (DEBUG(JOB) && isJobs) 642 job_table_dump("no pid"); 643 return NULL; 644 } 645 646 /*- 647 *----------------------------------------------------------------------- 648 * JobPrintCommand -- 649 * Put out another command for the given job. If the command starts 650 * with an @ or a - we process it specially. In the former case, 651 * so long as the -s and -n flags weren't given to make, we stick 652 * a shell-specific echoOff command in the script. In the latter, 653 * we ignore errors for the entire job, unless the shell has error 654 * control. 655 * If the command is just "..." we take all future commands for this 656 * job to be commands to be executed once the entire graph has been 657 * made and return non-zero to signal that the end of the commands 658 * was reached. These commands are later attached to the postCommands 659 * node and executed by Job_End when all things are done. 660 * This function is called from JobStart via Lst_ForEach. 661 * 662 * Input: 663 * cmdp command string to print 664 * jobp job for which to print it 665 * 666 * Results: 667 * Always 0, unless the command was "..." 668 * 669 * Side Effects: 670 * If the command begins with a '-' and the shell has no error control, 671 * the JOB_IGNERR flag is set in the job descriptor. 672 * If the command is "..." and we're not ignoring such things, 673 * tailCmds is set to the successor node of the cmd. 674 * numCommands is incremented if the command is actually printed. 675 *----------------------------------------------------------------------- 676 */ 677 static int 678 JobPrintCommand(void *cmdp, void *jobp) 679 { 680 Boolean noSpecials; /* true if we shouldn't worry about 681 * inserting special commands into 682 * the input stream. */ 683 Boolean shutUp = FALSE; /* true if we put a no echo command 684 * into the command file */ 685 Boolean errOff = FALSE; /* true if we turned error checking 686 * off before printing the command 687 * and need to turn it back on */ 688 const char *cmdTemplate; /* Template to use when printing the 689 * command */ 690 char *cmdStart; /* Start of expanded command */ 691 char *escCmd = NULL; /* Command with quotes/backticks escaped */ 692 char *cmd = (char *)cmdp; 693 Job *job = (Job *)jobp; 694 int i, j; 695 696 noSpecials = NoExecute(job->node); 697 698 if (strcmp(cmd, "...") == 0) { 699 job->node->type |= OP_SAVE_CMDS; 700 if ((job->flags & JOB_IGNDOTS) == 0) { 701 job->tailCmds = Lst_Succ(Lst_Member(job->node->commands, 702 cmd)); 703 return 1; 704 } 705 return 0; 706 } 707 708 #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ 709 (void)fprintf(debug_file, fmt, arg); \ 710 } \ 711 (void)fprintf(job->cmdFILE, fmt, arg); \ 712 (void)fflush(job->cmdFILE); 713 714 numCommands += 1; 715 716 cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE); 717 718 cmdTemplate = "%s\n"; 719 720 /* 721 * Check for leading @' and -'s to control echoing and error checking. 722 */ 723 while (*cmd == '@' || *cmd == '-' || (*cmd == '+')) { 724 switch (*cmd) { 725 case '@': 726 shutUp = DEBUG(LOUD) ? FALSE : TRUE; 727 break; 728 case '-': 729 job->flags |= JOB_IGNERR; 730 errOff = TRUE; 731 break; 732 case '+': 733 if (noSpecials) { 734 /* 735 * We're not actually executing anything... 736 * but this one needs to be - use compat mode just for it. 737 */ 738 CompatRunCommand(cmdp, job->node); 739 return 0; 740 } 741 break; 742 } 743 cmd++; 744 } 745 746 while (isspace((unsigned char) *cmd)) 747 cmd++; 748 749 /* 750 * If the shell doesn't have error control the alternate echo'ing will 751 * be done (to avoid showing additional error checking code) 752 * and this will need the characters '$ ` \ "' escaped 753 */ 754 755 if (!commandShell->hasErrCtl) { 756 /* Worst that could happen is every char needs escaping. */ 757 escCmd = bmake_malloc((strlen(cmd) * 2) + 1); 758 for (i = 0, j= 0; cmd[i] != '\0'; i++, j++) { 759 if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' || 760 cmd[i] == '"') 761 escCmd[j++] = '\\'; 762 escCmd[j] = cmd[i]; 763 } 764 escCmd[j] = 0; 765 } 766 767 if (shutUp) { 768 if (!(job->flags & JOB_SILENT) && !noSpecials && 769 commandShell->hasEchoCtl) { 770 DBPRINTF("%s\n", commandShell->echoOff); 771 } else { 772 if (commandShell->hasErrCtl) 773 shutUp = FALSE; 774 } 775 } 776 777 if (errOff) { 778 if (!noSpecials) { 779 if (commandShell->hasErrCtl) { 780 /* 781 * we don't want the error-control commands showing 782 * up either, so we turn off echoing while executing 783 * them. We could put another field in the shell 784 * structure to tell JobDoOutput to look for this 785 * string too, but why make it any more complex than 786 * it already is? 787 */ 788 if (!(job->flags & JOB_SILENT) && !shutUp && 789 commandShell->hasEchoCtl) { 790 DBPRINTF("%s\n", commandShell->echoOff); 791 DBPRINTF("%s\n", commandShell->ignErr); 792 DBPRINTF("%s\n", commandShell->echoOn); 793 } else { 794 DBPRINTF("%s\n", commandShell->ignErr); 795 } 796 } else if (commandShell->ignErr && 797 (*commandShell->ignErr != '\0')) 798 { 799 /* 800 * The shell has no error control, so we need to be 801 * weird to get it to ignore any errors from the command. 802 * If echoing is turned on, we turn it off and use the 803 * errCheck template to echo the command. Leave echoing 804 * off so the user doesn't see the weirdness we go through 805 * to ignore errors. Set cmdTemplate to use the weirdness 806 * instead of the simple "%s\n" template. 807 */ 808 if (!(job->flags & JOB_SILENT) && !shutUp) { 809 if (commandShell->hasEchoCtl) { 810 DBPRINTF("%s\n", commandShell->echoOff); 811 } 812 DBPRINTF(commandShell->errCheck, escCmd); 813 shutUp = TRUE; 814 } else { 815 if (!shutUp) { 816 DBPRINTF(commandShell->errCheck, escCmd); 817 } 818 } 819 cmdTemplate = commandShell->ignErr; 820 /* 821 * The error ignoration (hee hee) is already taken care 822 * of by the ignErr template, so pretend error checking 823 * is still on. 824 */ 825 errOff = FALSE; 826 } else { 827 errOff = FALSE; 828 } 829 } else { 830 errOff = FALSE; 831 } 832 } else { 833 834 /* 835 * If errors are being checked and the shell doesn't have error control 836 * but does supply an errOut template, then setup commands to run 837 * through it. 838 */ 839 840 if (!commandShell->hasErrCtl && commandShell->errOut && 841 (*commandShell->errOut != '\0')) { 842 if (!(job->flags & JOB_SILENT) && !shutUp) { 843 if (commandShell->hasEchoCtl) { 844 DBPRINTF("%s\n", commandShell->echoOff); 845 } 846 DBPRINTF(commandShell->errCheck, escCmd); 847 shutUp = TRUE; 848 } 849 /* If it's a comment line or blank, treat as an ignored error */ 850 if ((escCmd[0] == commandShell->commentChar) || 851 (escCmd[0] == 0)) 852 cmdTemplate = commandShell->ignErr; 853 else 854 cmdTemplate = commandShell->errOut; 855 errOff = FALSE; 856 } 857 } 858 859 if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 && 860 (job->flags & JOB_TRACED) == 0) { 861 DBPRINTF("set -%s\n", "x"); 862 job->flags |= JOB_TRACED; 863 } 864 865 DBPRINTF(cmdTemplate, cmd); 866 free(cmdStart); 867 if (escCmd) 868 free(escCmd); 869 if (errOff) { 870 /* 871 * If echoing is already off, there's no point in issuing the 872 * echoOff command. Otherwise we issue it and pretend it was on 873 * for the whole command... 874 */ 875 if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){ 876 DBPRINTF("%s\n", commandShell->echoOff); 877 shutUp = TRUE; 878 } 879 DBPRINTF("%s\n", commandShell->errCheck); 880 } 881 if (shutUp && commandShell->hasEchoCtl) { 882 DBPRINTF("%s\n", commandShell->echoOn); 883 } 884 return 0; 885 } 886 887 /*- 888 *----------------------------------------------------------------------- 889 * JobSaveCommand -- 890 * Save a command to be executed when everything else is done. 891 * Callback function for JobFinish... 892 * 893 * Results: 894 * Always returns 0 895 * 896 * Side Effects: 897 * The command is tacked onto the end of postCommands's commands list. 898 * 899 *----------------------------------------------------------------------- 900 */ 901 static int 902 JobSaveCommand(void *cmd, void *gn) 903 { 904 cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE); 905 (void)Lst_AtEnd(postCommands->commands, cmd); 906 return(0); 907 } 908 909 910 /*- 911 *----------------------------------------------------------------------- 912 * JobClose -- 913 * Called to close both input and output pipes when a job is finished. 914 * 915 * Results: 916 * Nada 917 * 918 * Side Effects: 919 * The file descriptors associated with the job are closed. 920 * 921 *----------------------------------------------------------------------- 922 */ 923 static void 924 JobClose(Job *job) 925 { 926 clearfd(job); 927 (void)close(job->outPipe); 928 job->outPipe = -1; 929 930 JobDoOutput(job, TRUE); 931 (void)close(job->inPipe); 932 job->inPipe = -1; 933 } 934 935 /*- 936 *----------------------------------------------------------------------- 937 * JobFinish -- 938 * Do final processing for the given job including updating 939 * parents and starting new jobs as available/necessary. Note 940 * that we pay no attention to the JOB_IGNERR flag here. 941 * This is because when we're called because of a noexecute flag 942 * or something, jstat.w_status is 0 and when called from 943 * Job_CatchChildren, the status is zeroed if it s/b ignored. 944 * 945 * Input: 946 * job job to finish 947 * status sub-why job went away 948 * 949 * Results: 950 * None 951 * 952 * Side Effects: 953 * Final commands for the job are placed on postCommands. 954 * 955 * If we got an error and are aborting (aborting == ABORT_ERROR) and 956 * the job list is now empty, we are done for the day. 957 * If we recognized an error (errors !=0), we set the aborting flag 958 * to ABORT_ERROR so no more jobs will be started. 959 *----------------------------------------------------------------------- 960 */ 961 /*ARGSUSED*/ 962 static void 963 JobFinish (Job *job, WAIT_T status) 964 { 965 Boolean done, return_job_token; 966 967 if (DEBUG(JOB)) { 968 fprintf(debug_file, "Jobfinish: %d [%s], status %d\n", 969 job->pid, job->node->name, status); 970 } 971 972 if ((WIFEXITED(status) && 973 (((WEXITSTATUS(status) != 0) && !(job->flags & JOB_IGNERR)))) || 974 WIFSIGNALED(status)) 975 { 976 /* 977 * If it exited non-zero and either we're doing things our 978 * way or we're not ignoring errors, the job is finished. 979 * Similarly, if the shell died because of a signal 980 * the job is also finished. In these 981 * cases, finish out the job's output before printing the exit 982 * status... 983 */ 984 JobClose(job); 985 if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 986 (void)fclose(job->cmdFILE); 987 job->cmdFILE = NULL; 988 } 989 done = TRUE; 990 } else if (WIFEXITED(status)) { 991 /* 992 * Deal with ignored errors in -B mode. We need to print a message 993 * telling of the ignored error as well as setting status.w_status 994 * to 0 so the next command gets run. To do this, we set done to be 995 * TRUE if in -B mode and the job exited non-zero. 996 */ 997 done = WEXITSTATUS(status) != 0; 998 /* 999 * Old comment said: "Note we don't 1000 * want to close down any of the streams until we know we're at the 1001 * end." 1002 * But we do. Otherwise when are we going to print the rest of the 1003 * stuff? 1004 */ 1005 JobClose(job); 1006 } else { 1007 /* 1008 * No need to close things down or anything. 1009 */ 1010 done = FALSE; 1011 } 1012 1013 if (done) { 1014 if (WIFEXITED(status)) { 1015 if (DEBUG(JOB)) { 1016 (void)fprintf(debug_file, "Process %d [%s] exited.\n", 1017 job->pid, job->node->name); 1018 } 1019 if (WEXITSTATUS(status) != 0) { 1020 if (job->node != lastNode) { 1021 MESSAGE(stdout, job->node); 1022 lastNode = job->node; 1023 } 1024 #ifdef USE_META 1025 if (useMeta) { 1026 meta_job_error(job, job->node, job->flags, WEXITSTATUS(status)); 1027 } 1028 #endif 1029 (void)printf("*** [%s] Error code %d%s\n", 1030 job->node->name, 1031 WEXITSTATUS(status), 1032 (job->flags & JOB_IGNERR) ? " (ignored)" : ""); 1033 if (job->flags & JOB_IGNERR) { 1034 WAIT_STATUS(status) = 0; 1035 } else { 1036 PrintOnError(job->node, NULL); 1037 } 1038 } else if (DEBUG(JOB)) { 1039 if (job->node != lastNode) { 1040 MESSAGE(stdout, job->node); 1041 lastNode = job->node; 1042 } 1043 (void)printf("*** [%s] Completed successfully\n", 1044 job->node->name); 1045 } 1046 } else { 1047 if (job->node != lastNode) { 1048 MESSAGE(stdout, job->node); 1049 lastNode = job->node; 1050 } 1051 (void)printf("*** [%s] Signal %d\n", 1052 job->node->name, WTERMSIG(status)); 1053 } 1054 (void)fflush(stdout); 1055 } 1056 1057 #ifdef USE_META 1058 if (useMeta) { 1059 meta_job_finish(job); 1060 } 1061 #endif 1062 1063 return_job_token = FALSE; 1064 1065 Trace_Log(JOBEND, job); 1066 if (!(job->flags & JOB_SPECIAL)) { 1067 if ((WAIT_STATUS(status) != 0) || 1068 (aborting == ABORT_ERROR) || 1069 (aborting == ABORT_INTERRUPT)) 1070 return_job_token = TRUE; 1071 } 1072 1073 if ((aborting != ABORT_ERROR) && (aborting != ABORT_INTERRUPT) && 1074 (WAIT_STATUS(status) == 0)) { 1075 /* 1076 * As long as we aren't aborting and the job didn't return a non-zero 1077 * status that we shouldn't ignore, we call Make_Update to update 1078 * the parents. In addition, any saved commands for the node are placed 1079 * on the .END target. 1080 */ 1081 if (job->tailCmds != NULL) { 1082 Lst_ForEachFrom(job->node->commands, job->tailCmds, 1083 JobSaveCommand, 1084 job->node); 1085 } 1086 job->node->made = MADE; 1087 if (!(job->flags & JOB_SPECIAL)) 1088 return_job_token = TRUE; 1089 Make_Update(job->node); 1090 job->job_state = JOB_ST_FREE; 1091 } else if (WAIT_STATUS(status)) { 1092 errors += 1; 1093 job->job_state = JOB_ST_FREE; 1094 } 1095 1096 /* 1097 * Set aborting if any error. 1098 */ 1099 if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) { 1100 /* 1101 * If we found any errors in this batch of children and the -k flag 1102 * wasn't given, we set the aborting flag so no more jobs get 1103 * started. 1104 */ 1105 aborting = ABORT_ERROR; 1106 } 1107 1108 if (return_job_token) 1109 Job_TokenReturn(); 1110 1111 if (aborting == ABORT_ERROR && jobTokensRunning == 0) { 1112 /* 1113 * If we are aborting and the job table is now empty, we finish. 1114 */ 1115 Finish(errors); 1116 } 1117 } 1118 1119 /*- 1120 *----------------------------------------------------------------------- 1121 * Job_Touch -- 1122 * Touch the given target. Called by JobStart when the -t flag was 1123 * given 1124 * 1125 * Input: 1126 * gn the node of the file to touch 1127 * silent TRUE if should not print message 1128 * 1129 * Results: 1130 * None 1131 * 1132 * Side Effects: 1133 * The data modification of the file is changed. In addition, if the 1134 * file did not exist, it is created. 1135 *----------------------------------------------------------------------- 1136 */ 1137 void 1138 Job_Touch(GNode *gn, Boolean silent) 1139 { 1140 int streamID; /* ID of stream opened to do the touch */ 1141 struct utimbuf times; /* Times for utime() call */ 1142 1143 if (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC|OP_OPTIONAL| 1144 OP_SPECIAL|OP_PHONY)) { 1145 /* 1146 * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets 1147 * and, as such, shouldn't really be created. 1148 */ 1149 return; 1150 } 1151 1152 if (!silent || NoExecute(gn)) { 1153 (void)fprintf(stdout, "touch %s\n", gn->name); 1154 (void)fflush(stdout); 1155 } 1156 1157 if (NoExecute(gn)) { 1158 return; 1159 } 1160 1161 if (gn->type & OP_ARCHV) { 1162 Arch_Touch(gn); 1163 } else if (gn->type & OP_LIB) { 1164 Arch_TouchLib(gn); 1165 } else { 1166 char *file = gn->path ? gn->path : gn->name; 1167 1168 times.actime = times.modtime = now; 1169 if (utime(file, ×) < 0){ 1170 streamID = open(file, O_RDWR | O_CREAT, 0666); 1171 1172 if (streamID >= 0) { 1173 char c; 1174 1175 /* 1176 * Read and write a byte to the file to change the 1177 * modification time, then close the file. 1178 */ 1179 if (read(streamID, &c, 1) == 1) { 1180 (void)lseek(streamID, (off_t)0, SEEK_SET); 1181 while (write(streamID, &c, 1) == -1 && errno == EAGAIN) 1182 continue; 1183 } 1184 1185 (void)close(streamID); 1186 } else { 1187 (void)fprintf(stdout, "*** couldn't touch %s: %s", 1188 file, strerror(errno)); 1189 (void)fflush(stdout); 1190 } 1191 } 1192 } 1193 } 1194 1195 /*- 1196 *----------------------------------------------------------------------- 1197 * Job_CheckCommands -- 1198 * Make sure the given node has all the commands it needs. 1199 * 1200 * Input: 1201 * gn The target whose commands need verifying 1202 * abortProc Function to abort with message 1203 * 1204 * Results: 1205 * TRUE if the commands list is/was ok. 1206 * 1207 * Side Effects: 1208 * The node will have commands from the .DEFAULT rule added to it 1209 * if it needs them. 1210 *----------------------------------------------------------------------- 1211 */ 1212 Boolean 1213 Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) 1214 { 1215 if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) && 1216 ((gn->type & OP_LIB) == 0 || Lst_IsEmpty(gn->children))) { 1217 /* 1218 * No commands. Look for .DEFAULT rule from which we might infer 1219 * commands 1220 */ 1221 if ((DEFAULT != NULL) && !Lst_IsEmpty(DEFAULT->commands) && 1222 (gn->type & OP_SPECIAL) == 0) { 1223 char *p1; 1224 /* 1225 * Make only looks for a .DEFAULT if the node was never the 1226 * target of an operator, so that's what we do too. If 1227 * a .DEFAULT was given, we substitute its commands for gn's 1228 * commands and set the IMPSRC variable to be the target's name 1229 * The DEFAULT node acts like a transformation rule, in that 1230 * gn also inherits any attributes or sources attached to 1231 * .DEFAULT itself. 1232 */ 1233 Make_HandleUse(DEFAULT, gn); 1234 Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn, 0); 1235 if (p1) 1236 free(p1); 1237 } else if (Dir_MTime(gn, 0) == 0 && (gn->type & OP_SPECIAL) == 0) { 1238 /* 1239 * The node wasn't the target of an operator we have no .DEFAULT 1240 * rule to go on and the target doesn't already exist. There's 1241 * nothing more we can do for this branch. If the -k flag wasn't 1242 * given, we stop in our tracks, otherwise we just don't update 1243 * this node's parents so they never get examined. 1244 */ 1245 static const char msg[] = ": don't know how to make"; 1246 1247 if (gn->flags & FROM_DEPEND) { 1248 fprintf(stdout, "%s: ignoring stale %s for %s\n", 1249 progname, makeDependfile, gn->name); 1250 return TRUE; 1251 } 1252 1253 if (gn->type & OP_OPTIONAL) { 1254 (void)fprintf(stdout, "%s%s %s (ignored)\n", progname, 1255 msg, gn->name); 1256 (void)fflush(stdout); 1257 } else if (keepgoing) { 1258 (void)fprintf(stdout, "%s%s %s (continuing)\n", progname, 1259 msg, gn->name); 1260 (void)fflush(stdout); 1261 return FALSE; 1262 } else { 1263 (*abortProc)("%s%s %s. Stop", progname, msg, gn->name); 1264 return FALSE; 1265 } 1266 } 1267 } 1268 return TRUE; 1269 } 1270 1271 /*- 1272 *----------------------------------------------------------------------- 1273 * JobExec -- 1274 * Execute the shell for the given job. Called from JobStart 1275 * 1276 * Input: 1277 * job Job to execute 1278 * 1279 * Results: 1280 * None. 1281 * 1282 * Side Effects: 1283 * A shell is executed, outputs is altered and the Job structure added 1284 * to the job table. 1285 * 1286 *----------------------------------------------------------------------- 1287 */ 1288 static void 1289 JobExec(Job *job, char **argv) 1290 { 1291 int cpid; /* ID of new child */ 1292 sigset_t mask; 1293 1294 job->flags &= ~JOB_TRACED; 1295 1296 if (DEBUG(JOB)) { 1297 int i; 1298 1299 (void)fprintf(debug_file, "Running %s %sly\n", job->node->name, "local"); 1300 (void)fprintf(debug_file, "\tCommand: "); 1301 for (i = 0; argv[i] != NULL; i++) { 1302 (void)fprintf(debug_file, "%s ", argv[i]); 1303 } 1304 (void)fprintf(debug_file, "\n"); 1305 } 1306 1307 /* 1308 * Some jobs produce no output and it's disconcerting to have 1309 * no feedback of their running (since they produce no output, the 1310 * banner with their name in it never appears). This is an attempt to 1311 * provide that feedback, even if nothing follows it. 1312 */ 1313 if ((lastNode != job->node) && !(job->flags & JOB_SILENT)) { 1314 MESSAGE(stdout, job->node); 1315 lastNode = job->node; 1316 } 1317 1318 /* No interruptions until this job is on the `jobs' list */ 1319 JobSigLock(&mask); 1320 1321 /* Pre-emptively mark job running, pid still zero though */ 1322 job->job_state = JOB_ST_RUNNING; 1323 1324 cpid = vFork(); 1325 if (cpid == -1) 1326 Punt("Cannot vfork: %s", strerror(errno)); 1327 1328 if (cpid == 0) { 1329 /* Child */ 1330 sigset_t tmask; 1331 1332 #ifdef USE_META 1333 if (useMeta) { 1334 meta_job_child(job); 1335 } 1336 #endif 1337 /* 1338 * Reset all signal handlers; this is necessary because we also 1339 * need to unblock signals before we exec(2). 1340 */ 1341 JobSigReset(); 1342 1343 /* Now unblock signals */ 1344 sigemptyset(&tmask); 1345 JobSigUnlock(&tmask); 1346 1347 /* 1348 * Must duplicate the input stream down to the child's input and 1349 * reset it to the beginning (again). Since the stream was marked 1350 * close-on-exec, we must clear that bit in the new input. 1351 */ 1352 if (dup2(FILENO(job->cmdFILE), 0) == -1) { 1353 execError("dup2", "job->cmdFILE"); 1354 _exit(1); 1355 } 1356 (void)fcntl(0, F_SETFD, 0); 1357 (void)lseek(0, (off_t)0, SEEK_SET); 1358 1359 if (job->node->type & OP_MAKE) { 1360 /* 1361 * Pass job token pipe to submakes. 1362 */ 1363 fcntl(tokenWaitJob.inPipe, F_SETFD, 0); 1364 fcntl(tokenWaitJob.outPipe, F_SETFD, 0); 1365 } 1366 1367 /* 1368 * Set up the child's output to be routed through the pipe 1369 * we've created for it. 1370 */ 1371 if (dup2(job->outPipe, 1) == -1) { 1372 execError("dup2", "job->outPipe"); 1373 _exit(1); 1374 } 1375 /* 1376 * The output channels are marked close on exec. This bit was 1377 * duplicated by the dup2(on some systems), so we have to clear 1378 * it before routing the shell's error output to the same place as 1379 * its standard output. 1380 */ 1381 (void)fcntl(1, F_SETFD, 0); 1382 if (dup2(1, 2) == -1) { 1383 execError("dup2", "1, 2"); 1384 _exit(1); 1385 } 1386 1387 /* 1388 * We want to switch the child into a different process family so 1389 * we can kill it and all its descendants in one fell swoop, 1390 * by killing its process family, but not commit suicide. 1391 */ 1392 #if defined(HAVE_SETPGID) 1393 (void)setpgid(0, getpid()); 1394 #else 1395 #if defined(HAVE_SETSID) 1396 /* XXX: dsl - I'm sure this should be setpgrp()... */ 1397 (void)setsid(); 1398 #else 1399 (void)setpgrp(0, getpid()); 1400 #endif 1401 #endif 1402 1403 Var_ExportVars(); 1404 1405 (void)execv(shellPath, argv); 1406 execError("exec", shellPath); 1407 _exit(1); 1408 } 1409 1410 /* Parent, continuing after the child exec */ 1411 job->pid = cpid; 1412 1413 Trace_Log(JOBSTART, job); 1414 1415 /* 1416 * Set the current position in the buffer to the beginning 1417 * and mark another stream to watch in the outputs mask 1418 */ 1419 job->curPos = 0; 1420 1421 watchfd(job); 1422 1423 if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1424 (void)fclose(job->cmdFILE); 1425 job->cmdFILE = NULL; 1426 } 1427 1428 /* 1429 * Now the job is actually running, add it to the table. 1430 */ 1431 if (DEBUG(JOB)) { 1432 fprintf(debug_file, "JobExec(%s): pid %d added to jobs table\n", 1433 job->node->name, job->pid); 1434 job_table_dump("job started"); 1435 } 1436 JobSigUnlock(&mask); 1437 } 1438 1439 /*- 1440 *----------------------------------------------------------------------- 1441 * JobMakeArgv -- 1442 * Create the argv needed to execute the shell for a given job. 1443 * 1444 * 1445 * Results: 1446 * 1447 * Side Effects: 1448 * 1449 *----------------------------------------------------------------------- 1450 */ 1451 static void 1452 JobMakeArgv(Job *job, char **argv) 1453 { 1454 int argc; 1455 static char args[10]; /* For merged arguments */ 1456 1457 argv[0] = UNCONST(shellName); 1458 argc = 1; 1459 1460 if ((commandShell->exit && (*commandShell->exit != '-')) || 1461 (commandShell->echo && (*commandShell->echo != '-'))) 1462 { 1463 /* 1464 * At least one of the flags doesn't have a minus before it, so 1465 * merge them together. Have to do this because the *(&(@*#*&#$# 1466 * Bourne shell thinks its second argument is a file to source. 1467 * Grrrr. Note the ten-character limitation on the combined arguments. 1468 */ 1469 (void)snprintf(args, sizeof(args), "-%s%s", 1470 ((job->flags & JOB_IGNERR) ? "" : 1471 (commandShell->exit ? commandShell->exit : "")), 1472 ((job->flags & JOB_SILENT) ? "" : 1473 (commandShell->echo ? commandShell->echo : ""))); 1474 1475 if (args[1]) { 1476 argv[argc] = args; 1477 argc++; 1478 } 1479 } else { 1480 if (!(job->flags & JOB_IGNERR) && commandShell->exit) { 1481 argv[argc] = UNCONST(commandShell->exit); 1482 argc++; 1483 } 1484 if (!(job->flags & JOB_SILENT) && commandShell->echo) { 1485 argv[argc] = UNCONST(commandShell->echo); 1486 argc++; 1487 } 1488 } 1489 argv[argc] = NULL; 1490 } 1491 1492 /*- 1493 *----------------------------------------------------------------------- 1494 * JobStart -- 1495 * Start a target-creation process going for the target described 1496 * by the graph node gn. 1497 * 1498 * Input: 1499 * gn target to create 1500 * flags flags for the job to override normal ones. 1501 * e.g. JOB_SPECIAL or JOB_IGNDOTS 1502 * previous The previous Job structure for this node, if any. 1503 * 1504 * Results: 1505 * JOB_ERROR if there was an error in the commands, JOB_FINISHED 1506 * if there isn't actually anything left to do for the job and 1507 * JOB_RUNNING if the job has been started. 1508 * 1509 * Side Effects: 1510 * A new Job node is created and added to the list of running 1511 * jobs. PMake is forked and a child shell created. 1512 * 1513 * NB: I'm fairly sure that this code is never called with JOB_SPECIAL set 1514 * JOB_IGNDOTS is never set (dsl) 1515 * Also the return value is ignored by everyone. 1516 *----------------------------------------------------------------------- 1517 */ 1518 static int 1519 JobStart(GNode *gn, int flags) 1520 { 1521 Job *job; /* new job descriptor */ 1522 char *argv[10]; /* Argument vector to shell */ 1523 Boolean cmdsOK; /* true if the nodes commands were all right */ 1524 Boolean noExec; /* Set true if we decide not to run the job */ 1525 int tfd; /* File descriptor to the temp file */ 1526 1527 for (job = job_table; job < job_table_end; job++) { 1528 if (job->job_state == JOB_ST_FREE) 1529 break; 1530 } 1531 if (job >= job_table_end) 1532 Punt("JobStart no job slots vacant"); 1533 1534 memset(job, 0, sizeof *job); 1535 job->job_state = JOB_ST_SETUP; 1536 if (gn->type & OP_SPECIAL) 1537 flags |= JOB_SPECIAL; 1538 1539 job->node = gn; 1540 job->tailCmds = NULL; 1541 1542 /* 1543 * Set the initial value of the flags for this job based on the global 1544 * ones and the node's attributes... Any flags supplied by the caller 1545 * are also added to the field. 1546 */ 1547 job->flags = 0; 1548 if (Targ_Ignore(gn)) { 1549 job->flags |= JOB_IGNERR; 1550 } 1551 if (Targ_Silent(gn)) { 1552 job->flags |= JOB_SILENT; 1553 } 1554 job->flags |= flags; 1555 1556 /* 1557 * Check the commands now so any attributes from .DEFAULT have a chance 1558 * to migrate to the node 1559 */ 1560 cmdsOK = Job_CheckCommands(gn, Error); 1561 1562 job->inPollfd = NULL; 1563 /* 1564 * If the -n flag wasn't given, we open up OUR (not the child's) 1565 * temporary file to stuff commands in it. The thing is rd/wr so we don't 1566 * need to reopen it to feed it to the shell. If the -n flag *was* given, 1567 * we just set the file to be stdout. Cute, huh? 1568 */ 1569 if (((gn->type & OP_MAKE) && !(noRecursiveExecute)) || 1570 (!noExecute && !touchFlag)) { 1571 /* 1572 * tfile is the name of a file into which all shell commands are 1573 * put. It is removed before the child shell is executed, unless 1574 * DEBUG(SCRIPT) is set. 1575 */ 1576 char *tfile; 1577 sigset_t mask; 1578 /* 1579 * We're serious here, but if the commands were bogus, we're 1580 * also dead... 1581 */ 1582 if (!cmdsOK) { 1583 PrintOnError(gn, NULL); /* provide some clue */ 1584 DieHorribly(); 1585 } 1586 1587 JobSigLock(&mask); 1588 tfd = mkTempFile(TMPPAT, &tfile); 1589 if (!DEBUG(SCRIPT)) 1590 (void)eunlink(tfile); 1591 JobSigUnlock(&mask); 1592 1593 job->cmdFILE = fdopen(tfd, "w+"); 1594 if (job->cmdFILE == NULL) { 1595 Punt("Could not fdopen %s", tfile); 1596 } 1597 (void)fcntl(FILENO(job->cmdFILE), F_SETFD, 1); 1598 /* 1599 * Send the commands to the command file, flush all its buffers then 1600 * rewind and remove the thing. 1601 */ 1602 noExec = FALSE; 1603 1604 #ifdef USE_META 1605 if (useMeta) { 1606 meta_job_start(job, gn); 1607 if (Targ_Silent(gn)) { /* might have changed */ 1608 job->flags |= JOB_SILENT; 1609 } 1610 } 1611 #endif 1612 /* 1613 * We can do all the commands at once. hooray for sanity 1614 */ 1615 numCommands = 0; 1616 Lst_ForEach(gn->commands, JobPrintCommand, job); 1617 1618 /* 1619 * If we didn't print out any commands to the shell script, 1620 * there's not much point in executing the shell, is there? 1621 */ 1622 if (numCommands == 0) { 1623 noExec = TRUE; 1624 } 1625 1626 free(tfile); 1627 } else if (NoExecute(gn)) { 1628 /* 1629 * Not executing anything -- just print all the commands to stdout 1630 * in one fell swoop. This will still set up job->tailCmds correctly. 1631 */ 1632 if (lastNode != gn) { 1633 MESSAGE(stdout, gn); 1634 lastNode = gn; 1635 } 1636 job->cmdFILE = stdout; 1637 /* 1638 * Only print the commands if they're ok, but don't die if they're 1639 * not -- just let the user know they're bad and keep going. It 1640 * doesn't do any harm in this case and may do some good. 1641 */ 1642 if (cmdsOK) { 1643 Lst_ForEach(gn->commands, JobPrintCommand, job); 1644 } 1645 /* 1646 * Don't execute the shell, thank you. 1647 */ 1648 noExec = TRUE; 1649 } else { 1650 /* 1651 * Just touch the target and note that no shell should be executed. 1652 * Set cmdFILE to stdout to make life easier. Check the commands, too, 1653 * but don't die if they're no good -- it does no harm to keep working 1654 * up the graph. 1655 */ 1656 job->cmdFILE = stdout; 1657 Job_Touch(gn, job->flags&JOB_SILENT); 1658 noExec = TRUE; 1659 } 1660 /* Just in case it isn't already... */ 1661 (void)fflush(job->cmdFILE); 1662 1663 /* 1664 * If we're not supposed to execute a shell, don't. 1665 */ 1666 if (noExec) { 1667 if (!(job->flags & JOB_SPECIAL)) 1668 Job_TokenReturn(); 1669 /* 1670 * Unlink and close the command file if we opened one 1671 */ 1672 if (job->cmdFILE != stdout) { 1673 if (job->cmdFILE != NULL) { 1674 (void)fclose(job->cmdFILE); 1675 job->cmdFILE = NULL; 1676 } 1677 } 1678 1679 /* 1680 * We only want to work our way up the graph if we aren't here because 1681 * the commands for the job were no good. 1682 */ 1683 if (cmdsOK && aborting == 0) { 1684 if (job->tailCmds != NULL) { 1685 Lst_ForEachFrom(job->node->commands, job->tailCmds, 1686 JobSaveCommand, 1687 job->node); 1688 } 1689 job->node->made = MADE; 1690 Make_Update(job->node); 1691 } 1692 job->job_state = JOB_ST_FREE; 1693 return cmdsOK ? JOB_FINISHED : JOB_ERROR; 1694 } 1695 1696 /* 1697 * Set up the control arguments to the shell. This is based on the flags 1698 * set earlier for this job. 1699 */ 1700 JobMakeArgv(job, argv); 1701 1702 /* Create the pipe by which we'll get the shell's output. */ 1703 JobCreatePipe(job, 3); 1704 1705 JobExec(job, argv); 1706 return(JOB_RUNNING); 1707 } 1708 1709 static char * 1710 JobOutput(Job *job, char *cp, char *endp, int msg) 1711 { 1712 char *ecp; 1713 1714 if (commandShell->noPrint) { 1715 ecp = Str_FindSubstring(cp, commandShell->noPrint); 1716 while (ecp != NULL) { 1717 if (cp != ecp) { 1718 *ecp = '\0'; 1719 if (!beSilent && msg && job->node != lastNode) { 1720 MESSAGE(stdout, job->node); 1721 lastNode = job->node; 1722 } 1723 /* 1724 * The only way there wouldn't be a newline after 1725 * this line is if it were the last in the buffer. 1726 * however, since the non-printable comes after it, 1727 * there must be a newline, so we don't print one. 1728 */ 1729 (void)fprintf(stdout, "%s", cp); 1730 (void)fflush(stdout); 1731 } 1732 cp = ecp + commandShell->noPLen; 1733 if (cp != endp) { 1734 /* 1735 * Still more to print, look again after skipping 1736 * the whitespace following the non-printable 1737 * command.... 1738 */ 1739 cp++; 1740 while (*cp == ' ' || *cp == '\t' || *cp == '\n') { 1741 cp++; 1742 } 1743 ecp = Str_FindSubstring(cp, commandShell->noPrint); 1744 } else { 1745 return cp; 1746 } 1747 } 1748 } 1749 return cp; 1750 } 1751 1752 /*- 1753 *----------------------------------------------------------------------- 1754 * JobDoOutput -- 1755 * This function is called at different times depending on 1756 * whether the user has specified that output is to be collected 1757 * via pipes or temporary files. In the former case, we are called 1758 * whenever there is something to read on the pipe. We collect more 1759 * output from the given job and store it in the job's outBuf. If 1760 * this makes up a line, we print it tagged by the job's identifier, 1761 * as necessary. 1762 * If output has been collected in a temporary file, we open the 1763 * file and read it line by line, transfering it to our own 1764 * output channel until the file is empty. At which point we 1765 * remove the temporary file. 1766 * In both cases, however, we keep our figurative eye out for the 1767 * 'noPrint' line for the shell from which the output came. If 1768 * we recognize a line, we don't print it. If the command is not 1769 * alone on the line (the character after it is not \0 or \n), we 1770 * do print whatever follows it. 1771 * 1772 * Input: 1773 * job the job whose output needs printing 1774 * finish TRUE if this is the last time we'll be called 1775 * for this job 1776 * 1777 * Results: 1778 * None 1779 * 1780 * Side Effects: 1781 * curPos may be shifted as may the contents of outBuf. 1782 *----------------------------------------------------------------------- 1783 */ 1784 STATIC void 1785 JobDoOutput(Job *job, Boolean finish) 1786 { 1787 Boolean gotNL = FALSE; /* true if got a newline */ 1788 Boolean fbuf; /* true if our buffer filled up */ 1789 int nr; /* number of bytes read */ 1790 int i; /* auxiliary index into outBuf */ 1791 int max; /* limit for i (end of current data) */ 1792 int nRead; /* (Temporary) number of bytes read */ 1793 1794 /* 1795 * Read as many bytes as will fit in the buffer. 1796 */ 1797 end_loop: 1798 gotNL = FALSE; 1799 fbuf = FALSE; 1800 1801 nRead = read(job->inPipe, &job->outBuf[job->curPos], 1802 JOB_BUFSIZE - job->curPos); 1803 if (nRead < 0) { 1804 if (errno == EAGAIN) 1805 return; 1806 if (DEBUG(JOB)) { 1807 perror("JobDoOutput(piperead)"); 1808 } 1809 nr = 0; 1810 } else { 1811 nr = nRead; 1812 } 1813 1814 /* 1815 * If we hit the end-of-file (the job is dead), we must flush its 1816 * remaining output, so pretend we read a newline if there's any 1817 * output remaining in the buffer. 1818 * Also clear the 'finish' flag so we stop looping. 1819 */ 1820 if ((nr == 0) && (job->curPos != 0)) { 1821 job->outBuf[job->curPos] = '\n'; 1822 nr = 1; 1823 finish = FALSE; 1824 } else if (nr == 0) { 1825 finish = FALSE; 1826 } 1827 1828 /* 1829 * Look for the last newline in the bytes we just got. If there is 1830 * one, break out of the loop with 'i' as its index and gotNL set 1831 * TRUE. 1832 */ 1833 max = job->curPos + nr; 1834 for (i = job->curPos + nr - 1; i >= job->curPos; i--) { 1835 if (job->outBuf[i] == '\n') { 1836 gotNL = TRUE; 1837 break; 1838 } else if (job->outBuf[i] == '\0') { 1839 /* 1840 * Why? 1841 */ 1842 job->outBuf[i] = ' '; 1843 } 1844 } 1845 1846 if (!gotNL) { 1847 job->curPos += nr; 1848 if (job->curPos == JOB_BUFSIZE) { 1849 /* 1850 * If we've run out of buffer space, we have no choice 1851 * but to print the stuff. sigh. 1852 */ 1853 fbuf = TRUE; 1854 i = job->curPos; 1855 } 1856 } 1857 if (gotNL || fbuf) { 1858 /* 1859 * Need to send the output to the screen. Null terminate it 1860 * first, overwriting the newline character if there was one. 1861 * So long as the line isn't one we should filter (according 1862 * to the shell description), we print the line, preceded 1863 * by a target banner if this target isn't the same as the 1864 * one for which we last printed something. 1865 * The rest of the data in the buffer are then shifted down 1866 * to the start of the buffer and curPos is set accordingly. 1867 */ 1868 job->outBuf[i] = '\0'; 1869 if (i >= job->curPos) { 1870 char *cp; 1871 1872 cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE); 1873 1874 /* 1875 * There's still more in that thar buffer. This time, though, 1876 * we know there's no newline at the end, so we add one of 1877 * our own free will. 1878 */ 1879 if (*cp != '\0') { 1880 if (!beSilent && job->node != lastNode) { 1881 MESSAGE(stdout, job->node); 1882 lastNode = job->node; 1883 } 1884 #ifdef USE_META 1885 if (useMeta) { 1886 meta_job_output(job, cp, gotNL ? "\n" : ""); 1887 } 1888 #endif 1889 (void)fprintf(stdout, "%s%s", cp, gotNL ? "\n" : ""); 1890 (void)fflush(stdout); 1891 } 1892 } 1893 if (i < max - 1) { 1894 /* shift the remaining characters down */ 1895 (void)memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1)); 1896 job->curPos = max - (i + 1); 1897 1898 } else { 1899 /* 1900 * We have written everything out, so we just start over 1901 * from the start of the buffer. No copying. No nothing. 1902 */ 1903 job->curPos = 0; 1904 } 1905 } 1906 if (finish) { 1907 /* 1908 * If the finish flag is true, we must loop until we hit 1909 * end-of-file on the pipe. This is guaranteed to happen 1910 * eventually since the other end of the pipe is now closed 1911 * (we closed it explicitly and the child has exited). When 1912 * we do get an EOF, finish will be set FALSE and we'll fall 1913 * through and out. 1914 */ 1915 goto end_loop; 1916 } 1917 } 1918 1919 static void 1920 JobRun(GNode *targ) 1921 { 1922 #ifdef notyet 1923 /* 1924 * Unfortunately it is too complicated to run .BEGIN, .END, 1925 * and .INTERRUPT job in the parallel job module. This has 1926 * the nice side effect that it avoids a lot of other problems. 1927 */ 1928 Lst lst = Lst_Init(FALSE); 1929 Lst_AtEnd(lst, targ); 1930 (void)Make_Run(lst); 1931 Lst_Destroy(lst, NULL); 1932 JobStart(targ, JOB_SPECIAL); 1933 while (jobTokensRunning) { 1934 Job_CatchOutput(); 1935 } 1936 #else 1937 Compat_Make(targ, targ); 1938 if (targ->made == ERROR) { 1939 PrintOnError(targ, "\n\nStop."); 1940 exit(1); 1941 } 1942 #endif 1943 } 1944 1945 /*- 1946 *----------------------------------------------------------------------- 1947 * Job_CatchChildren -- 1948 * Handle the exit of a child. Called from Make_Make. 1949 * 1950 * Input: 1951 * block TRUE if should block on the wait 1952 * 1953 * Results: 1954 * none. 1955 * 1956 * Side Effects: 1957 * The job descriptor is removed from the list of children. 1958 * 1959 * Notes: 1960 * We do waits, blocking or not, according to the wisdom of our 1961 * caller, until there are no more children to report. For each 1962 * job, call JobFinish to finish things off. 1963 * 1964 *----------------------------------------------------------------------- 1965 */ 1966 1967 void 1968 Job_CatchChildren(void) 1969 { 1970 int pid; /* pid of dead child */ 1971 WAIT_T status; /* Exit/termination status */ 1972 1973 /* 1974 * Don't even bother if we know there's no one around. 1975 */ 1976 if (jobTokensRunning == 0) 1977 return; 1978 1979 while ((pid = waitpid((pid_t) -1, &status, WNOHANG | WUNTRACED)) > 0) { 1980 if (DEBUG(JOB)) { 1981 (void)fprintf(debug_file, "Process %d exited/stopped status %x.\n", pid, 1982 WAIT_STATUS(status)); 1983 } 1984 JobReapChild(pid, status, TRUE); 1985 } 1986 } 1987 1988 /* 1989 * It is possible that wait[pid]() was called from elsewhere, 1990 * this lets us reap jobs regardless. 1991 */ 1992 void 1993 JobReapChild(pid_t pid, WAIT_T status, Boolean isJobs) 1994 { 1995 Job *job; /* job descriptor for dead child */ 1996 1997 /* 1998 * Don't even bother if we know there's no one around. 1999 */ 2000 if (jobTokensRunning == 0) 2001 return; 2002 2003 job = JobFindPid(pid, JOB_ST_RUNNING, isJobs); 2004 if (job == NULL) { 2005 if (isJobs) { 2006 if (!lurking_children) 2007 Error("Child (%d) status %x not in table?", pid, status); 2008 } 2009 return; /* not ours */ 2010 } 2011 if (WIFSTOPPED(status)) { 2012 if (DEBUG(JOB)) { 2013 (void)fprintf(debug_file, "Process %d (%s) stopped.\n", 2014 job->pid, job->node->name); 2015 } 2016 if (!make_suspended) { 2017 switch (WSTOPSIG(status)) { 2018 case SIGTSTP: 2019 (void)printf("*** [%s] Suspended\n", job->node->name); 2020 break; 2021 case SIGSTOP: 2022 (void)printf("*** [%s] Stopped\n", job->node->name); 2023 break; 2024 default: 2025 (void)printf("*** [%s] Stopped -- signal %d\n", 2026 job->node->name, WSTOPSIG(status)); 2027 } 2028 job->job_suspended = 1; 2029 } 2030 (void)fflush(stdout); 2031 return; 2032 } 2033 2034 job->job_state = JOB_ST_FINISHED; 2035 job->exit_status = WAIT_STATUS(status); 2036 2037 JobFinish(job, status); 2038 } 2039 2040 /*- 2041 *----------------------------------------------------------------------- 2042 * Job_CatchOutput -- 2043 * Catch the output from our children, if we're using 2044 * pipes do so. Otherwise just block time until we get a 2045 * signal(most likely a SIGCHLD) since there's no point in 2046 * just spinning when there's nothing to do and the reaping 2047 * of a child can wait for a while. 2048 * 2049 * Results: 2050 * None 2051 * 2052 * Side Effects: 2053 * Output is read from pipes if we're piping. 2054 * ----------------------------------------------------------------------- 2055 */ 2056 void 2057 Job_CatchOutput(void) 2058 { 2059 int nready; 2060 Job *job; 2061 int i; 2062 2063 (void)fflush(stdout); 2064 2065 /* The first fd in the list is the job token pipe */ 2066 nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC); 2067 2068 if (nready < 0 || readyfd(&childExitJob)) { 2069 char token = 0; 2070 nready -= 1; 2071 while (read(childExitJob.inPipe, &token, 1) == -1 && errno == EAGAIN) 2072 continue; 2073 if (token == DO_JOB_RESUME[0]) 2074 /* Complete relay requested from our SIGCONT handler */ 2075 JobRestartJobs(); 2076 Job_CatchChildren(); 2077 } 2078 2079 if (nready <= 0) 2080 return; 2081 2082 if (wantToken && readyfd(&tokenWaitJob)) 2083 nready--; 2084 2085 for (i = 2; i < nfds; i++) { 2086 if (!fds[i].revents) 2087 continue; 2088 job = jobfds[i]; 2089 if (job->job_state != JOB_ST_RUNNING) 2090 continue; 2091 JobDoOutput(job, FALSE); 2092 } 2093 } 2094 2095 /*- 2096 *----------------------------------------------------------------------- 2097 * Job_Make -- 2098 * Start the creation of a target. Basically a front-end for 2099 * JobStart used by the Make module. 2100 * 2101 * Results: 2102 * None. 2103 * 2104 * Side Effects: 2105 * Another job is started. 2106 * 2107 *----------------------------------------------------------------------- 2108 */ 2109 void 2110 Job_Make(GNode *gn) 2111 { 2112 (void)JobStart(gn, 0); 2113 } 2114 2115 void 2116 Shell_Init(void) 2117 { 2118 if (shellPath == NULL) { 2119 /* 2120 * We are using the default shell, which may be an absolute 2121 * path if DEFSHELL_CUSTOM is defined. 2122 */ 2123 shellName = commandShell->name; 2124 #ifdef DEFSHELL_CUSTOM 2125 if (*shellName == '/') { 2126 shellPath = shellName; 2127 shellName = strrchr(shellPath, '/'); 2128 shellName++; 2129 } else 2130 #endif 2131 shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH); 2132 } 2133 if (commandShell->exit == NULL) { 2134 commandShell->exit = ""; 2135 } 2136 if (commandShell->echo == NULL) { 2137 commandShell->echo = ""; 2138 } 2139 } 2140 2141 /*- 2142 * Returns the string literal that is used in the current command shell 2143 * to produce a newline character. 2144 */ 2145 const char * 2146 Shell_GetNewline(void) 2147 { 2148 2149 return commandShell->newline; 2150 } 2151 2152 void 2153 Job_SetPrefix(void) 2154 { 2155 2156 if (targPrefix) { 2157 free(targPrefix); 2158 } else if (!Var_Exists(MAKE_JOB_PREFIX, VAR_GLOBAL)) { 2159 Var_Set(MAKE_JOB_PREFIX, "---", VAR_GLOBAL, 0); 2160 } 2161 2162 targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}", VAR_GLOBAL, 0); 2163 } 2164 2165 /*- 2166 *----------------------------------------------------------------------- 2167 * Job_Init -- 2168 * Initialize the process module 2169 * 2170 * Input: 2171 * 2172 * Results: 2173 * none 2174 * 2175 * Side Effects: 2176 * lists and counters are initialized 2177 *----------------------------------------------------------------------- 2178 */ 2179 void 2180 Job_Init(void) 2181 { 2182 GNode *begin; /* node for commands to do at the very start */ 2183 2184 /* Allocate space for all the job info */ 2185 job_table = bmake_malloc(maxJobs * sizeof *job_table); 2186 memset(job_table, 0, maxJobs * sizeof *job_table); 2187 job_table_end = job_table + maxJobs; 2188 wantToken = 0; 2189 2190 aborting = 0; 2191 errors = 0; 2192 2193 lastNode = NULL; 2194 2195 /* 2196 * There is a non-zero chance that we already have children. 2197 * eg after 'make -f- <<EOF' 2198 * Since their termination causes a 'Child (pid) not in table' message, 2199 * Collect the status of any that are already dead, and suppress the 2200 * error message if there are any undead ones. 2201 */ 2202 for (;;) { 2203 int rval, status; 2204 rval = waitpid((pid_t) -1, &status, WNOHANG); 2205 if (rval > 0) 2206 continue; 2207 if (rval == 0) 2208 lurking_children = 1; 2209 break; 2210 } 2211 2212 Shell_Init(); 2213 2214 JobCreatePipe(&childExitJob, 3); 2215 2216 /* We can only need to wait for tokens, children and output from each job */ 2217 fds = bmake_malloc(sizeof (*fds) * (2 + maxJobs)); 2218 jobfds = bmake_malloc(sizeof (*jobfds) * (2 + maxJobs)); 2219 2220 /* These are permanent entries and take slots 0 and 1 */ 2221 watchfd(&tokenWaitJob); 2222 watchfd(&childExitJob); 2223 2224 sigemptyset(&caught_signals); 2225 /* 2226 * Install a SIGCHLD handler. 2227 */ 2228 (void)bmake_signal(SIGCHLD, JobChildSig); 2229 sigaddset(&caught_signals, SIGCHLD); 2230 2231 #define ADDSIG(s,h) \ 2232 if (bmake_signal(s, SIG_IGN) != SIG_IGN) { \ 2233 sigaddset(&caught_signals, s); \ 2234 (void)bmake_signal(s, h); \ 2235 } 2236 2237 /* 2238 * Catch the four signals that POSIX specifies if they aren't ignored. 2239 * JobPassSig will take care of calling JobInterrupt if appropriate. 2240 */ 2241 ADDSIG(SIGINT, JobPassSig_int) 2242 ADDSIG(SIGHUP, JobPassSig_term) 2243 ADDSIG(SIGTERM, JobPassSig_term) 2244 ADDSIG(SIGQUIT, JobPassSig_term) 2245 2246 /* 2247 * There are additional signals that need to be caught and passed if 2248 * either the export system wants to be told directly of signals or if 2249 * we're giving each job its own process group (since then it won't get 2250 * signals from the terminal driver as we own the terminal) 2251 */ 2252 ADDSIG(SIGTSTP, JobPassSig_suspend) 2253 ADDSIG(SIGTTOU, JobPassSig_suspend) 2254 ADDSIG(SIGTTIN, JobPassSig_suspend) 2255 ADDSIG(SIGWINCH, JobCondPassSig) 2256 ADDSIG(SIGCONT, JobContinueSig) 2257 #undef ADDSIG 2258 2259 begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); 2260 2261 if (begin != NULL) { 2262 JobRun(begin); 2263 if (begin->made == ERROR) { 2264 PrintOnError(begin, "\n\nStop."); 2265 exit(1); 2266 } 2267 } 2268 postCommands = Targ_FindNode(".END", TARG_CREATE); 2269 } 2270 2271 static void JobSigReset(void) 2272 { 2273 #define DELSIG(s) \ 2274 if (sigismember(&caught_signals, s)) { \ 2275 (void)bmake_signal(s, SIG_DFL); \ 2276 } 2277 2278 DELSIG(SIGINT) 2279 DELSIG(SIGHUP) 2280 DELSIG(SIGQUIT) 2281 DELSIG(SIGTERM) 2282 DELSIG(SIGTSTP) 2283 DELSIG(SIGTTOU) 2284 DELSIG(SIGTTIN) 2285 DELSIG(SIGWINCH) 2286 DELSIG(SIGCONT) 2287 #undef DELSIG 2288 (void)bmake_signal(SIGCHLD, SIG_DFL); 2289 } 2290 2291 /*- 2292 *----------------------------------------------------------------------- 2293 * JobMatchShell -- 2294 * Find a shell in 'shells' given its name. 2295 * 2296 * Results: 2297 * A pointer to the Shell structure. 2298 * 2299 * Side Effects: 2300 * None. 2301 * 2302 *----------------------------------------------------------------------- 2303 */ 2304 static Shell * 2305 JobMatchShell(const char *name) 2306 { 2307 Shell *sh; 2308 2309 for (sh = shells; sh->name != NULL; sh++) { 2310 if (strcmp(name, sh->name) == 0) 2311 return (sh); 2312 } 2313 return NULL; 2314 } 2315 2316 /*- 2317 *----------------------------------------------------------------------- 2318 * Job_ParseShell -- 2319 * Parse a shell specification and set up commandShell, shellPath 2320 * and shellName appropriately. 2321 * 2322 * Input: 2323 * line The shell spec 2324 * 2325 * Results: 2326 * FAILURE if the specification was incorrect. 2327 * 2328 * Side Effects: 2329 * commandShell points to a Shell structure (either predefined or 2330 * created from the shell spec), shellPath is the full path of the 2331 * shell described by commandShell, while shellName is just the 2332 * final component of shellPath. 2333 * 2334 * Notes: 2335 * A shell specification consists of a .SHELL target, with dependency 2336 * operator, followed by a series of blank-separated words. Double 2337 * quotes can be used to use blanks in words. A backslash escapes 2338 * anything (most notably a double-quote and a space) and 2339 * provides the functionality it does in C. Each word consists of 2340 * keyword and value separated by an equal sign. There should be no 2341 * unnecessary spaces in the word. The keywords are as follows: 2342 * name Name of shell. 2343 * path Location of shell. 2344 * quiet Command to turn off echoing. 2345 * echo Command to turn echoing on 2346 * filter Result of turning off echoing that shouldn't be 2347 * printed. 2348 * echoFlag Flag to turn echoing on at the start 2349 * errFlag Flag to turn error checking on at the start 2350 * hasErrCtl True if shell has error checking control 2351 * newline String literal to represent a newline char 2352 * check Command to turn on error checking if hasErrCtl 2353 * is TRUE or template of command to echo a command 2354 * for which error checking is off if hasErrCtl is 2355 * FALSE. 2356 * ignore Command to turn off error checking if hasErrCtl 2357 * is TRUE or template of command to execute a 2358 * command so as to ignore any errors it returns if 2359 * hasErrCtl is FALSE. 2360 * 2361 *----------------------------------------------------------------------- 2362 */ 2363 ReturnStatus 2364 Job_ParseShell(char *line) 2365 { 2366 char **words; 2367 char **argv; 2368 int argc; 2369 char *path; 2370 Shell newShell; 2371 Boolean fullSpec = FALSE; 2372 Shell *sh; 2373 2374 while (isspace((unsigned char)*line)) { 2375 line++; 2376 } 2377 2378 if (shellArgv) 2379 free(UNCONST(shellArgv)); 2380 2381 memset(&newShell, 0, sizeof(newShell)); 2382 2383 /* 2384 * Parse the specification by keyword 2385 */ 2386 words = brk_string(line, &argc, TRUE, &path); 2387 if (words == NULL) { 2388 Error("Unterminated quoted string [%s]", line); 2389 return FAILURE; 2390 } 2391 shellArgv = path; 2392 2393 for (path = NULL, argv = words; argc != 0; argc--, argv++) { 2394 if (strncmp(*argv, "path=", 5) == 0) { 2395 path = &argv[0][5]; 2396 } else if (strncmp(*argv, "name=", 5) == 0) { 2397 newShell.name = &argv[0][5]; 2398 } else { 2399 if (strncmp(*argv, "quiet=", 6) == 0) { 2400 newShell.echoOff = &argv[0][6]; 2401 } else if (strncmp(*argv, "echo=", 5) == 0) { 2402 newShell.echoOn = &argv[0][5]; 2403 } else if (strncmp(*argv, "filter=", 7) == 0) { 2404 newShell.noPrint = &argv[0][7]; 2405 newShell.noPLen = strlen(newShell.noPrint); 2406 } else if (strncmp(*argv, "echoFlag=", 9) == 0) { 2407 newShell.echo = &argv[0][9]; 2408 } else if (strncmp(*argv, "errFlag=", 8) == 0) { 2409 newShell.exit = &argv[0][8]; 2410 } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) { 2411 char c = argv[0][10]; 2412 newShell.hasErrCtl = !((c != 'Y') && (c != 'y') && 2413 (c != 'T') && (c != 't')); 2414 } else if (strncmp(*argv, "newline=", 8) == 0) { 2415 newShell.newline = &argv[0][8]; 2416 } else if (strncmp(*argv, "check=", 6) == 0) { 2417 newShell.errCheck = &argv[0][6]; 2418 } else if (strncmp(*argv, "ignore=", 7) == 0) { 2419 newShell.ignErr = &argv[0][7]; 2420 } else if (strncmp(*argv, "errout=", 7) == 0) { 2421 newShell.errOut = &argv[0][7]; 2422 } else if (strncmp(*argv, "comment=", 8) == 0) { 2423 newShell.commentChar = argv[0][8]; 2424 } else { 2425 Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"", 2426 *argv); 2427 free(words); 2428 return(FAILURE); 2429 } 2430 fullSpec = TRUE; 2431 } 2432 } 2433 2434 if (path == NULL) { 2435 /* 2436 * If no path was given, the user wants one of the pre-defined shells, 2437 * yes? So we find the one s/he wants with the help of JobMatchShell 2438 * and set things up the right way. shellPath will be set up by 2439 * Shell_Init. 2440 */ 2441 if (newShell.name == NULL) { 2442 Parse_Error(PARSE_FATAL, "Neither path nor name specified"); 2443 free(words); 2444 return(FAILURE); 2445 } else { 2446 if ((sh = JobMatchShell(newShell.name)) == NULL) { 2447 Parse_Error(PARSE_WARNING, "%s: No matching shell", 2448 newShell.name); 2449 free(words); 2450 return(FAILURE); 2451 } 2452 commandShell = sh; 2453 shellName = newShell.name; 2454 if (shellPath) { 2455 /* Shell_Init has already been called! Do it again. */ 2456 free(UNCONST(shellPath)); 2457 shellPath = NULL; 2458 Shell_Init(); 2459 } 2460 } 2461 } else { 2462 /* 2463 * The user provided a path. If s/he gave nothing else (fullSpec is 2464 * FALSE), try and find a matching shell in the ones we know of. 2465 * Else we just take the specification at its word and copy it 2466 * to a new location. In either case, we need to record the 2467 * path the user gave for the shell. 2468 */ 2469 shellPath = path; 2470 path = strrchr(path, '/'); 2471 if (path == NULL) { 2472 path = UNCONST(shellPath); 2473 } else { 2474 path += 1; 2475 } 2476 if (newShell.name != NULL) { 2477 shellName = newShell.name; 2478 } else { 2479 shellName = path; 2480 } 2481 if (!fullSpec) { 2482 if ((sh = JobMatchShell(shellName)) == NULL) { 2483 Parse_Error(PARSE_WARNING, "%s: No matching shell", 2484 shellName); 2485 free(words); 2486 return(FAILURE); 2487 } 2488 commandShell = sh; 2489 } else { 2490 commandShell = bmake_malloc(sizeof(Shell)); 2491 *commandShell = newShell; 2492 } 2493 } 2494 2495 if (commandShell->echoOn && commandShell->echoOff) { 2496 commandShell->hasEchoCtl = TRUE; 2497 } 2498 2499 if (!commandShell->hasErrCtl) { 2500 if (commandShell->errCheck == NULL) { 2501 commandShell->errCheck = ""; 2502 } 2503 if (commandShell->ignErr == NULL) { 2504 commandShell->ignErr = "%s\n"; 2505 } 2506 } 2507 2508 /* 2509 * Do not free up the words themselves, since they might be in use by the 2510 * shell specification. 2511 */ 2512 free(words); 2513 return SUCCESS; 2514 } 2515 2516 /*- 2517 *----------------------------------------------------------------------- 2518 * JobInterrupt -- 2519 * Handle the receipt of an interrupt. 2520 * 2521 * Input: 2522 * runINTERRUPT Non-zero if commands for the .INTERRUPT target 2523 * should be executed 2524 * signo signal received 2525 * 2526 * Results: 2527 * None 2528 * 2529 * Side Effects: 2530 * All children are killed. Another job will be started if the 2531 * .INTERRUPT target was given. 2532 *----------------------------------------------------------------------- 2533 */ 2534 static void 2535 JobInterrupt(int runINTERRUPT, int signo) 2536 { 2537 Job *job; /* job descriptor in that element */ 2538 GNode *interrupt; /* the node describing the .INTERRUPT target */ 2539 sigset_t mask; 2540 GNode *gn; 2541 2542 aborting = ABORT_INTERRUPT; 2543 2544 JobSigLock(&mask); 2545 2546 for (job = job_table; job < job_table_end; job++) { 2547 if (job->job_state != JOB_ST_RUNNING) 2548 continue; 2549 2550 gn = job->node; 2551 2552 if ((gn->type & (OP_JOIN|OP_PHONY)) == 0 && !Targ_Precious(gn)) { 2553 char *file = (gn->path == NULL ? gn->name : gn->path); 2554 if (!noExecute && eunlink(file) != -1) { 2555 Error("*** %s removed", file); 2556 } 2557 } 2558 if (job->pid) { 2559 if (DEBUG(JOB)) { 2560 (void)fprintf(debug_file, 2561 "JobInterrupt passing signal %d to child %d.\n", 2562 signo, job->pid); 2563 } 2564 KILLPG(job->pid, signo); 2565 } 2566 } 2567 2568 JobSigUnlock(&mask); 2569 2570 if (runINTERRUPT && !touchFlag) { 2571 interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 2572 if (interrupt != NULL) { 2573 ignoreErrors = FALSE; 2574 JobRun(interrupt); 2575 } 2576 } 2577 Trace_Log(MAKEINTR, 0); 2578 exit(signo); 2579 } 2580 2581 /* 2582 *----------------------------------------------------------------------- 2583 * Job_Finish -- 2584 * Do final processing such as the running of the commands 2585 * attached to the .END target. 2586 * 2587 * Results: 2588 * Number of errors reported. 2589 * 2590 * Side Effects: 2591 * None. 2592 *----------------------------------------------------------------------- 2593 */ 2594 int 2595 Job_Finish(void) 2596 { 2597 if (postCommands != NULL && 2598 (!Lst_IsEmpty(postCommands->commands) || 2599 !Lst_IsEmpty(postCommands->children))) { 2600 if (errors) { 2601 Error("Errors reported so .END ignored"); 2602 } else { 2603 JobRun(postCommands); 2604 } 2605 } 2606 return(errors); 2607 } 2608 2609 /*- 2610 *----------------------------------------------------------------------- 2611 * Job_End -- 2612 * Cleanup any memory used by the jobs module 2613 * 2614 * Results: 2615 * None. 2616 * 2617 * Side Effects: 2618 * Memory is freed 2619 *----------------------------------------------------------------------- 2620 */ 2621 void 2622 Job_End(void) 2623 { 2624 #ifdef CLEANUP 2625 if (shellArgv) 2626 free(shellArgv); 2627 #endif 2628 } 2629 2630 /*- 2631 *----------------------------------------------------------------------- 2632 * Job_Wait -- 2633 * Waits for all running jobs to finish and returns. Sets 'aborting' 2634 * to ABORT_WAIT to prevent other jobs from starting. 2635 * 2636 * Results: 2637 * None. 2638 * 2639 * Side Effects: 2640 * Currently running jobs finish. 2641 * 2642 *----------------------------------------------------------------------- 2643 */ 2644 void 2645 Job_Wait(void) 2646 { 2647 aborting = ABORT_WAIT; 2648 while (jobTokensRunning != 0) { 2649 Job_CatchOutput(); 2650 } 2651 aborting = 0; 2652 } 2653 2654 /*- 2655 *----------------------------------------------------------------------- 2656 * Job_AbortAll -- 2657 * Abort all currently running jobs without handling output or anything. 2658 * This function is to be called only in the event of a major 2659 * error. Most definitely NOT to be called from JobInterrupt. 2660 * 2661 * Results: 2662 * None 2663 * 2664 * Side Effects: 2665 * All children are killed, not just the firstborn 2666 *----------------------------------------------------------------------- 2667 */ 2668 void 2669 Job_AbortAll(void) 2670 { 2671 Job *job; /* the job descriptor in that element */ 2672 WAIT_T foo; 2673 2674 aborting = ABORT_ERROR; 2675 2676 if (jobTokensRunning) { 2677 for (job = job_table; job < job_table_end; job++) { 2678 if (job->job_state != JOB_ST_RUNNING) 2679 continue; 2680 /* 2681 * kill the child process with increasingly drastic signals to make 2682 * darn sure it's dead. 2683 */ 2684 KILLPG(job->pid, SIGINT); 2685 KILLPG(job->pid, SIGKILL); 2686 } 2687 } 2688 2689 /* 2690 * Catch as many children as want to report in at first, then give up 2691 */ 2692 while (waitpid((pid_t) -1, &foo, WNOHANG) > 0) 2693 continue; 2694 } 2695 2696 2697 /*- 2698 *----------------------------------------------------------------------- 2699 * JobRestartJobs -- 2700 * Tries to restart stopped jobs if there are slots available. 2701 * Called in process context in response to a SIGCONT. 2702 * 2703 * Results: 2704 * None. 2705 * 2706 * Side Effects: 2707 * Resumes jobs. 2708 * 2709 *----------------------------------------------------------------------- 2710 */ 2711 static void 2712 JobRestartJobs(void) 2713 { 2714 Job *job; 2715 2716 for (job = job_table; job < job_table_end; job++) { 2717 if (job->job_state == JOB_ST_RUNNING && 2718 (make_suspended || job->job_suspended)) { 2719 if (DEBUG(JOB)) { 2720 (void)fprintf(debug_file, "Restarting stopped job pid %d.\n", 2721 job->pid); 2722 } 2723 if (job->job_suspended) { 2724 (void)printf("*** [%s] Continued\n", job->node->name); 2725 (void)fflush(stdout); 2726 } 2727 job->job_suspended = 0; 2728 if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) { 2729 fprintf(debug_file, "Failed to send SIGCONT to %d\n", job->pid); 2730 } 2731 } 2732 if (job->job_state == JOB_ST_FINISHED) 2733 /* Job exit deferred after calling waitpid() in a signal handler */ 2734 JobFinish(job, job->exit_status); 2735 } 2736 make_suspended = 0; 2737 } 2738 2739 static void 2740 watchfd(Job *job) 2741 { 2742 if (job->inPollfd != NULL) 2743 Punt("Watching watched job"); 2744 2745 fds[nfds].fd = job->inPipe; 2746 fds[nfds].events = POLLIN; 2747 jobfds[nfds] = job; 2748 job->inPollfd = &fds[nfds]; 2749 nfds++; 2750 } 2751 2752 static void 2753 clearfd(Job *job) 2754 { 2755 int i; 2756 if (job->inPollfd == NULL) 2757 Punt("Unwatching unwatched job"); 2758 i = job->inPollfd - fds; 2759 nfds--; 2760 /* 2761 * Move last job in table into hole made by dead job. 2762 */ 2763 if (nfds != i) { 2764 fds[i] = fds[nfds]; 2765 jobfds[i] = jobfds[nfds]; 2766 jobfds[i]->inPollfd = &fds[i]; 2767 } 2768 job->inPollfd = NULL; 2769 } 2770 2771 static int 2772 readyfd(Job *job) 2773 { 2774 if (job->inPollfd == NULL) 2775 Punt("Polling unwatched job"); 2776 return (job->inPollfd->revents & POLLIN) != 0; 2777 } 2778 2779 /*- 2780 *----------------------------------------------------------------------- 2781 * JobTokenAdd -- 2782 * Put a token into the job pipe so that some make process can start 2783 * another job. 2784 * 2785 * Side Effects: 2786 * Allows more build jobs to be spawned somewhere. 2787 * 2788 *----------------------------------------------------------------------- 2789 */ 2790 2791 static void 2792 JobTokenAdd(void) 2793 { 2794 char tok = JOB_TOKENS[aborting], tok1; 2795 2796 /* If we are depositing an error token flush everything else */ 2797 while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1) 2798 continue; 2799 2800 if (DEBUG(JOB)) 2801 fprintf(debug_file, "(%d) aborting %d, deposit token %c\n", 2802 getpid(), aborting, JOB_TOKENS[aborting]); 2803 while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN) 2804 continue; 2805 } 2806 2807 /*- 2808 *----------------------------------------------------------------------- 2809 * Job_ServerStartTokenAdd -- 2810 * Prep the job token pipe in the root make process. 2811 * 2812 *----------------------------------------------------------------------- 2813 */ 2814 2815 void 2816 Job_ServerStart(int max_tokens, int jp_0, int jp_1) 2817 { 2818 int i; 2819 char jobarg[64]; 2820 2821 if (jp_0 >= 0 && jp_1 >= 0) { 2822 /* Pipe passed in from parent */ 2823 tokenWaitJob.inPipe = jp_0; 2824 tokenWaitJob.outPipe = jp_1; 2825 return; 2826 } 2827 2828 JobCreatePipe(&tokenWaitJob, 15); 2829 2830 snprintf(jobarg, sizeof(jobarg), "%d,%d", 2831 tokenWaitJob.inPipe, tokenWaitJob.outPipe); 2832 2833 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); 2834 Var_Append(MAKEFLAGS, jobarg, VAR_GLOBAL); 2835 2836 /* 2837 * Preload the job pipe with one token per job, save the one 2838 * "extra" token for the primary job. 2839 * 2840 * XXX should clip maxJobs against PIPE_BUF -- if max_tokens is 2841 * larger than the write buffer size of the pipe, we will 2842 * deadlock here. 2843 */ 2844 for (i = 1; i < max_tokens; i++) 2845 JobTokenAdd(); 2846 } 2847 2848 /*- 2849 *----------------------------------------------------------------------- 2850 * Job_TokenReturn -- 2851 * Return a withdrawn token to the pool. 2852 * 2853 *----------------------------------------------------------------------- 2854 */ 2855 2856 void 2857 Job_TokenReturn(void) 2858 { 2859 jobTokensRunning--; 2860 if (jobTokensRunning < 0) 2861 Punt("token botch"); 2862 if (jobTokensRunning || JOB_TOKENS[aborting] != '+') 2863 JobTokenAdd(); 2864 } 2865 2866 /*- 2867 *----------------------------------------------------------------------- 2868 * Job_TokenWithdraw -- 2869 * Attempt to withdraw a token from the pool. 2870 * 2871 * Results: 2872 * Returns TRUE if a token was withdrawn, and FALSE if the pool 2873 * is currently empty. 2874 * 2875 * Side Effects: 2876 * If pool is empty, set wantToken so that we wake up 2877 * when a token is released. 2878 * 2879 *----------------------------------------------------------------------- 2880 */ 2881 2882 2883 Boolean 2884 Job_TokenWithdraw(void) 2885 { 2886 char tok, tok1; 2887 int count; 2888 2889 wantToken = 0; 2890 if (DEBUG(JOB)) 2891 fprintf(debug_file, "Job_TokenWithdraw(%d): aborting %d, running %d\n", 2892 getpid(), aborting, jobTokensRunning); 2893 2894 if (aborting || (jobTokensRunning >= maxJobs)) 2895 return FALSE; 2896 2897 count = read(tokenWaitJob.inPipe, &tok, 1); 2898 if (count == 0) 2899 Fatal("eof on job pipe!"); 2900 if (count < 0 && jobTokensRunning != 0) { 2901 if (errno != EAGAIN) { 2902 Fatal("job pipe read: %s", strerror(errno)); 2903 } 2904 if (DEBUG(JOB)) 2905 fprintf(debug_file, "(%d) blocked for token\n", getpid()); 2906 wantToken = 1; 2907 return FALSE; 2908 } 2909 2910 if (count == 1 && tok != '+') { 2911 /* make being abvorted - remove any other job tokens */ 2912 if (DEBUG(JOB)) 2913 fprintf(debug_file, "(%d) aborted by token %c\n", getpid(), tok); 2914 while (read(tokenWaitJob.inPipe, &tok1, 1) == 1) 2915 continue; 2916 /* And put the stopper back */ 2917 while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN) 2918 continue; 2919 Fatal("A failure has been detected in another branch of the parallel make"); 2920 } 2921 2922 if (count == 1 && jobTokensRunning == 0) 2923 /* We didn't want the token really */ 2924 while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN) 2925 continue; 2926 2927 jobTokensRunning++; 2928 if (DEBUG(JOB)) 2929 fprintf(debug_file, "(%d) withdrew token\n", getpid()); 2930 return TRUE; 2931 } 2932 2933 #ifdef USE_SELECT 2934 int 2935 emul_poll(struct pollfd *fd, int nfd, int timeout) 2936 { 2937 fd_set rfds, wfds; 2938 int i, maxfd, nselect, npoll; 2939 struct timeval tv, *tvp; 2940 long usecs; 2941 2942 FD_ZERO(&rfds); 2943 FD_ZERO(&wfds); 2944 2945 maxfd = -1; 2946 for (i = 0; i < nfd; i++) { 2947 fd[i].revents = 0; 2948 2949 if (fd[i].events & POLLIN) 2950 FD_SET(fd[i].fd, &rfds); 2951 2952 if (fd[i].events & POLLOUT) 2953 FD_SET(fd[i].fd, &wfds); 2954 2955 if (fd[i].fd > maxfd) 2956 maxfd = fd[i].fd; 2957 } 2958 2959 if (maxfd >= FD_SETSIZE) { 2960 Punt("Ran out of fd_set slots; " 2961 "recompile with a larger FD_SETSIZE."); 2962 } 2963 2964 if (timeout < 0) { 2965 tvp = NULL; 2966 } else { 2967 usecs = timeout * 1000; 2968 tv.tv_sec = usecs / 1000000; 2969 tv.tv_usec = usecs % 1000000; 2970 tvp = &tv; 2971 } 2972 2973 nselect = select(maxfd + 1, &rfds, &wfds, 0, tvp); 2974 2975 if (nselect <= 0) 2976 return nselect; 2977 2978 npoll = 0; 2979 for (i = 0; i < nfd; i++) { 2980 if (FD_ISSET(fd[i].fd, &rfds)) 2981 fd[i].revents |= POLLIN; 2982 2983 if (FD_ISSET(fd[i].fd, &wfds)) 2984 fd[i].revents |= POLLOUT; 2985 2986 if (fd[i].revents) 2987 npoll++; 2988 } 2989 2990 return npoll; 2991 } 2992 #endif /* USE_SELECT */ 2993