1 /* $NetBSD: job.c,v 1.529 2026/04/06 17:13:54 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 /* 73 * Create child processes and collect their output. 74 * 75 * Interface: 76 * Job_Init Initialize this module and make the .BEGIN target. 77 * 78 * Job_End Clean up any memory used. 79 * 80 * Job_Make Start making the given target. 81 * 82 * Job_CatchChildren 83 * Handle the termination of any children. 84 * 85 * Job_CatchOutput 86 * Print any output the child processes have produced. 87 * 88 * Job_ParseShell Given a special dependency line with target '.SHELL', 89 * define the shell that is used for the creation 90 * commands in jobs mode. 91 * 92 * Job_MakeDotEnd Make the .END target. Must only be called when the 93 * job table is empty. 94 * 95 * Job_AbortAll Kill all currently running jobs, in an emergency. 96 * 97 * Job_CheckCommands 98 * Add fallback commands to a target, if necessary. 99 * 100 * Job_Touch Update a target without really updating it. 101 * 102 * Job_Wait Wait for all currently-running jobs to finish. 103 */ 104 105 #include <sys/types.h> 106 #include <sys/stat.h> 107 #include <sys/time.h> 108 #include <sys/wait.h> 109 110 #include <errno.h> 111 #ifndef USE_SELECT 112 #include <poll.h> 113 #endif 114 #include <signal.h> 115 #include <utime.h> 116 117 #include "make.h" 118 #include "dir.h" 119 #include "job.h" 120 #ifdef USE_META 121 # include "meta.h" 122 #endif 123 #include "pathnames.h" 124 #include "trace.h" 125 126 /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ 127 MAKE_RCSID("$NetBSD: job.c,v 1.529 2026/04/06 17:13:54 rillig Exp $"); 128 129 130 #ifdef USE_SELECT 131 /* 132 * Emulate poll() in terms of select(). This is not a complete 133 * emulation but it is sufficient for make's purposes. 134 */ 135 136 #define poll emul_poll 137 #define pollfd emul_pollfd 138 139 struct emul_pollfd { 140 int fd; 141 short events; 142 short revents; 143 }; 144 145 #define POLLIN 0x0001 146 #define POLLOUT 0x0004 147 148 int emul_poll(struct pollfd *, int, int); 149 #endif 150 151 struct pollfd; 152 153 154 enum JobStatus { 155 JOB_ST_FREE, /* Job is available */ 156 JOB_ST_SET_UP, /* Job is allocated but otherwise invalid */ 157 JOB_ST_RUNNING, /* Job is running, pid valid */ 158 JOB_ST_FINISHED /* Job is done (i.e. after SIGCHLD) */ 159 }; 160 161 static const char JobStatus_Name[][9] = { 162 "free", 163 "set-up", 164 "running", 165 "finished", 166 }; 167 168 /* 169 * A Job manages the shell commands that are run to create a single target. 170 * Each job is run in a separate subprocess by a shell. Several jobs can run 171 * in parallel. 172 * 173 * The shell commands for the target are written to a temporary file, 174 * then the shell is run with the temporary file as stdin, and the output 175 * of that shell is captured via a pipe. 176 * 177 * When a job is finished, Make_Update updates all parents of the node 178 * that was just remade, marking them as ready to be made next if all 179 * other dependencies are finished as well. 180 */ 181 struct Job { 182 /* The process ID of the shell running the commands */ 183 int pid; 184 185 /* The target the child is making */ 186 GNode *node; 187 188 /* 189 * If one of the shell commands is "...", all following commands are 190 * delayed until the .END node is made. This list node points to the 191 * first of these commands, if any. 192 */ 193 StringListNode *tailCmds; 194 195 /* This is where the shell commands go. */ 196 FILE *cmdFILE; 197 198 int exit_status; /* from wait4() in signal handler */ 199 200 enum JobStatus status; 201 202 bool suspended; 203 204 /* Ignore non-zero exits */ 205 bool ignerr; 206 /* Output the command before or instead of running it. */ 207 bool echo; 208 /* Target is a special one. */ 209 bool special; 210 211 int inPipe; /* Pipe for reading output from job */ 212 int outPipe; /* Pipe for writing control commands */ 213 struct pollfd *inPollfd; /* pollfd associated with inPipe */ 214 215 #define JOB_BUFSIZE 1024 216 /* Buffer for storing the output of the job, line by line. */ 217 char outBuf[JOB_BUFSIZE + 1]; 218 size_t outBufLen; 219 220 #ifdef USE_META 221 struct BuildMon bm; 222 #endif 223 }; 224 225 226 /* 227 * A shell defines how the commands are run. All commands for a target are 228 * written into a single file, which is then given to the shell to execute 229 * the commands from it. The commands are written to the file using a few 230 * templates for echo control and error control. 231 * 232 * The name of the shell is the basename for the predefined shells, such as 233 * "sh", "csh", "bash". For custom shells, it is the full pathname, and its 234 * basename is used to select the type of shell; the longest match wins. 235 * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. 236 * 237 * The echoing of command lines is controlled using hasEchoCtl, echoOff, 238 * echoOn, noPrint and noPrintLen. When echoOff is executed by the shell, it 239 * still outputs something, but this something is not interesting, therefore 240 * it is filtered out using noPrint and noPrintLen. 241 * 242 * The error checking for individual commands is controlled using hasErrCtl, 243 * errOn, errOff and runChkTmpl. 244 * 245 * In case a shell doesn't have error control, echoTmpl is a printf template 246 * for echoing the command, should echoing be on; runIgnTmpl is another 247 * printf template for executing the command while ignoring the return 248 * status. Finally runChkTmpl is a printf template for running the command and 249 * causing the shell to exit on error. If any of these strings are empty when 250 * hasErrCtl is false, the command will be executed anyway as is, and if it 251 * causes an error, so be it. Any templates set up to echo the command will 252 * escape any '$ ` \ "' characters in the command string to avoid unwanted 253 * shell code injection, the escaped command is safe to use in double quotes. 254 * 255 * The command-line flags "echo" and "exit" also control the behavior. The 256 * "echo" flag causes the shell to start echoing commands right away. The 257 * "exit" flag causes the shell to exit when an error is detected in one of 258 * the commands. 259 */ 260 typedef struct Shell { 261 262 /* 263 * The name of the shell. For Bourne and C shells, this is used only 264 * to find the shell description when used as the single source of a 265 * .SHELL target. For user-defined shells, this is the full path of 266 * the shell. 267 */ 268 const char *name; 269 270 bool hasEchoCtl; /* whether both echoOff and echoOn are there */ 271 const char *echoOff; /* command to turn echoing off */ 272 const char *echoOn; /* command to turn echoing back on */ 273 const char *noPrint; /* text to skip when printing output from the 274 * shell. This is usually the same as echoOff */ 275 size_t noPrintLen; /* length of noPrint command */ 276 277 bool hasErrCtl; /* whether error checking can be controlled 278 * for individual commands */ 279 const char *errOn; /* command to turn on error checking */ 280 const char *errOff; /* command to turn off error checking */ 281 282 const char *echoTmpl; /* template to echo a command */ 283 const char *runIgnTmpl; /* template to run a command without error 284 * checking */ 285 const char *runChkTmpl; /* template to run a command with error 286 * checking */ 287 288 /* 289 * A string literal that results in a newline character when it 290 * occurs outside of any 'quote' or "quote" characters. 291 */ 292 const char *newline; 293 char commentChar; /* character used by shell for comment lines */ 294 295 const char *echoFlag; /* shell flag to echo commands */ 296 const char *errFlag; /* shell flag to exit on error */ 297 } Shell; 298 299 typedef struct CommandFlags { 300 /* Whether to echo the command before or instead of running it. */ 301 bool echo; 302 303 /* Run the command even in -n or -N mode. */ 304 bool always; 305 306 /* 307 * true if we turned error checking off before writing the command to 308 * the commands file and need to turn it back on 309 */ 310 bool ignerr; 311 } CommandFlags; 312 313 /* 314 * Write shell commands to a file. 315 * 316 * TODO: keep track of whether commands are echoed. 317 * TODO: keep track of whether error checking is active. 318 */ 319 typedef struct ShellWriter { 320 FILE *f; 321 322 /* we've sent 'set -x' */ 323 bool xtraced; 324 325 } ShellWriter; 326 327 /* error handling variables */ 328 static int job_errors = 0; /* number of errors reported */ 329 static enum { /* Why is the make aborting? */ 330 ABORT_NONE, 331 ABORT_ERROR, /* Aborted because of an error */ 332 ABORT_INTERRUPT, /* Aborted because it was interrupted */ 333 ABORT_WAIT /* Waiting for jobs to finish */ 334 } aborting = ABORT_NONE; 335 #define JOB_TOKENS "+EI+" /* Token to requeue for each abort state */ 336 337 static const char aborting_name[][6] = { "NONE", "ERROR", "INTR", "WAIT" }; 338 339 /* Tracks the number of tokens currently "out" to build jobs. */ 340 int jobTokensRunning = 0; 341 342 /* 343 * Descriptions for various shells. 344 * 345 * The build environment may set DEFSHELL_INDEX to one of 346 * DEFSHELL_INDEX_SH, DEFSHELL_INDEX_KSH, or DEFSHELL_INDEX_CSH, to 347 * select one of the predefined shells as the default shell. 348 * 349 * Alternatively, the build environment may set DEFSHELL_CUSTOM to the 350 * name or the full path of a sh-compatible shell, which will be used as 351 * the default shell. 352 * 353 * ".SHELL" lines in Makefiles can choose the default shell from the 354 * set defined here, or add additional shells. 355 */ 356 357 #ifdef DEFSHELL_CUSTOM 358 #define DEFSHELL_INDEX_CUSTOM 0 359 #define DEFSHELL_INDEX_SH 1 360 #define DEFSHELL_INDEX_KSH 2 361 #define DEFSHELL_INDEX_CSH 3 362 #else 363 #define DEFSHELL_INDEX_SH 0 364 #define DEFSHELL_INDEX_KSH 1 365 #define DEFSHELL_INDEX_CSH 2 366 #endif 367 368 #ifndef DEFSHELL_INDEX 369 #define DEFSHELL_INDEX 0 /* DEFSHELL_INDEX_CUSTOM or DEFSHELL_INDEX_SH */ 370 #endif 371 372 static Shell shells[] = { 373 #ifdef DEFSHELL_CUSTOM 374 /* 375 * An sh-compatible shell with a non-standard name. 376 * 377 * Keep this in sync with the "sh" description below, but avoid 378 * non-portable features that might not be supplied by all 379 * sh-compatible shells. 380 */ 381 { 382 DEFSHELL_CUSTOM, /* .name */ 383 false, /* .hasEchoCtl */ 384 "", /* .echoOff */ 385 "", /* .echoOn */ 386 "", /* .noPrint */ 387 0, /* .noPrintLen */ 388 false, /* .hasErrCtl */ 389 "", /* .errOn */ 390 "", /* .errOff */ 391 "echo \"%s\"\n", /* .echoTmpl */ 392 "%s\n", /* .runIgnTmpl */ 393 "{ %s \n} || exit $?\n", /* .runChkTmpl */ 394 "'\n'", /* .newline */ 395 '#', /* .commentChar */ 396 "", /* .echoFlag */ 397 "", /* .errFlag */ 398 }, 399 #endif /* DEFSHELL_CUSTOM */ 400 /* 401 * SH description. Echo control is also possible and, under 402 * sun UNIX anyway, one can even control error checking. 403 */ 404 { 405 "sh", /* .name */ 406 false, /* .hasEchoCtl */ 407 "", /* .echoOff */ 408 "", /* .echoOn */ 409 "", /* .noPrint */ 410 0, /* .noPrintLen */ 411 false, /* .hasErrCtl */ 412 "", /* .errOn */ 413 "", /* .errOff */ 414 "echo \"%s\"\n", /* .echoTmpl */ 415 "%s\n", /* .runIgnTmpl */ 416 "{ %s \n} || exit $?\n", /* .runChkTmpl */ 417 "'\n'", /* .newline */ 418 '#', /* .commentChar*/ 419 #if defined(MAKE_NATIVE) && defined(__NetBSD__) 420 /* XXX: -q is not really echoFlag, it's more like noEchoInSysFlag. */ 421 "q", /* .echoFlag */ 422 #else 423 "", /* .echoFlag */ 424 #endif 425 "", /* .errFlag */ 426 }, 427 /* 428 * KSH description. 429 */ 430 { 431 "ksh", /* .name */ 432 true, /* .hasEchoCtl */ 433 "set +v", /* .echoOff */ 434 "set -v", /* .echoOn */ 435 "set +v", /* .noPrint */ 436 6, /* .noPrintLen */ 437 false, /* .hasErrCtl */ 438 "", /* .errOn */ 439 "", /* .errOff */ 440 "echo \"%s\"\n", /* .echoTmpl */ 441 "%s\n", /* .runIgnTmpl */ 442 "{ %s \n} || exit $?\n", /* .runChkTmpl */ 443 "'\n'", /* .newline */ 444 '#', /* .commentChar */ 445 "v", /* .echoFlag */ 446 "", /* .errFlag */ 447 }, 448 /* 449 * CSH description. The csh can do echo control by playing 450 * with the setting of the 'echo' shell variable. Sadly, 451 * however, it is unable to do error control nicely. 452 */ 453 { 454 "csh", /* .name */ 455 true, /* .hasEchoCtl */ 456 "unset verbose", /* .echoOff */ 457 "set verbose", /* .echoOn */ 458 "unset verbose", /* .noPrint */ 459 13, /* .noPrintLen */ 460 false, /* .hasErrCtl */ 461 "", /* .errOn */ 462 "", /* .errOff */ 463 "echo \"%s\"\n", /* .echoTmpl */ 464 "csh -c \"%s || exit 0\"\n", /* .runIgnTmpl */ 465 "", /* .runChkTmpl */ 466 "'\\\n'", /* .newline */ 467 '#', /* .commentChar */ 468 "v", /* .echoFlag */ 469 "e", /* .errFlag */ 470 } 471 }; 472 473 /* 474 * This is the shell to which we pass all commands in the Makefile. 475 * It is set by the Job_ParseShell function. 476 */ 477 static Shell *shell = &shells[DEFSHELL_INDEX]; 478 char *shellPath; /* full pathname of executable image */ 479 const char *shellName = NULL; /* last component of shellPath */ 480 char *shellErrFlag = NULL; 481 static char *shell_freeIt = NULL; /* Allocated memory for custom .SHELL */ 482 483 484 static Job *job_table; /* The structures that describe them */ 485 static Job *job_table_end; /* job_table + maxJobs */ 486 static bool wantToken; 487 static bool lurking_children = false; 488 static bool make_suspended = false; /* Whether we've seen a SIGTSTP (etc) */ 489 490 /* 491 * Set of descriptors of pipes connected to 492 * the output channels of children 493 */ 494 static struct pollfd *fds = NULL; 495 static Job **jobByFdIndex = NULL; 496 static nfds_t fdsLen = 0; 497 static void watchfd(Job *); 498 static void clearfd(Job *); 499 500 static char *targPrefix = NULL; /* To identify a job change in the output. */ 501 502 static Job tokenPoolJob; /* token wait pseudo-job */ 503 504 static Job childExitJob; /* child exit pseudo-job */ 505 #define CEJ_CHILD_EXITED '.' 506 #define CEJ_RESUME_JOBS 'R' 507 508 enum { 509 npseudojobs = 2 /* number of pseudo-jobs */ 510 }; 511 512 static sigset_t caught_signals; /* Set of signals we handle */ 513 static volatile sig_atomic_t caught_sigchld; 514 515 static void CollectOutput(Job *, bool); 516 static void JobInterrupt(bool, int) MAKE_ATTR_DEAD; 517 static void JobSigReset(void); 518 519 static void 520 SwitchOutputTo(GNode *gn) 521 { 522 /* The node for which output was most recently produced. */ 523 static GNode *lastNode = NULL; 524 525 if (gn == lastNode) 526 return; 527 lastNode = gn; 528 529 if (opts.maxJobs != 1 && targPrefix != NULL && targPrefix[0] != '\0') 530 (void)fprintf(stdout, "%s %s ---\n", targPrefix, gn->name); 531 } 532 533 static unsigned 534 nfds_per_job(void) 535 { 536 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV) 537 if (useMeta) 538 return 2; 539 #endif 540 return 1; 541 } 542 543 void 544 Job_FlagsToString(const Job *job, char *buf, size_t bufsize) 545 { 546 snprintf(buf, bufsize, "%c%c%c", 547 job->ignerr ? 'i' : '-', 548 !job->echo ? 's' : '-', 549 job->special ? 'S' : '-'); 550 } 551 552 #ifdef USE_META 553 struct BuildMon * 554 Job_BuildMon(Job *job) 555 { 556 return &job->bm; 557 } 558 #endif 559 560 GNode * 561 Job_Node(Job *job) 562 { 563 return job->node; 564 } 565 566 int 567 Job_Pid(Job *job) 568 { 569 return job->pid; 570 } 571 572 static void 573 JobTable_Dump(const char *where) 574 { 575 const Job *job; 576 char flags[4]; 577 578 debug_printf("%s, job table:\n", where); 579 for (job = job_table; job < job_table_end; job++) { 580 Job_FlagsToString(job, flags, sizeof flags); 581 debug_printf("job %d, status %s, flags %s, pid %d\n", 582 (int)(job - job_table), JobStatus_Name[job->status], 583 flags, job->pid); 584 } 585 } 586 587 /* 588 * Delete the target of a failed, interrupted, or otherwise 589 * unsuccessful job unless inhibited by .PRECIOUS. 590 */ 591 static void 592 JobDeleteTarget(GNode *gn) 593 { 594 const char *file; 595 596 if (gn->type & OP_JOIN) 597 return; 598 if (gn->type & OP_PHONY) 599 return; 600 if (GNode_IsPrecious(gn)) 601 return; 602 if (opts.noExecute) 603 return; 604 605 file = GNode_Path(gn); 606 if (unlink_file(file) == 0) 607 Error("*** %s removed", file); 608 } 609 610 /* Lock the jobs table and the jobs therein. */ 611 static void 612 JobsTable_Lock(sigset_t *omaskp) 613 { 614 if (sigprocmask(SIG_BLOCK, &caught_signals, omaskp) != 0) 615 Punt("JobsTable_Lock: %s", strerror(errno)); 616 } 617 618 /* Unlock the jobs table and the jobs therein. */ 619 static void 620 JobsTable_Unlock(sigset_t *omaskp) 621 { 622 (void)sigprocmask(SIG_SETMASK, omaskp, NULL); 623 } 624 625 static void 626 SetNonblocking(int fd) 627 { 628 int flags = fcntl(fd, F_GETFL, 0); 629 if (flags == -1) 630 Punt("SetNonblocking.get: %s", strerror(errno)); 631 flags |= O_NONBLOCK; 632 if (fcntl(fd, F_SETFL, flags) == -1) 633 Punt("SetNonblocking.set: %s", strerror(errno)); 634 } 635 636 static void 637 SetCloseOnExec(int fd) 638 { 639 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) 640 Punt("SetCloseOnExec: %s", strerror(errno)); 641 } 642 643 static void 644 JobCreatePipe(Job *job, int minfd) 645 { 646 int i; 647 int pipe_fds[2]; 648 649 if (pipe(pipe_fds) == -1) 650 Punt("JobCreatePipe: %s", strerror(errno)); 651 652 for (i = 0; i < 2; i++) { 653 /* Avoid using low-numbered fds */ 654 int fd = fcntl(pipe_fds[i], F_DUPFD, minfd); 655 if (fd != -1) { 656 close(pipe_fds[i]); 657 pipe_fds[i] = fd; 658 } 659 } 660 661 job->inPipe = pipe_fds[0]; 662 job->outPipe = pipe_fds[1]; 663 664 SetCloseOnExec(job->inPipe); 665 SetCloseOnExec(job->outPipe); 666 667 /* 668 * We mark the input side of the pipe non-blocking; we poll(2) the 669 * pipe when we're waiting for a job token, but we might lose the 670 * race for the token when a new one becomes available, so the read 671 * from the pipe should not block. 672 */ 673 SetNonblocking(job->inPipe); 674 } 675 676 /* Pass the signal to each running job. */ 677 static void 678 JobCondPassSig(int signo) 679 { 680 Job *job; 681 682 DEBUG1(JOB, "JobCondPassSig: signal %d\n", signo); 683 684 for (job = job_table; job < job_table_end; job++) { 685 if (job->status != JOB_ST_RUNNING) 686 continue; 687 DEBUG2(JOB, "JobCondPassSig passing signal %d to pid %d\n", 688 signo, job->pid); 689 KILLPG(job->pid, signo); 690 } 691 } 692 693 static void 694 WriteOrDie(int fd, char ch) 695 { 696 if (write(fd, &ch, 1) != 1) 697 execDie("write", "child"); 698 } 699 700 static void 701 HandleSIGCHLD(int signo MAKE_ATTR_UNUSED) 702 { 703 caught_sigchld = 1; 704 /* Wake up from poll(). */ 705 WriteOrDie(childExitJob.outPipe, CEJ_CHILD_EXITED); 706 } 707 708 static void 709 HandleSIGCONT(int signo MAKE_ATTR_UNUSED) 710 { 711 WriteOrDie(childExitJob.outPipe, CEJ_RESUME_JOBS); 712 } 713 714 /* 715 * Pass a signal on to all jobs, then resend to ourselves. 716 * We die by the same signal. 717 */ 718 MAKE_ATTR_DEAD static void 719 JobPassSig_int(int signo) 720 { 721 /* Run .INTERRUPT target then exit */ 722 JobInterrupt(true, signo); 723 } 724 725 /* 726 * Pass a signal on to all jobs, then resend to ourselves. 727 * We die by the same signal. 728 */ 729 MAKE_ATTR_DEAD static void 730 JobPassSig_term(int signo) 731 { 732 /* Dont run .INTERRUPT target then exit */ 733 JobInterrupt(false, signo); 734 } 735 736 static void 737 JobPassSig_suspend(int signo) 738 { 739 sigset_t nmask, omask; 740 struct sigaction act; 741 742 /* Suppress job started/continued messages */ 743 make_suspended = true; 744 745 /* Pass the signal onto every job */ 746 JobCondPassSig(signo); 747 748 /* 749 * Send ourselves the signal now we've given the message to everyone 750 * else. Note we block everything else possible while we're getting 751 * the signal. This ensures that all our jobs get continued when we 752 * wake up before we take any other signal. 753 */ 754 sigfillset(&nmask); 755 sigdelset(&nmask, signo); 756 (void)sigprocmask(SIG_SETMASK, &nmask, &omask); 757 758 act.sa_handler = SIG_DFL; 759 sigemptyset(&act.sa_mask); 760 act.sa_flags = 0; 761 (void)sigaction(signo, &act, NULL); 762 763 DEBUG1(JOB, "JobPassSig_suspend passing signal %d to self\n", signo); 764 765 (void)kill(getpid(), signo); 766 767 /* 768 * We've been continued. 769 * 770 * A whole host of signals is going to happen! 771 * SIGCHLD for any processes that actually suspended themselves. 772 * SIGCHLD for any processes that exited while we were asleep. 773 * The SIGCONT that actually caused us to wake up. 774 * 775 * Since we defer passing the SIGCONT on to our children until 776 * the main processing loop, we can be sure that all the SIGCHLD 777 * events will have happened by then - and that the waitpid() will 778 * collect the child 'suspended' events. 779 * For correct sequencing we just need to ensure we process the 780 * waitpid() before passing on the SIGCONT. 781 * 782 * In any case nothing else is needed here. 783 */ 784 785 /* Restore handler and signal mask */ 786 act.sa_handler = JobPassSig_suspend; 787 (void)sigaction(signo, &act, NULL); 788 (void)sigprocmask(SIG_SETMASK, &omask, NULL); 789 } 790 791 static Job * 792 JobFindPid(int pid, enum JobStatus status, bool isJobs) 793 { 794 Job *job; 795 796 for (job = job_table; job < job_table_end; job++) { 797 if (job->status == status && job->pid == pid) 798 return job; 799 } 800 if (DEBUG(JOB) && isJobs) 801 JobTable_Dump("no pid"); 802 return NULL; 803 } 804 805 /* Parse leading '@', '-' and '+', which control the exact execution mode. */ 806 static void 807 ParseCommandFlags(char **pp, CommandFlags *out_cmdFlags) 808 { 809 char *p = *pp; 810 out_cmdFlags->echo = true; 811 out_cmdFlags->ignerr = false; 812 out_cmdFlags->always = false; 813 814 for (;;) { 815 if (*p == '@') 816 out_cmdFlags->echo = DEBUG(LOUD); 817 else if (*p == '-') 818 out_cmdFlags->ignerr = true; 819 else if (*p == '+') 820 out_cmdFlags->always = true; 821 else if (!ch_isspace(*p)) 822 /* Ignore whitespace for compatibility with GNU make */ 823 break; 824 p++; 825 } 826 827 *pp = p; 828 } 829 830 /* Escape a string for a double-quoted string literal in sh, csh and ksh. */ 831 static char * 832 EscapeShellDblQuot(const char *cmd) 833 { 834 size_t i, j; 835 836 /* Worst that could happen is every char needs escaping. */ 837 char *esc = bmake_malloc(strlen(cmd) * 2 + 1); 838 for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) { 839 if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' || 840 cmd[i] == '"') 841 esc[j++] = '\\'; 842 esc[j] = cmd[i]; 843 } 844 esc[j] = '\0'; 845 846 return esc; 847 } 848 849 static void 850 ShellWriter_WriteFmt(ShellWriter *wr, const char *fmt, const char *arg) 851 { 852 DEBUG1(JOB, fmt, arg); 853 854 (void)fprintf(wr->f, fmt, arg); 855 if (wr->f == stdout) 856 (void)fflush(wr->f); 857 } 858 859 static void 860 ShellWriter_WriteLine(ShellWriter *wr, const char *line) 861 { 862 ShellWriter_WriteFmt(wr, "%s\n", line); 863 } 864 865 static void 866 ShellWriter_EchoOff(ShellWriter *wr) 867 { 868 if (shell->hasEchoCtl) 869 ShellWriter_WriteLine(wr, shell->echoOff); 870 } 871 872 static void 873 ShellWriter_EchoCmd(ShellWriter *wr, const char *escCmd) 874 { 875 ShellWriter_WriteFmt(wr, shell->echoTmpl, escCmd); 876 } 877 878 static void 879 ShellWriter_EchoOn(ShellWriter *wr) 880 { 881 if (shell->hasEchoCtl) 882 ShellWriter_WriteLine(wr, shell->echoOn); 883 } 884 885 static void 886 ShellWriter_TraceOn(ShellWriter *wr) 887 { 888 if (!wr->xtraced) { 889 ShellWriter_WriteLine(wr, "set -x"); 890 wr->xtraced = true; 891 } 892 } 893 894 static void 895 ShellWriter_ErrOff(ShellWriter *wr, bool echo) 896 { 897 if (echo) 898 ShellWriter_EchoOff(wr); 899 ShellWriter_WriteLine(wr, shell->errOff); 900 if (echo) 901 ShellWriter_EchoOn(wr); 902 } 903 904 static void 905 ShellWriter_ErrOn(ShellWriter *wr, bool echo) 906 { 907 if (echo) 908 ShellWriter_EchoOff(wr); 909 ShellWriter_WriteLine(wr, shell->errOn); 910 if (echo) 911 ShellWriter_EchoOn(wr); 912 } 913 914 /* 915 * The shell has no built-in error control, so emulate error control by 916 * enclosing each shell command in a template like "{ %s \n } || exit $?" 917 * (configurable per shell). 918 */ 919 static void 920 JobWriteSpecialsEchoCtl(Job *job, ShellWriter *wr, CommandFlags *inout_cmdFlags, 921 const char *escCmd, const char **inout_cmdTemplate) 922 { 923 /* XXX: Why is the whole job modified at this point? */ 924 job->ignerr = true; 925 926 if (job->echo && inout_cmdFlags->echo) { 927 ShellWriter_EchoOff(wr); 928 ShellWriter_EchoCmd(wr, escCmd); 929 930 /* 931 * Leave echoing off so the user doesn't see the commands 932 * for toggling the error checking. 933 */ 934 inout_cmdFlags->echo = false; 935 } 936 *inout_cmdTemplate = shell->runIgnTmpl; 937 938 /* 939 * The template runIgnTmpl already takes care of ignoring errors, 940 * so pretend error checking is still on. 941 * XXX: What effects does this have, and why is it necessary? 942 */ 943 inout_cmdFlags->ignerr = false; 944 } 945 946 static void 947 JobWriteSpecials(Job *job, ShellWriter *wr, const char *escCmd, bool run, 948 CommandFlags *inout_cmdFlags, const char **inout_cmdTemplate) 949 { 950 if (!run) 951 inout_cmdFlags->ignerr = false; 952 else if (shell->hasErrCtl) 953 ShellWriter_ErrOff(wr, job->echo && inout_cmdFlags->echo); 954 else if (shell->runIgnTmpl != NULL && shell->runIgnTmpl[0] != '\0') { 955 JobWriteSpecialsEchoCtl(job, wr, inout_cmdFlags, escCmd, 956 inout_cmdTemplate); 957 } else 958 inout_cmdFlags->ignerr = false; 959 } 960 961 static bool 962 find_make(const char *cmd, const char *make, size_t len) 963 { 964 const char *p; 965 966 for (p = strstr(cmd, make); p != NULL; p = strstr(&p[1], make)) { 967 if (p == cmd || ch_isspace(p[-1])) { 968 if (p[len] == '\0' || ch_isspace(p[len])) { 969 DEBUG4(JOB, "find_make: matched \"%.*s\" in \"%.*s...\"\n", 970 (int)len, p, 971 (int)len + 32, cmd); 972 973 return true; 974 } 975 } 976 } 977 return false; 978 } 979 980 /* 981 * See if the command possibly calls a sub-make by checking 982 * for expansion of ${.MAKE} and possibly ${.MAKE:T}. 983 */ 984 bool 985 MaybeSubMake(const char *cmd) 986 { 987 static char *make, *make_name; 988 static size_t make_len, make_name_len; 989 990 if (make == NULL) { 991 make = Var_Subst("${.MAKE}", SCOPE_GLOBAL, VARE_EVAL); 992 make_len = strlen(make); 993 make_name = strrchr(make, '/'); 994 if (make_name != NULL) { 995 make_name++; 996 make_name_len = strlen(make_name); 997 } else 998 make_name_len = 0; 999 DEBUG1(JOB, "MaybeSubMake: Looking for \"%s\"\n", make); 1000 } 1001 cmd += strspn(cmd, "@ \t+-"); 1002 if (find_make(cmd, make, make_len)) 1003 return true; 1004 if (make_name_len > 0 && find_make(cmd, make_name, make_name_len)) 1005 return true; 1006 return false; 1007 } 1008 1009 /* 1010 * Write a shell command to the job's commands file, to be run later. 1011 * 1012 * If the command starts with '@' and neither the -s nor the -n flag was 1013 * given to make, stick a shell-specific echoOff command in the script. 1014 * 1015 * If the command starts with '-' and the shell has no error control (none 1016 * of the predefined shells has that), ignore errors for the rest of the job. 1017 * 1018 * XXX: Why ignore errors for the entire job? This is documented in the 1019 * manual page, but without giving a rationale. 1020 * 1021 * If the command is just "...", attach all further commands of this job to 1022 * the .END node instead, see Job_Finish. 1023 */ 1024 static void 1025 JobWriteCommand(Job *job, ShellWriter *wr, StringListNode *ln, const char *ucmd) 1026 { 1027 bool run; 1028 1029 CommandFlags cmdFlags; 1030 /* Template for writing a command to the shell file */ 1031 const char *cmdTemplate; 1032 char *xcmd; /* The expanded command */ 1033 char *xcmdStart; 1034 char *escCmd; /* xcmd escaped to be used in double quotes */ 1035 1036 run = GNode_ShouldExecute(job->node); 1037 1038 xcmd = Var_SubstInTarget(ucmd, job->node); 1039 /* TODO: handle errors */ 1040 xcmdStart = xcmd; 1041 1042 if (job->node->flags.doneSubmake == false 1043 && (job->node->type & (OP_MAKE | OP_SUBMAKE)) == 0) { 1044 if (MaybeSubMake(xcmd)) 1045 job->node->type |= OP_SUBMAKE; 1046 } 1047 1048 cmdTemplate = "%s\n"; 1049 1050 ParseCommandFlags(&xcmd, &cmdFlags); 1051 1052 /* The '+' command flag overrides the -n or -N options. */ 1053 if (cmdFlags.always && !run) { 1054 /* 1055 * We're not actually executing anything... 1056 * but this one needs to be - use compat mode just for it. 1057 */ 1058 (void)Compat_RunCommand(ucmd, job->node, ln); 1059 free(xcmdStart); 1060 return; 1061 } 1062 1063 /* 1064 * If the shell doesn't have error control, the alternate echoing 1065 * will be done (to avoid showing additional error checking code) 1066 * and this needs some characters escaped. 1067 */ 1068 escCmd = shell->hasErrCtl ? NULL : EscapeShellDblQuot(xcmd); 1069 1070 if (!cmdFlags.echo) { 1071 if (job->echo && run && shell->hasEchoCtl) 1072 ShellWriter_EchoOff(wr); 1073 else if (shell->hasErrCtl) 1074 cmdFlags.echo = true; 1075 } 1076 1077 if (cmdFlags.ignerr) { 1078 JobWriteSpecials(job, wr, escCmd, run, &cmdFlags, &cmdTemplate); 1079 } else { 1080 1081 /* 1082 * If errors are being checked and the shell doesn't have 1083 * error control but does supply an runChkTmpl template, then 1084 * set up commands to run through it. 1085 */ 1086 1087 if (!shell->hasErrCtl && shell->runChkTmpl != NULL && 1088 shell->runChkTmpl[0] != '\0') { 1089 if (job->echo && cmdFlags.echo) { 1090 ShellWriter_EchoOff(wr); 1091 ShellWriter_EchoCmd(wr, escCmd); 1092 cmdFlags.echo = false; 1093 } 1094 /* 1095 * If it's a comment line or blank, avoid the possible 1096 * syntax error generated by "{\n} || exit $?". 1097 */ 1098 cmdTemplate = escCmd[0] == shell->commentChar || 1099 escCmd[0] == '\0' 1100 ? shell->runIgnTmpl 1101 : shell->runChkTmpl; 1102 cmdFlags.ignerr = false; 1103 } 1104 } 1105 1106 if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0) 1107 ShellWriter_TraceOn(wr); 1108 1109 ShellWriter_WriteFmt(wr, cmdTemplate, xcmd); 1110 free(xcmdStart); 1111 free(escCmd); 1112 1113 if (cmdFlags.ignerr) 1114 ShellWriter_ErrOn(wr, cmdFlags.echo && job->echo); 1115 1116 if (!cmdFlags.echo) 1117 ShellWriter_EchoOn(wr); 1118 } 1119 1120 /* 1121 * Write all commands to the shell file that is later executed. 1122 * 1123 * The special command "..." stops writing and saves the remaining commands 1124 * to be executed later, when the target '.END' is made. 1125 * 1126 * Return whether at least one command was written to the shell file. 1127 */ 1128 static bool 1129 JobWriteCommands(Job *job) 1130 { 1131 StringListNode *ln; 1132 bool seen = false; 1133 ShellWriter wr; 1134 1135 wr.f = job->cmdFILE; 1136 wr.xtraced = false; 1137 1138 for (ln = job->node->commands.first; ln != NULL; ln = ln->next) { 1139 const char *cmd = ln->datum; 1140 1141 if (strcmp(cmd, "...") == 0) { 1142 job->node->type |= OP_SAVE_CMDS; 1143 job->tailCmds = ln->next; 1144 break; 1145 } 1146 1147 JobWriteCommand(job, &wr, ln, ln->datum); 1148 seen = true; 1149 } 1150 job->node->flags.doneSubmake = true; 1151 1152 return seen; 1153 } 1154 1155 /* 1156 * Save the delayed commands (those after '...'), to be executed later in 1157 * the '.END' node, when everything else is done. 1158 */ 1159 static void 1160 JobSaveCommands(Job *job) 1161 { 1162 StringListNode *ln; 1163 1164 for (ln = job->tailCmds; ln != NULL; ln = ln->next) { 1165 const char *cmd = ln->datum; 1166 char *expanded_cmd; 1167 /* 1168 * XXX: This Var_Subst is only intended to expand the dynamic 1169 * variables such as .TARGET, .IMPSRC. It is not intended to 1170 * expand the other variables as well; see deptgt-end.mk. 1171 */ 1172 expanded_cmd = Var_SubstInTarget(cmd, job->node); 1173 /* TODO: handle errors */ 1174 Lst_Append(&Targ_GetEndNode()->commands, expanded_cmd); 1175 Parse_RegisterCommand(expanded_cmd); 1176 } 1177 } 1178 1179 1180 /* Close both input and output pipes when a job is finished. */ 1181 static void 1182 JobClosePipes(Job *job) 1183 { 1184 clearfd(job); 1185 (void)close(job->outPipe); 1186 job->outPipe = -1; 1187 1188 CollectOutput(job, true); 1189 (void)close(job->inPipe); 1190 job->inPipe = -1; 1191 } 1192 1193 static void 1194 DebugFailedJob(const Job *job) 1195 { 1196 const StringListNode *ln; 1197 1198 if (!DEBUG(ERROR)) 1199 return; 1200 1201 debug_printf("\n"); 1202 debug_printf("*** Failed target: %s\n", job->node->name); 1203 debug_printf("*** In directory: %s\n", curdir); 1204 debug_printf("*** Failed commands:\n"); 1205 for (ln = job->node->commands.first; ln != NULL; ln = ln->next) { 1206 const char *cmd = ln->datum; 1207 debug_printf("\t%s\n", cmd); 1208 1209 if (strchr(cmd, '$') != NULL) { 1210 char *xcmd = Var_Subst(cmd, job->node, VARE_EVAL); 1211 debug_printf("\t=> %s\n", xcmd); 1212 free(xcmd); 1213 } 1214 } 1215 } 1216 1217 static void 1218 JobFinishDoneExitedError(Job *job, int *inout_status) 1219 { 1220 SwitchOutputTo(job->node); 1221 #ifdef USE_META 1222 if (useMeta) { 1223 meta_job_error(job, job->node, 1224 job->ignerr, WEXITSTATUS(*inout_status)); 1225 } 1226 #endif 1227 if (!shouldDieQuietly(job->node, -1)) { 1228 DebugFailedJob(job); 1229 (void)printf("*** [%s] Error code %d%s\n", 1230 job->node->name, WEXITSTATUS(*inout_status), 1231 job->ignerr ? " (ignored)" : ""); 1232 } 1233 1234 if (job->ignerr) 1235 *inout_status = 0; 1236 else { 1237 if (deleteOnError) 1238 JobDeleteTarget(job->node); 1239 PrintOnError(job->node, "\n"); 1240 } 1241 } 1242 1243 static void 1244 JobFinishDoneExited(Job *job, int *inout_status) 1245 { 1246 DEBUG2(JOB, "Target %s, pid %d exited\n", 1247 job->node->name, job->pid); 1248 1249 if (WEXITSTATUS(*inout_status) != 0) 1250 JobFinishDoneExitedError(job, inout_status); 1251 else if (DEBUG(JOB)) { 1252 SwitchOutputTo(job->node); 1253 (void)printf("Target %s, pid %d exited successfully\n", 1254 job->node->name, job->pid); 1255 } 1256 } 1257 1258 static void 1259 JobFinishDoneSignaled(Job *job, int status) 1260 { 1261 SwitchOutputTo(job->node); 1262 DebugFailedJob(job); 1263 (void)printf("*** [%s] Signal %d\n", job->node->name, WTERMSIG(status)); 1264 if (deleteOnError) 1265 JobDeleteTarget(job->node); 1266 } 1267 1268 static void 1269 JobFinishDone(Job *job, int *inout_status) 1270 { 1271 if (WIFEXITED(*inout_status)) 1272 JobFinishDoneExited(job, inout_status); 1273 else 1274 JobFinishDoneSignaled(job, *inout_status); 1275 1276 (void)fflush(stdout); 1277 } 1278 1279 /* 1280 * Finish the job, add deferred commands to the .END node, mark the job as 1281 * free, update parent nodes and start new jobs as available/necessary. 1282 */ 1283 static void 1284 JobFinish(Job *job, int status) 1285 { 1286 bool done, return_job_token; 1287 1288 DEBUG3(JOB, "JobFinish: target %s, pid %d, status %#x\n", 1289 job->node->name, job->pid, status); 1290 1291 if ((WIFEXITED(status) && WEXITSTATUS(status) != 0 && !job->ignerr) || 1292 WIFSIGNALED(status)) { 1293 /* Finished because of an error. */ 1294 1295 JobClosePipes(job); 1296 if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1297 if (fclose(job->cmdFILE) != 0) 1298 Punt("Cannot write shell script for \"%s\": %s", 1299 job->node->name, strerror(errno)); 1300 job->cmdFILE = NULL; 1301 } 1302 done = true; 1303 1304 } else if (WIFEXITED(status)) { 1305 /* 1306 * Deal with ignored errors in -B mode. We need to print a 1307 * message telling of the ignored error as well as to run 1308 * the next command. 1309 */ 1310 done = WEXITSTATUS(status) != 0; 1311 1312 JobClosePipes(job); 1313 1314 } else { 1315 /* No need to close things down or anything. */ 1316 done = false; 1317 } 1318 1319 if (done) 1320 JobFinishDone(job, &status); 1321 1322 #ifdef USE_META 1323 if (useMeta) { 1324 int meta_status = meta_job_finish(job); 1325 if (meta_status != 0 && status == 0) 1326 status = meta_status; 1327 } 1328 #endif 1329 1330 return_job_token = false; 1331 1332 Trace_Log(JOBEND, job); 1333 if (!job->special) { 1334 if (status != 0 || 1335 aborting == ABORT_ERROR || aborting == ABORT_INTERRUPT) 1336 return_job_token = true; 1337 } 1338 1339 if (aborting != ABORT_ERROR && aborting != ABORT_INTERRUPT && 1340 status == 0) { 1341 JobSaveCommands(job); 1342 job->node->made = MADE; 1343 if (!job->special) 1344 return_job_token = true; 1345 Make_Update(job->node); 1346 job->status = JOB_ST_FREE; 1347 } else if (status != 0) { 1348 job_errors++; 1349 job->status = JOB_ST_FREE; 1350 } 1351 1352 if (job_errors > 0 && !opts.keepgoing && aborting != ABORT_INTERRUPT) { 1353 /* Prevent more jobs from getting started. */ 1354 aborting = ABORT_ERROR; 1355 } 1356 1357 if (return_job_token) 1358 TokenPool_Return(); 1359 1360 if (aborting == ABORT_ERROR && jobTokensRunning == 0) { 1361 if (shouldDieQuietly(NULL, -1)) 1362 exit(2); 1363 Fatal("%d error%s", job_errors, job_errors == 1 ? "" : "s"); 1364 } 1365 } 1366 1367 static void 1368 TouchRegular(GNode *gn) 1369 { 1370 const char *file = GNode_Path(gn); 1371 struct utimbuf times; 1372 int fd; 1373 char c; 1374 1375 times.actime = now; 1376 times.modtime = now; 1377 if (utime(file, ×) >= 0) 1378 return; 1379 1380 fd = open(file, O_RDWR | O_CREAT, 0666); 1381 if (fd < 0) { 1382 (void)fprintf(stderr, "*** couldn't touch %s: %s\n", 1383 file, strerror(errno)); 1384 (void)fflush(stderr); 1385 return; /* XXX: What about propagating the error? */ 1386 } 1387 1388 /* 1389 * Last resort: update the file's time stamps in the traditional way. 1390 * XXX: This doesn't work for empty files, which are sometimes used 1391 * as marker files. 1392 */ 1393 if (read(fd, &c, 1) == 1) { 1394 (void)lseek(fd, 0, SEEK_SET); 1395 while (write(fd, &c, 1) == -1 && errno == EAGAIN) 1396 continue; 1397 } 1398 (void)close(fd); /* XXX: What about propagating the error? */ 1399 } 1400 1401 /* 1402 * Touch the given target. Called by Job_Make when the -t flag was given. 1403 * 1404 * The modification date of the file is changed. 1405 * If the file did not exist, it is created. 1406 */ 1407 void 1408 Job_Touch(GNode *gn, bool echo) 1409 { 1410 if (gn->type & 1411 (OP_JOIN | OP_USE | OP_USEBEFORE | OP_EXEC | OP_OPTIONAL | 1412 OP_SPECIAL | OP_PHONY)) { 1413 /* 1414 * These are "virtual" targets and should not really be 1415 * created. 1416 */ 1417 return; 1418 } 1419 1420 if (echo || !GNode_ShouldExecute(gn)) { 1421 (void)fprintf(stdout, "touch %s\n", gn->name); 1422 (void)fflush(stdout); 1423 } 1424 1425 if (!GNode_ShouldExecute(gn)) 1426 return; 1427 1428 if (gn->type & OP_ARCHV) 1429 Arch_Touch(gn); 1430 else if (gn->type & OP_LIB) 1431 Arch_TouchLib(gn); 1432 else 1433 TouchRegular(gn); 1434 } 1435 1436 /* 1437 * Make sure the given node has all the commands it needs. 1438 * 1439 * The node will have commands from the .DEFAULT rule added to it if it 1440 * needs them. 1441 * 1442 * Input: 1443 * gn The target whose commands need verifying 1444 * abortProc Function to abort with message 1445 * 1446 * Results: 1447 * true if the commands are ok. 1448 */ 1449 bool 1450 Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) 1451 { 1452 if (GNode_IsTarget(gn)) 1453 return true; 1454 if (!Lst_IsEmpty(&gn->commands)) 1455 return true; 1456 if ((gn->type & OP_LIB) && !Lst_IsEmpty(&gn->children)) 1457 return true; 1458 1459 /* 1460 * No commands. Look for .DEFAULT rule from which we might infer 1461 * commands. 1462 */ 1463 if (defaultNode != NULL && !Lst_IsEmpty(&defaultNode->commands) && 1464 !(gn->type & OP_SPECIAL)) { 1465 /* 1466 * The traditional Make only looks for a .DEFAULT if the node 1467 * was never the target of an operator, so that's what we do 1468 * too. 1469 * 1470 * The .DEFAULT node acts like a transformation rule, in that 1471 * gn also inherits any attributes or sources attached to 1472 * .DEFAULT itself. 1473 */ 1474 Make_HandleUse(defaultNode, gn); 1475 Var_Set(gn, IMPSRC, GNode_VarTarget(gn)); 1476 return true; 1477 } 1478 1479 Dir_UpdateMTime(gn, false); 1480 if (gn->mtime != 0 || (gn->type & OP_SPECIAL)) 1481 return true; 1482 1483 /* 1484 * The node wasn't the target of an operator. We have no .DEFAULT 1485 * rule to go on and the target doesn't already exist. There's 1486 * nothing more we can do for this branch. If the -k flag wasn't 1487 * given, we stop in our tracks, otherwise we just don't update 1488 * this node's parents so they never get examined. 1489 */ 1490 1491 if (gn->flags.fromDepend) { 1492 if (!Job_RunTarget(".STALE", gn->fname)) 1493 fprintf(stdout, 1494 "%s: %s:%u: ignoring stale %s for %s\n", 1495 progname, gn->fname, gn->lineno, makeDependfile, 1496 gn->name); 1497 return true; 1498 } 1499 1500 if (gn->type & OP_OPTIONAL) { 1501 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n", 1502 progname, gn->name, "ignored"); 1503 (void)fflush(stdout); 1504 return true; 1505 } 1506 1507 if (opts.keepgoing) { 1508 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n", 1509 progname, gn->name, "continuing"); 1510 (void)fflush(stdout); 1511 return false; 1512 } 1513 1514 abortProc("don't know how to make %s. Stop", gn->name); 1515 return false; 1516 } 1517 1518 /* 1519 * Execute the shell for the given job. 1520 * 1521 * See Job_CatchOutput for handling the output of the shell. 1522 */ 1523 static void 1524 JobExec(Job *job, char **argv) 1525 { 1526 int cpid; /* ID of new child */ 1527 sigset_t mask; 1528 1529 if (DEBUG(JOB)) { 1530 int i; 1531 1532 debug_printf("Running %s\n", job->node->name); 1533 debug_printf("\tCommand:"); 1534 for (i = 0; argv[i] != NULL; i++) { 1535 debug_printf(" %s", argv[i]); 1536 } 1537 debug_printf("\n"); 1538 } 1539 1540 /* 1541 * Some jobs produce no output, and it's disconcerting to have 1542 * no feedback of their running (since they produce no output, the 1543 * banner with their name in it never appears). This is an attempt to 1544 * provide that feedback, even if nothing follows it. 1545 */ 1546 if (job->echo) 1547 SwitchOutputTo(job->node); 1548 1549 /* No interruptions until this job is in the jobs table. */ 1550 JobsTable_Lock(&mask); 1551 1552 /* Pre-emptively mark job running, pid still zero though */ 1553 job->status = JOB_ST_RUNNING; 1554 1555 Var_ReexportVars(job->node); 1556 Var_ExportStackTrace(job->node->name, NULL); 1557 1558 cpid = FORK_FUNCTION(); 1559 if (cpid == -1) 1560 Punt("fork: %s", strerror(errno)); 1561 1562 if (cpid == 0) { 1563 /* Child */ 1564 sigset_t tmask; 1565 1566 #ifdef USE_META 1567 if (useMeta) 1568 meta_job_child(job); 1569 #endif 1570 /* 1571 * Reset all signal handlers; this is necessary because we 1572 * also need to unblock signals before we exec(2). 1573 */ 1574 JobSigReset(); 1575 1576 sigemptyset(&tmask); 1577 JobsTable_Unlock(&tmask); 1578 1579 if (dup2(fileno(job->cmdFILE), STDIN_FILENO) == -1) 1580 execDie("dup2", "job->cmdFILE"); 1581 if (fcntl(STDIN_FILENO, F_SETFD, 0) == -1) 1582 execDie("clear close-on-exec", "stdin"); 1583 if (lseek(STDIN_FILENO, 0, SEEK_SET) == -1) 1584 execDie("lseek to 0", "stdin"); 1585 1586 if (job->node->type & (OP_MAKE | OP_SUBMAKE)) { 1587 /* Pass job token pipe to submakes. */ 1588 if (fcntl(tokenPoolJob.inPipe, F_SETFD, 0) == -1) 1589 execDie("clear close-on-exec", 1590 "tokenPoolJob.inPipe"); 1591 if (fcntl(tokenPoolJob.outPipe, F_SETFD, 0) == -1) 1592 execDie("clear close-on-exec", 1593 "tokenPoolJob.outPipe"); 1594 } 1595 1596 if (dup2(job->outPipe, STDOUT_FILENO) == -1) 1597 execDie("dup2", "job->outPipe"); 1598 1599 /* 1600 * The output channels are marked close on exec. This bit 1601 * was duplicated by dup2 (on some systems), so we have 1602 * to clear it before routing the shell's error output to 1603 * the same place as its standard output. 1604 */ 1605 if (fcntl(STDOUT_FILENO, F_SETFD, 0) == -1) 1606 execDie("clear close-on-exec", "stdout"); 1607 if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) 1608 execDie("dup2", "1, 2"); 1609 1610 /* 1611 * We want to switch the child into a different process 1612 * family so we can kill it and all its descendants in 1613 * one fell swoop, by killing its process family, but not 1614 * commit suicide. 1615 */ 1616 #if defined(MAKE_NATIVE) || defined(HAVE_SETPGID) 1617 # if defined(SYSV) 1618 /* XXX: dsl - I'm sure this should be setpgrp()... */ 1619 (void)setsid(); 1620 # else 1621 (void)setpgid(0, getpid()); 1622 # endif 1623 #endif 1624 1625 (void)execv(shellPath, argv); 1626 execDie("exec", shellPath); 1627 } 1628 1629 /* Parent, continuing after the child exec */ 1630 job->pid = cpid; 1631 1632 Trace_Log(JOBSTART, job); 1633 1634 #ifdef USE_META 1635 if (useMeta) 1636 meta_job_parent(job, cpid); 1637 #endif 1638 1639 job->outBufLen = 0; 1640 1641 watchfd(job); 1642 1643 if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1644 if (fclose(job->cmdFILE) != 0) 1645 Punt("Cannot write shell script for \"%s\": %s", 1646 job->node->name, strerror(errno)); 1647 job->cmdFILE = NULL; 1648 } 1649 1650 if (DEBUG(JOB)) { 1651 debug_printf( 1652 "JobExec: target %s, pid %d added to jobs table\n", 1653 job->node->name, job->pid); 1654 JobTable_Dump("job started"); 1655 } 1656 JobsTable_Unlock(&mask); 1657 } 1658 1659 static void 1660 BuildArgv(Job *job, char **argv) 1661 { 1662 int argc; 1663 static char args[10]; 1664 1665 argv[0] = UNCONST(shellName); 1666 argc = 1; 1667 1668 if ((shell->errFlag != NULL && shell->errFlag[0] != '-') || 1669 (shell->echoFlag != NULL && shell->echoFlag[0] != '-')) { 1670 /* 1671 * At least one of the flags doesn't have a minus before it, 1672 * so merge them together. Have to do this because the Bourne 1673 * shell thinks its second argument is a file to source. 1674 * Grrrr. Note the ten-character limitation on the combined 1675 * arguments. 1676 * 1677 * TODO: Research until when the above comments were 1678 * practically relevant. 1679 */ 1680 (void)snprintf(args, sizeof args, "-%s%s", 1681 !job->ignerr && shell->errFlag != NULL 1682 ? shell->errFlag : "", 1683 job->echo && shell->echoFlag != NULL 1684 ? shell->echoFlag : ""); 1685 if (args[1] != '\0') { 1686 argv[argc] = args; 1687 argc++; 1688 } 1689 } else { 1690 if (!job->ignerr && shell->errFlag != NULL) { 1691 argv[argc] = UNCONST(shell->errFlag); 1692 argc++; 1693 } 1694 if (job->echo && shell->echoFlag != NULL) { 1695 argv[argc] = UNCONST(shell->echoFlag); 1696 argc++; 1697 } 1698 } 1699 argv[argc] = NULL; 1700 } 1701 1702 static void 1703 JobWriteShellCommands(Job *job, GNode *gn, bool *out_run) 1704 { 1705 char fname[MAXPATHLEN]; 1706 int fd; 1707 1708 fd = Job_TempFile(NULL, fname, sizeof fname); 1709 1710 job->cmdFILE = fdopen(fd, "w+"); 1711 if (job->cmdFILE == NULL) 1712 Punt("Could not fdopen %s", fname); 1713 1714 (void)fcntl(fd, F_SETFD, FD_CLOEXEC); 1715 1716 #ifdef USE_META 1717 if (useMeta) { 1718 meta_job_start(job, gn); 1719 if (gn->type & OP_SILENT) /* might have changed */ 1720 job->echo = false; 1721 } 1722 #endif 1723 1724 *out_run = JobWriteCommands(job); 1725 } 1726 1727 void 1728 Job_Make(GNode *gn) 1729 { 1730 Job *job; 1731 char *argv[10]; 1732 bool cmdsOK; /* true if the nodes commands were all right */ 1733 bool run; 1734 1735 for (job = job_table; job < job_table_end; job++) { 1736 if (job->status == JOB_ST_FREE) 1737 break; 1738 } 1739 if (job >= job_table_end) 1740 Punt("Job_Make no job slots vacant"); 1741 1742 memset(job, 0, sizeof *job); 1743 job->node = gn; 1744 job->tailCmds = NULL; 1745 job->status = JOB_ST_SET_UP; 1746 1747 job->special = (gn->type & OP_SPECIAL) != OP_NONE; 1748 job->ignerr = opts.ignoreErrors || gn->type & OP_IGNORE; 1749 job->echo = !(opts.silent || gn->type & OP_SILENT); 1750 1751 /* 1752 * Check the commands now so any attributes from .DEFAULT have a 1753 * chance to migrate to the node. 1754 */ 1755 cmdsOK = Job_CheckCommands(gn, Error); 1756 1757 job->inPollfd = NULL; 1758 1759 if (Lst_IsEmpty(&gn->commands)) { 1760 job->cmdFILE = stdout; 1761 run = false; 1762 1763 if (!cmdsOK) { 1764 PrintOnError(gn, "\n"); 1765 DieHorribly(); 1766 } 1767 } else if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) || 1768 (!opts.noExecute && !opts.touch)) { 1769 int parseErrorsBefore; 1770 1771 if (!cmdsOK) { 1772 PrintOnError(gn, "\n"); 1773 DieHorribly(); 1774 } 1775 1776 parseErrorsBefore = parseErrors; 1777 JobWriteShellCommands(job, gn, &run); 1778 if (parseErrors != parseErrorsBefore) 1779 run = false; 1780 (void)fflush(job->cmdFILE); 1781 } else if (!GNode_ShouldExecute(gn)) { 1782 SwitchOutputTo(gn); 1783 job->cmdFILE = stdout; 1784 if (cmdsOK) 1785 JobWriteCommands(job); 1786 run = false; 1787 (void)fflush(job->cmdFILE); 1788 } else { 1789 Job_Touch(gn, job->echo); 1790 run = false; 1791 } 1792 1793 if (!run) { 1794 if (!job->special) 1795 TokenPool_Return(); 1796 1797 if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1798 (void)fclose(job->cmdFILE); 1799 job->cmdFILE = NULL; 1800 } 1801 1802 if (cmdsOK && aborting == ABORT_NONE) { 1803 JobSaveCommands(job); 1804 job->node->made = MADE; 1805 Make_Update(job->node); 1806 } 1807 job->status = JOB_ST_FREE; 1808 return; 1809 } 1810 1811 BuildArgv(job, argv); 1812 JobCreatePipe(job, 3); 1813 JobExec(job, argv); 1814 } 1815 1816 /* 1817 * If the shell has an output filter (which only csh and ksh have by default), 1818 * print the output of the child process, skipping the noPrint text of the 1819 * shell. 1820 * 1821 * Return the part of the output that the calling function needs to output by 1822 * itself. 1823 */ 1824 static const char * 1825 PrintFilteredOutput(Job *job, size_t len) 1826 { 1827 const char *p = job->outBuf, *ep, *endp; 1828 1829 if (shell->noPrint == NULL || shell->noPrint[0] == '\0') 1830 return p; 1831 1832 endp = p + len; 1833 while ((ep = strstr(p, shell->noPrint)) != NULL && ep < endp) { 1834 if (ep > p) { 1835 if (!opts.silent) 1836 SwitchOutputTo(job->node); 1837 (void)fwrite(p, 1, (size_t)(ep - p), stdout); 1838 (void)fflush(stdout); 1839 } 1840 p = ep + shell->noPrintLen; 1841 if (p == endp) 1842 break; 1843 p++; /* skip over the (XXX: assumed) newline */ 1844 cpp_skip_whitespace(&p); 1845 } 1846 return p; 1847 } 1848 1849 /* 1850 * Collect output from the job. Print any complete lines. 1851 * 1852 * In the output of the shell, the 'noPrint' lines are removed. If the 1853 * command is not alone on the line (the character after it is not \0 or 1854 * \n), we do print whatever follows it. 1855 * 1856 * If finish is true, collect all remaining output for the job. 1857 */ 1858 static void 1859 CollectOutput(Job *job, bool finish) 1860 { 1861 const char *p; 1862 size_t nr; /* number of bytes read */ 1863 size_t i; /* auxiliary index into outBuf */ 1864 size_t max; /* limit for i (end of current data) */ 1865 1866 again: 1867 nr = (size_t)read(job->inPipe, job->outBuf + job->outBufLen, 1868 JOB_BUFSIZE - job->outBufLen); 1869 if (nr == (size_t)-1) { 1870 if (errno == EAGAIN) 1871 return; 1872 if (DEBUG(JOB)) 1873 perror("CollectOutput(piperead)"); 1874 nr = 0; 1875 } 1876 1877 if (nr == 0) 1878 finish = false; /* stop looping */ 1879 1880 if (nr == 0 && job->outBufLen > 0) { 1881 job->outBuf[job->outBufLen] = '\n'; 1882 nr = 1; 1883 } 1884 1885 max = job->outBufLen + nr; 1886 job->outBuf[max] = '\0'; 1887 1888 for (i = job->outBufLen; i < max; i++) 1889 if (job->outBuf[i] == '\0') 1890 job->outBuf[i] = ' '; 1891 1892 for (i = max; i > job->outBufLen; i--) 1893 if (job->outBuf[i - 1] == '\n') 1894 break; 1895 1896 if (i == job->outBufLen) { 1897 job->outBufLen = max; 1898 if (max < JOB_BUFSIZE) 1899 goto unfinished_line; 1900 i = max; 1901 } 1902 1903 p = PrintFilteredOutput(job, i); 1904 if (*p != '\0') { 1905 if (!opts.silent) 1906 SwitchOutputTo(job->node); 1907 #ifdef USE_META 1908 if (useMeta) 1909 meta_job_output(job, p, i < max ? i : max); 1910 #endif 1911 (void)fwrite(p, 1, (size_t)(job->outBuf + i - p), stdout); 1912 (void)fflush(stdout); 1913 } 1914 memmove(job->outBuf, job->outBuf + i, max - i); 1915 job->outBufLen = max - i; 1916 1917 unfinished_line: 1918 if (finish) 1919 goto again; 1920 } 1921 1922 static void 1923 JobRun(GNode *target) 1924 { 1925 /* Don't let these special jobs overlap with other unrelated jobs. */ 1926 Compat_Make(target, target); 1927 if (GNode_IsError(target)) { 1928 PrintOnError(target, "\n\nStop.\n"); 1929 exit(1); 1930 } 1931 } 1932 1933 void 1934 Job_CatchChildren(void) 1935 { 1936 int pid; 1937 int status; 1938 1939 if (jobTokensRunning == 0) 1940 return; 1941 if (caught_sigchld == 0) 1942 return; 1943 caught_sigchld = 0; 1944 1945 while ((pid = waitpid((pid_t)-1, &status, WNOHANG | WUNTRACED)) > 0) { 1946 DEBUG2(JOB, 1947 "Process with pid %d exited/stopped with status %#x.\n", 1948 pid, status); 1949 JobReapChild(pid, status, true); 1950 } 1951 } 1952 1953 /* 1954 * It is possible that wait[pid]() was called from elsewhere, 1955 * this lets us reap jobs regardless. 1956 */ 1957 void 1958 JobReapChild(pid_t pid, int status, bool isJobs) 1959 { 1960 Job *job; 1961 1962 if (jobTokensRunning == 0) 1963 return; 1964 1965 job = JobFindPid(pid, JOB_ST_RUNNING, isJobs); 1966 if (job == NULL) { 1967 if (isJobs && !lurking_children) 1968 Error("Child with pid %d and status %#x not in table?", 1969 pid, status); 1970 return; 1971 } 1972 1973 if (WIFSTOPPED(status)) { 1974 DEBUG2(JOB, "Process for target %s, pid %d stopped\n", 1975 job->node->name, job->pid); 1976 if (!make_suspended) { 1977 switch (WSTOPSIG(status)) { 1978 case SIGTSTP: 1979 (void)printf("*** [%s] Suspended\n", 1980 job->node->name); 1981 break; 1982 case SIGSTOP: 1983 (void)printf("*** [%s] Stopped\n", 1984 job->node->name); 1985 break; 1986 default: 1987 (void)printf("*** [%s] Stopped -- signal %d\n", 1988 job->node->name, WSTOPSIG(status)); 1989 } 1990 job->suspended = true; 1991 } 1992 (void)fflush(stdout); 1993 return; 1994 } 1995 1996 job->status = JOB_ST_FINISHED; 1997 job->exit_status = status; 1998 if (WIFEXITED(status)) 1999 job->node->exit_status = WEXITSTATUS(status); 2000 2001 JobFinish(job, status); 2002 } 2003 2004 static void 2005 Job_Continue(Job *job) 2006 { 2007 DEBUG1(JOB, "Continuing pid %d\n", job->pid); 2008 if (job->suspended) { 2009 (void)printf("*** [%s] Continued\n", job->node->name); 2010 (void)fflush(stdout); 2011 job->suspended = false; 2012 } 2013 if (KILLPG(job->pid, SIGCONT) != 0) 2014 DEBUG1(JOB, "Failed to send SIGCONT to pid %d\n", job->pid); 2015 } 2016 2017 static void 2018 ContinueJobs(void) 2019 { 2020 Job *job; 2021 2022 for (job = job_table; job < job_table_end; job++) { 2023 if (job->status == JOB_ST_RUNNING && 2024 (make_suspended || job->suspended)) 2025 Job_Continue(job); 2026 else if (job->status == JOB_ST_FINISHED) 2027 JobFinish(job, job->exit_status); 2028 } 2029 make_suspended = false; 2030 } 2031 2032 void 2033 Job_CatchOutput(void) 2034 { 2035 int nready; 2036 Job *job; 2037 unsigned i; 2038 2039 (void)fflush(stdout); 2040 2041 do { 2042 /* Maybe skip the job token pipe. */ 2043 nfds_t skip = wantToken ? 0 : 1; 2044 nready = poll(fds + skip, fdsLen - skip, -1); 2045 } while (nready < 0 && errno == EINTR); 2046 2047 if (nready < 0) 2048 Punt("poll: %s", strerror(errno)); 2049 2050 if (nready > 0 && childExitJob.inPollfd->revents & POLLIN) { 2051 char token; 2052 ssize_t count = read(childExitJob.inPipe, &token, 1); 2053 if (count != 1) 2054 Punt("childExitJob.read: %s", 2055 count == 0 ? "EOF" : strerror(errno)); 2056 if (token == CEJ_RESUME_JOBS) 2057 ContinueJobs(); 2058 nready--; 2059 } 2060 2061 Job_CatchChildren(); 2062 if (nready == 0) 2063 return; 2064 2065 for (i = npseudojobs * nfds_per_job(); i < fdsLen; i++) { 2066 if (fds[i].revents == 0) 2067 continue; 2068 job = jobByFdIndex[i]; 2069 if (job->status == JOB_ST_RUNNING) 2070 CollectOutput(job, false); 2071 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV) 2072 /* 2073 * With meta mode, we may have activity on the job's filemon 2074 * descriptor too, which at the moment is any pollfd other 2075 * than job->inPollfd. 2076 */ 2077 if (useMeta && job->inPollfd != &fds[i]) { 2078 if (meta_job_event(job) <= 0) 2079 fds[i].events = 0; /* never mind */ 2080 } 2081 #endif 2082 if (--nready == 0) 2083 return; 2084 } 2085 } 2086 2087 static void 2088 InitShellNameAndPath(void) 2089 { 2090 shellName = shell->name; 2091 2092 #ifdef DEFSHELL_CUSTOM 2093 if (shellName[0] == '/') { 2094 shellPath = bmake_strdup(shellName); 2095 shellName = str_basename(shellPath); 2096 return; 2097 } 2098 #endif 2099 2100 shellPath = str_concat3(_PATH_DEFSHELLDIR, "/", shellName); 2101 } 2102 2103 void 2104 Shell_Init(void) 2105 { 2106 if (shellPath == NULL) 2107 InitShellNameAndPath(); 2108 2109 Var_SetWithFlags(SCOPE_CMDLINE, ".SHELL", shellPath, 2110 VAR_SET_INTERNAL|VAR_SET_READONLY); 2111 if (shell->errFlag == NULL) 2112 shell->errFlag = ""; 2113 if (shell->echoFlag == NULL) 2114 shell->echoFlag = ""; 2115 if (shell->hasErrCtl && shell->errFlag[0] != '\0') { 2116 if (shellErrFlag != NULL && 2117 strcmp(shell->errFlag, &shellErrFlag[1]) != 0) { 2118 free(shellErrFlag); 2119 shellErrFlag = NULL; 2120 } 2121 if (shellErrFlag == NULL) 2122 shellErrFlag = str_concat2("-", shell->errFlag); 2123 } else if (shellErrFlag != NULL) { 2124 free(shellErrFlag); 2125 shellErrFlag = NULL; 2126 } 2127 } 2128 2129 /* Return the shell string literal that results in a newline character. */ 2130 const char * 2131 Shell_GetNewline(void) 2132 { 2133 return shell->newline; 2134 } 2135 2136 void 2137 Job_SetPrefix(void) 2138 { 2139 if (targPrefix != NULL) 2140 free(targPrefix); 2141 else if (!Var_Exists(SCOPE_GLOBAL, ".MAKE.JOB.PREFIX")) 2142 Global_Set(".MAKE.JOB.PREFIX", "---"); 2143 2144 targPrefix = Var_Subst("${.MAKE.JOB.PREFIX}", 2145 SCOPE_GLOBAL, VARE_EVAL); 2146 /* TODO: handle errors */ 2147 } 2148 2149 static void 2150 AddSig(int sig, SignalProc handler) 2151 { 2152 if (bmake_signal(sig, SIG_IGN) != SIG_IGN) { 2153 sigaddset(&caught_signals, sig); 2154 (void)bmake_signal(sig, handler); 2155 } 2156 } 2157 2158 void 2159 Job_Init(void) 2160 { 2161 Job_SetPrefix(); 2162 2163 job_table = bmake_malloc((size_t)opts.maxJobs * sizeof *job_table); 2164 memset(job_table, 0, (size_t)opts.maxJobs * sizeof *job_table); 2165 job_table_end = job_table + opts.maxJobs; 2166 wantToken = false; 2167 caught_sigchld = 0; 2168 2169 aborting = ABORT_NONE; 2170 job_errors = 0; 2171 2172 /* 2173 * There is a non-zero chance that we already have children, 2174 * e.g. after 'make -f- <<EOF'. 2175 * Since their termination causes a 'Child (pid) not in table' 2176 * message, Collect the status of any that are already dead, and 2177 * suppress the error message if there are any undead ones. 2178 */ 2179 for (;;) { 2180 int rval, status; 2181 rval = waitpid((pid_t)-1, &status, WNOHANG); 2182 if (rval > 0) 2183 continue; 2184 if (rval == 0) 2185 lurking_children = true; 2186 break; 2187 } 2188 2189 Shell_Init(); 2190 2191 JobCreatePipe(&childExitJob, 3); 2192 2193 { 2194 size_t nfds = (npseudojobs + (size_t)opts.maxJobs) * 2195 nfds_per_job(); 2196 fds = bmake_malloc(sizeof *fds * nfds); 2197 jobByFdIndex = bmake_malloc(sizeof *jobByFdIndex * nfds); 2198 } 2199 2200 /* These are permanent entries and take slots 0 and 1 */ 2201 watchfd(&tokenPoolJob); 2202 watchfd(&childExitJob); 2203 2204 sigemptyset(&caught_signals); 2205 (void)bmake_signal(SIGCHLD, HandleSIGCHLD); 2206 sigaddset(&caught_signals, SIGCHLD); 2207 2208 /* Handle the signals specified by POSIX. */ 2209 AddSig(SIGINT, JobPassSig_int); 2210 AddSig(SIGHUP, JobPassSig_term); 2211 AddSig(SIGTERM, JobPassSig_term); 2212 AddSig(SIGQUIT, JobPassSig_term); 2213 2214 /* 2215 * These signals need to be passed to the jobs, as each job has its 2216 * own process group and thus the terminal driver doesn't forward the 2217 * signals itself. 2218 */ 2219 AddSig(SIGTSTP, JobPassSig_suspend); 2220 AddSig(SIGTTOU, JobPassSig_suspend); 2221 AddSig(SIGTTIN, JobPassSig_suspend); 2222 AddSig(SIGWINCH, JobCondPassSig); 2223 AddSig(SIGCONT, HandleSIGCONT); 2224 2225 (void)Job_RunTarget(".BEGIN", NULL); 2226 /* Create the .END node, see Targ_GetEndNode in Compat_MakeAll. */ 2227 (void)Targ_GetEndNode(); 2228 } 2229 2230 static void 2231 DelSig(int sig) 2232 { 2233 if (sigismember(&caught_signals, sig) != 0) 2234 (void)bmake_signal(sig, SIG_DFL); 2235 } 2236 2237 static void 2238 JobSigReset(void) 2239 { 2240 DelSig(SIGINT); 2241 DelSig(SIGHUP); 2242 DelSig(SIGQUIT); 2243 DelSig(SIGTERM); 2244 DelSig(SIGTSTP); 2245 DelSig(SIGTTOU); 2246 DelSig(SIGTTIN); 2247 DelSig(SIGWINCH); 2248 DelSig(SIGCONT); 2249 (void)bmake_signal(SIGCHLD, SIG_DFL); 2250 } 2251 2252 static Shell * 2253 FindShellByName(const char *name) 2254 { 2255 Shell *sh = shells; 2256 const Shell *shellsEnd = sh + sizeof shells / sizeof shells[0]; 2257 2258 for (sh = shells; sh < shellsEnd; sh++) { 2259 if (strcmp(name, sh->name) == 0) 2260 return sh; 2261 } 2262 return NULL; 2263 } 2264 2265 /* 2266 * Parse a shell specification and set up 'shell', shellPath and 2267 * shellName appropriately. 2268 * 2269 * Input: 2270 * line The shell spec 2271 * 2272 * Results: 2273 * Returns false if the specification was incorrect. 2274 * If successful, 'shell' is usable, shellPath is the full path of the 2275 * shell described by 'shell', and shellName is the final component of 2276 * shellPath. 2277 * 2278 * Notes: 2279 * A shell specification has the form ".SHELL: keyword=value...". Double 2280 * quotes can be used to enclose blanks in words. A backslash escapes 2281 * anything (most notably a double-quote and a space) and 2282 * provides the usual escape sequences from C. There should be no 2283 * unnecessary spaces in the word. The keywords are: 2284 * name Name of shell. 2285 * path Location of shell. 2286 * quiet Command to turn off echoing. 2287 * echo Command to turn echoing on 2288 * filter The output from the shell command that turns off 2289 * echoing, to be filtered from the final output. 2290 * echoFlag Flag to turn echoing on at the start. 2291 * errFlag Flag to turn error checking on at the start. 2292 * hasErrCtl True if the shell has error checking control. 2293 * newline String literal to represent a newline character. 2294 * check If hasErrCtl is true: The command to turn on error 2295 * checking. If hasErrCtl is false: The template for a 2296 * shell command that echoes a command for which error 2297 * checking is off. 2298 * ignore If hasErrCtl is true: The command to turn off error 2299 * checking. If hasErrCtl is false: The template for a 2300 * shell command that executes a command so as to ignore 2301 * any errors it returns. 2302 */ 2303 bool 2304 Job_ParseShell(char *line) 2305 { 2306 Words wordsList; 2307 char **words; 2308 char **argv; 2309 size_t argc; 2310 char *path; 2311 Shell newShell; 2312 bool fullSpec = false; 2313 Shell *sh; 2314 2315 /* XXX: don't use line as an iterator variable */ 2316 pp_skip_whitespace(&line); 2317 2318 free(shell_freeIt); 2319 2320 memset(&newShell, 0, sizeof newShell); 2321 2322 wordsList = Str_Words(line, true); 2323 words = wordsList.words; 2324 argc = wordsList.len; 2325 path = wordsList.freeIt; 2326 if (words == NULL) { 2327 Error("Unterminated quoted string [%s]", line); 2328 return false; 2329 } 2330 shell_freeIt = path; 2331 2332 for (path = NULL, argv = words; argc != 0; argc--, argv++) { 2333 char *arg = *argv; 2334 if (strncmp(arg, "path=", 5) == 0) { 2335 path = arg + 5; 2336 } else if (strncmp(arg, "name=", 5) == 0) { 2337 newShell.name = arg + 5; 2338 } else { 2339 if (strncmp(arg, "quiet=", 6) == 0) { 2340 newShell.echoOff = arg + 6; 2341 } else if (strncmp(arg, "echo=", 5) == 0) { 2342 newShell.echoOn = arg + 5; 2343 } else if (strncmp(arg, "filter=", 7) == 0) { 2344 newShell.noPrint = arg + 7; 2345 newShell.noPrintLen = strlen(newShell.noPrint); 2346 } else if (strncmp(arg, "echoFlag=", 9) == 0) { 2347 newShell.echoFlag = arg + 9; 2348 } else if (strncmp(arg, "errFlag=", 8) == 0) { 2349 newShell.errFlag = arg + 8; 2350 } else if (strncmp(arg, "hasErrCtl=", 10) == 0) { 2351 char c = arg[10]; 2352 newShell.hasErrCtl = c == 'Y' || c == 'y' || 2353 c == 'T' || c == 't'; 2354 } else if (strncmp(arg, "newline=", 8) == 0) { 2355 newShell.newline = arg + 8; 2356 } else if (strncmp(arg, "check=", 6) == 0) { 2357 /* 2358 * Before 2020-12-10, these two variables had 2359 * been a single variable. 2360 */ 2361 newShell.errOn = arg + 6; 2362 newShell.echoTmpl = arg + 6; 2363 } else if (strncmp(arg, "ignore=", 7) == 0) { 2364 /* 2365 * Before 2020-12-10, these two variables had 2366 * been a single variable. 2367 */ 2368 newShell.errOff = arg + 7; 2369 newShell.runIgnTmpl = arg + 7; 2370 } else if (strncmp(arg, "errout=", 7) == 0) { 2371 newShell.runChkTmpl = arg + 7; 2372 } else if (strncmp(arg, "comment=", 8) == 0) { 2373 newShell.commentChar = arg[8]; 2374 } else { 2375 Parse_Error(PARSE_FATAL, 2376 "Unknown keyword \"%s\"", arg); 2377 free(words); 2378 return false; 2379 } 2380 fullSpec = true; 2381 } 2382 } 2383 2384 if (path == NULL) { 2385 if (newShell.name == NULL) { 2386 Parse_Error(PARSE_FATAL, 2387 "Neither path nor name specified"); 2388 free(words); 2389 return false; 2390 } else { 2391 if ((sh = FindShellByName(newShell.name)) == NULL) { 2392 Parse_Error(PARSE_WARNING, 2393 "%s: No matching shell", newShell.name); 2394 free(words); 2395 return false; 2396 } 2397 shell = sh; 2398 shellName = newShell.name; 2399 if (shellPath != NULL) { 2400 free(shellPath); 2401 shellPath = NULL; 2402 Shell_Init(); 2403 } 2404 } 2405 } else { 2406 free(shellPath); 2407 shellPath = bmake_strdup(path); 2408 shellName = newShell.name != NULL ? newShell.name 2409 : str_basename(path); 2410 if (!fullSpec) { 2411 if ((sh = FindShellByName(shellName)) == NULL) { 2412 Parse_Error(PARSE_WARNING, 2413 "%s: No matching shell", shellName); 2414 free(words); 2415 return false; 2416 } 2417 shell = sh; 2418 } else { 2419 shell = bmake_malloc(sizeof *shell); 2420 *shell = newShell; 2421 } 2422 /* This will take care of shellErrFlag. */ 2423 Shell_Init(); 2424 } 2425 2426 if (shell->echoOn != NULL && shell->echoOff != NULL) 2427 shell->hasEchoCtl = true; 2428 2429 if (!shell->hasErrCtl) { 2430 if (shell->echoTmpl == NULL) 2431 shell->echoTmpl = ""; 2432 if (shell->runIgnTmpl == NULL) 2433 shell->runIgnTmpl = "%s\n"; 2434 } 2435 2436 /* 2437 * Do not free up the words themselves, since they may be in use 2438 * by the shell specification. 2439 */ 2440 free(words); 2441 return true; 2442 } 2443 2444 /* 2445 * After receiving an interrupt signal, terminate all child processes and if 2446 * necessary make the .INTERRUPT target. 2447 */ 2448 static void 2449 JobInterrupt(bool runINTERRUPT, int signo) 2450 { 2451 Job *job; 2452 sigset_t mask; 2453 2454 aborting = ABORT_INTERRUPT; 2455 2456 JobsTable_Lock(&mask); 2457 2458 for (job = job_table; job < job_table_end; job++) { 2459 if (job->status == JOB_ST_RUNNING && job->pid != 0) { 2460 DEBUG2(JOB, 2461 "JobInterrupt passing signal %d to child %d.\n", 2462 signo, job->pid); 2463 KILLPG(job->pid, signo); 2464 } 2465 } 2466 2467 for (job = job_table; job < job_table_end; job++) { 2468 if (job->status == JOB_ST_RUNNING && job->pid != 0) { 2469 int status; 2470 (void)waitpid(job->pid, &status, 0); 2471 JobDeleteTarget(job->node); 2472 } 2473 } 2474 2475 JobsTable_Unlock(&mask); 2476 2477 if (runINTERRUPT && !opts.touch) { 2478 GNode *dotInterrupt = Targ_FindNode(".INTERRUPT"); 2479 if (dotInterrupt != NULL) { 2480 opts.ignoreErrors = false; 2481 JobRun(dotInterrupt); 2482 } 2483 } 2484 Trace_Log(MAKEINTR, NULL); 2485 exit(signo); /* XXX: why signo? */ 2486 } 2487 2488 /* Make the .END target, returning the number of job-related errors. */ 2489 int 2490 Job_MakeDotEnd(void) 2491 { 2492 GNode *dotEnd = Targ_GetEndNode(); 2493 if (!Lst_IsEmpty(&dotEnd->commands) || 2494 !Lst_IsEmpty(&dotEnd->children)) { 2495 if (job_errors != 0) 2496 Error("Errors reported so .END ignored"); 2497 else 2498 JobRun(dotEnd); 2499 } 2500 return job_errors; 2501 } 2502 2503 #ifdef CLEANUP 2504 void 2505 Job_End(void) 2506 { 2507 free(shell_freeIt); 2508 } 2509 #endif 2510 2511 /* Waits for all running jobs to finish. */ 2512 void 2513 Job_Wait(void) 2514 { 2515 aborting = ABORT_WAIT; /* Prevent other jobs from starting. */ 2516 while (jobTokensRunning != 0) 2517 Job_CatchOutput(); 2518 aborting = ABORT_NONE; 2519 } 2520 2521 /* 2522 * Abort all currently running jobs without handling output or anything. 2523 * This function is to be called only in the event of a major error. 2524 * Most definitely NOT to be called from JobInterrupt. 2525 */ 2526 void 2527 Job_AbortAll(void) 2528 { 2529 Job *job; 2530 int status; 2531 2532 aborting = ABORT_ERROR; 2533 2534 if (jobTokensRunning != 0) { 2535 for (job = job_table; job < job_table_end; job++) { 2536 if (job->status != JOB_ST_RUNNING) 2537 continue; 2538 KILLPG(job->pid, SIGINT); 2539 KILLPG(job->pid, SIGKILL); 2540 } 2541 } 2542 2543 while (waitpid((pid_t)-1, &status, WNOHANG) > 0) 2544 continue; 2545 } 2546 2547 static void 2548 watchfd(Job *job) 2549 { 2550 if (job->inPollfd != NULL) 2551 Punt("Watching watched job"); 2552 2553 fds[fdsLen].fd = job->inPipe; 2554 fds[fdsLen].events = POLLIN; 2555 jobByFdIndex[fdsLen] = job; 2556 job->inPollfd = &fds[fdsLen]; 2557 fdsLen++; 2558 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV) 2559 if (useMeta) { 2560 fds[fdsLen].fd = meta_job_fd(job); 2561 fds[fdsLen].events = fds[fdsLen].fd == -1 ? 0 : POLLIN; 2562 jobByFdIndex[fdsLen] = job; 2563 fdsLen++; 2564 } 2565 #endif 2566 } 2567 2568 static void 2569 clearfd(Job *job) 2570 { 2571 size_t i; 2572 if (job->inPollfd == NULL) 2573 Punt("Unwatching unwatched job"); 2574 i = (size_t)(job->inPollfd - fds); 2575 fdsLen--; 2576 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV) 2577 if (useMeta) { 2578 assert(nfds_per_job() == 2); 2579 if (i % 2 != 0) 2580 Punt("odd-numbered fd with meta"); 2581 fdsLen--; 2582 } 2583 #endif 2584 /* Move last job in table into hole made by dead job. */ 2585 if (fdsLen != i) { 2586 fds[i] = fds[fdsLen]; 2587 jobByFdIndex[i] = jobByFdIndex[fdsLen]; 2588 jobByFdIndex[i]->inPollfd = &fds[i]; 2589 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV) 2590 if (useMeta) { 2591 fds[i + 1] = fds[fdsLen + 1]; 2592 jobByFdIndex[i + 1] = jobByFdIndex[fdsLen + 1]; 2593 } 2594 #endif 2595 } 2596 job->inPollfd = NULL; 2597 } 2598 2599 int 2600 Job_TempFile(const char *pattern, char *tfile, size_t tfile_sz) 2601 { 2602 int fd; 2603 sigset_t mask; 2604 2605 JobsTable_Lock(&mask); 2606 fd = mkTempFile(pattern, tfile, tfile_sz); 2607 if (tfile != NULL && !DEBUG(SCRIPT)) 2608 unlink(tfile); 2609 JobsTable_Unlock(&mask); 2610 2611 return fd; 2612 } 2613 2614 static void 2615 TokenPool_Write(char tok) 2616 { 2617 if (write(tokenPoolJob.outPipe, &tok, 1) != 1) 2618 Punt("Cannot write \"%c\" to the token pool: %s", 2619 tok, strerror(errno)); 2620 } 2621 2622 /* 2623 * Put a token (back) into the job token pool. 2624 * This allows a make process to start a build job. 2625 */ 2626 static void 2627 TokenPool_Add(void) 2628 { 2629 char tok = JOB_TOKENS[aborting], tok1; 2630 2631 /* If we are depositing an error token, flush everything else. */ 2632 while (tok != '+' && read(tokenPoolJob.inPipe, &tok1, 1) == 1) 2633 continue; 2634 2635 DEBUG3(JOB, "TokenPool_Add: pid %d, aborting %s, token %c\n", 2636 getpid(), aborting_name[aborting], tok); 2637 TokenPool_Write(tok); 2638 } 2639 2640 static void 2641 TokenPool_InitClient(int tokenPoolReader, int tokenPoolWriter) 2642 { 2643 tokenPoolJob.inPipe = tokenPoolReader; 2644 tokenPoolJob.outPipe = tokenPoolWriter; 2645 (void)fcntl(tokenPoolReader, F_SETFD, FD_CLOEXEC); 2646 (void)fcntl(tokenPoolWriter, F_SETFD, FD_CLOEXEC); 2647 } 2648 2649 /* Prepare the job token pipe in the root make process. */ 2650 static void 2651 TokenPool_InitServer(int maxJobTokens) 2652 { 2653 int i; 2654 char jobarg[64]; 2655 2656 JobCreatePipe(&tokenPoolJob, 15); 2657 2658 snprintf(jobarg, sizeof jobarg, "%d,%d", 2659 tokenPoolJob.inPipe, tokenPoolJob.outPipe); 2660 2661 Global_Append(MAKEFLAGS, "-J"); 2662 Global_Append(MAKEFLAGS, jobarg); 2663 2664 /* 2665 * Preload the job pipe with one token per job, save the one 2666 * "extra" token for the primary job. 2667 */ 2668 SetNonblocking(tokenPoolJob.outPipe); 2669 for (i = 1; i < maxJobTokens; i++) 2670 TokenPool_Add(); 2671 } 2672 2673 void 2674 TokenPool_Init(int maxJobTokens, int tokenPoolReader, int tokenPoolWriter) 2675 { 2676 if (tokenPoolReader >= 0 && tokenPoolWriter >= 0) 2677 TokenPool_InitClient(tokenPoolReader, tokenPoolWriter); 2678 else 2679 TokenPool_InitServer(maxJobTokens); 2680 } 2681 2682 /* Return a taken token to the pool. */ 2683 void 2684 TokenPool_Return(void) 2685 { 2686 jobTokensRunning--; 2687 if (jobTokensRunning < 0) 2688 Punt("token botch"); 2689 if (jobTokensRunning != 0 || JOB_TOKENS[aborting] != '+') 2690 TokenPool_Add(); 2691 } 2692 2693 /* 2694 * Attempt to take a token from the pool. 2695 * 2696 * If the pool is empty, set wantToken so that we wake up when a token is 2697 * released. 2698 * 2699 * Returns true if a token was taken, and false if the pool is currently 2700 * empty. 2701 */ 2702 bool 2703 TokenPool_Take(void) 2704 { 2705 char tok, tok1; 2706 ssize_t count; 2707 2708 wantToken = false; 2709 DEBUG3(JOB, "TokenPool_Take: pid %d, aborting %s, running %d\n", 2710 getpid(), aborting_name[aborting], jobTokensRunning); 2711 2712 if (aborting != ABORT_NONE || jobTokensRunning >= opts.maxJobs) 2713 return false; 2714 2715 count = read(tokenPoolJob.inPipe, &tok, 1); 2716 if (count == 0) 2717 Fatal("eof on job pipe"); 2718 if (count < 0 && jobTokensRunning != 0) { 2719 if (errno != EAGAIN) 2720 Fatal("job pipe read: %s", strerror(errno)); 2721 DEBUG1(JOB, "TokenPool_Take: pid %d blocked for token\n", 2722 getpid()); 2723 wantToken = true; 2724 return false; 2725 } 2726 2727 if (count == 1 && tok != '+') { 2728 /* make being aborted - remove any other job tokens */ 2729 DEBUG2(JOB, "TokenPool_Take: pid %d aborted by token %c\n", 2730 getpid(), tok); 2731 while (read(tokenPoolJob.inPipe, &tok1, 1) == 1) 2732 continue; 2733 /* And put the stopper back */ 2734 TokenPool_Write(tok); 2735 if (shouldDieQuietly(NULL, 1)) { 2736 Job_Wait(); 2737 exit(6); 2738 } 2739 Fatal("A failure has been detected " 2740 "in another branch of the parallel make"); 2741 } 2742 2743 if (count == 1 && jobTokensRunning == 0) 2744 /* We didn't want the token really */ 2745 TokenPool_Write(tok); 2746 2747 jobTokensRunning++; 2748 DEBUG1(JOB, "TokenPool_Take: pid %d took a token\n", getpid()); 2749 return true; 2750 } 2751 2752 /* Make the named target if found, exit if the target fails. */ 2753 bool 2754 Job_RunTarget(const char *target, const char *fname) 2755 { 2756 GNode *gn = Targ_FindNode(target); 2757 if (gn == NULL) 2758 return false; 2759 2760 if (fname != NULL) 2761 Var_Set(gn, ALLSRC, fname); 2762 2763 JobRun(gn); 2764 return true; 2765 } 2766 2767 #ifdef USE_SELECT 2768 int 2769 emul_poll(struct pollfd *fd, int nfd, int timeout) 2770 { 2771 fd_set rfds, wfds; 2772 int i, maxfd, nselect, npoll; 2773 struct timeval tv, *tvp; 2774 long usecs; 2775 2776 FD_ZERO(&rfds); 2777 FD_ZERO(&wfds); 2778 2779 maxfd = -1; 2780 for (i = 0; i < nfd; i++) { 2781 fd[i].revents = 0; 2782 2783 if (fd[i].events & POLLIN) 2784 FD_SET(fd[i].fd, &rfds); 2785 2786 if (fd[i].events & POLLOUT) 2787 FD_SET(fd[i].fd, &wfds); 2788 2789 if (fd[i].fd > maxfd) 2790 maxfd = fd[i].fd; 2791 } 2792 2793 if (maxfd >= FD_SETSIZE) { 2794 Punt("Ran out of fd_set slots; " 2795 "recompile with a larger FD_SETSIZE."); 2796 } 2797 2798 if (timeout < 0) { 2799 tvp = NULL; 2800 } else { 2801 usecs = timeout * 1000; 2802 tv.tv_sec = usecs / 1000000; 2803 tv.tv_usec = usecs % 1000000; 2804 tvp = &tv; 2805 } 2806 2807 nselect = select(maxfd + 1, &rfds, &wfds, NULL, tvp); 2808 2809 if (nselect <= 0) 2810 return nselect; 2811 2812 npoll = 0; 2813 for (i = 0; i < nfd; i++) { 2814 if (FD_ISSET(fd[i].fd, &rfds)) 2815 fd[i].revents |= POLLIN; 2816 2817 if (FD_ISSET(fd[i].fd, &wfds)) 2818 fd[i].revents |= POLLOUT; 2819 2820 if (fd[i].revents) 2821 npoll++; 2822 } 2823 2824 return npoll; 2825 } 2826 #endif /* USE_SELECT */ 2827