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