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