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