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