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