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