job.c revision 1.488 1 /* $NetBSD: job.c,v 1.488 2025/03/07 16:41:21 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.488 2025/03/07 16:41:21 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 /*
1225 * TODO: better clean up properly, to avoid killing
1226 * child processes by SIGPIPE.
1227 */
1228 exit(2);
1229 }
1230 Fatal("%d error%s", job_errors, job_errors == 1 ? "" : "s");
1231 }
1232 }
1233
1234 static void
1235 TouchRegular(GNode *gn)
1236 {
1237 const char *file = GNode_Path(gn);
1238 struct utimbuf times;
1239 int fd;
1240 char c;
1241
1242 times.actime = now;
1243 times.modtime = now;
1244 if (utime(file, ×) >= 0)
1245 return;
1246
1247 fd = open(file, O_RDWR | O_CREAT, 0666);
1248 if (fd < 0) {
1249 (void)fprintf(stderr, "*** couldn't touch %s: %s\n",
1250 file, strerror(errno));
1251 (void)fflush(stderr);
1252 return; /* XXX: What about propagating the error? */
1253 }
1254
1255 /*
1256 * Last resort: update the file's time stamps in the traditional way.
1257 * XXX: This doesn't work for empty files, which are sometimes used
1258 * as marker files.
1259 */
1260 if (read(fd, &c, 1) == 1) {
1261 (void)lseek(fd, 0, SEEK_SET);
1262 while (write(fd, &c, 1) == -1 && errno == EAGAIN)
1263 continue;
1264 }
1265 (void)close(fd); /* XXX: What about propagating the error? */
1266 }
1267
1268 /*
1269 * Touch the given target. Called by Job_Make when the -t flag was given.
1270 *
1271 * The modification date of the file is changed.
1272 * If the file did not exist, it is created.
1273 */
1274 void
1275 Job_Touch(GNode *gn, bool echo)
1276 {
1277 if (gn->type &
1278 (OP_JOIN | OP_USE | OP_USEBEFORE | OP_EXEC | OP_OPTIONAL |
1279 OP_SPECIAL | OP_PHONY)) {
1280 /*
1281 * These are "virtual" targets and should not really be
1282 * created.
1283 */
1284 return;
1285 }
1286
1287 if (echo || !GNode_ShouldExecute(gn)) {
1288 (void)fprintf(stdout, "touch %s\n", gn->name);
1289 (void)fflush(stdout);
1290 }
1291
1292 if (!GNode_ShouldExecute(gn))
1293 return;
1294
1295 if (gn->type & OP_ARCHV)
1296 Arch_Touch(gn);
1297 else if (gn->type & OP_LIB)
1298 Arch_TouchLib(gn);
1299 else
1300 TouchRegular(gn);
1301 }
1302
1303 /*
1304 * Make sure the given node has all the commands it needs.
1305 *
1306 * The node will have commands from the .DEFAULT rule added to it if it
1307 * needs them.
1308 *
1309 * Input:
1310 * gn The target whose commands need verifying
1311 * abortProc Function to abort with message
1312 *
1313 * Results:
1314 * true if the commands list is/was ok.
1315 */
1316 bool
1317 Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
1318 {
1319 if (GNode_IsTarget(gn))
1320 return true;
1321 if (!Lst_IsEmpty(&gn->commands))
1322 return true;
1323 if ((gn->type & OP_LIB) && !Lst_IsEmpty(&gn->children))
1324 return true;
1325
1326 /*
1327 * No commands. Look for .DEFAULT rule from which we might infer
1328 * commands.
1329 */
1330 if (defaultNode != NULL && !Lst_IsEmpty(&defaultNode->commands) &&
1331 !(gn->type & OP_SPECIAL)) {
1332 /*
1333 * The traditional Make only looks for a .DEFAULT if the node
1334 * was never the target of an operator, so that's what we do
1335 * too.
1336 *
1337 * The .DEFAULT node acts like a transformation rule, in that
1338 * gn also inherits any attributes or sources attached to
1339 * .DEFAULT itself.
1340 */
1341 Make_HandleUse(defaultNode, gn);
1342 Var_Set(gn, IMPSRC, GNode_VarTarget(gn));
1343 return true;
1344 }
1345
1346 Dir_UpdateMTime(gn, false);
1347 if (gn->mtime != 0 || (gn->type & OP_SPECIAL))
1348 return true;
1349
1350 /*
1351 * The node wasn't the target of an operator. We have no .DEFAULT
1352 * rule to go on and the target doesn't already exist. There's
1353 * nothing more we can do for this branch. If the -k flag wasn't
1354 * given, we stop in our tracks, otherwise we just don't update
1355 * this node's parents so they never get examined.
1356 */
1357
1358 if (gn->flags.fromDepend) {
1359 if (!Job_RunTarget(".STALE", gn->fname))
1360 fprintf(stdout,
1361 "%s: %s, %u: ignoring stale %s for %s\n",
1362 progname, gn->fname, gn->lineno, makeDependfile,
1363 gn->name);
1364 return true;
1365 }
1366
1367 if (gn->type & OP_OPTIONAL) {
1368 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n",
1369 progname, gn->name, "ignored");
1370 (void)fflush(stdout);
1371 return true;
1372 }
1373
1374 if (opts.keepgoing) {
1375 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n",
1376 progname, gn->name, "continuing");
1377 (void)fflush(stdout);
1378 return false;
1379 }
1380
1381 abortProc("don't know how to make %s. Stop", gn->name);
1382 return false;
1383 }
1384
1385 /*
1386 * Execute the shell for the given job.
1387 *
1388 * See Job_CatchOutput for handling the output of the shell.
1389 */
1390 static void
1391 JobExec(Job *job, char **argv)
1392 {
1393 int cpid; /* ID of new child */
1394 sigset_t mask;
1395
1396 if (DEBUG(JOB)) {
1397 int i;
1398
1399 debug_printf("Running %s\n", job->node->name);
1400 debug_printf("\tCommand: ");
1401 for (i = 0; argv[i] != NULL; i++) {
1402 debug_printf("%s ", argv[i]);
1403 }
1404 debug_printf("\n");
1405 }
1406
1407 /*
1408 * Some jobs produce no output, and it's disconcerting to have
1409 * no feedback of their running (since they produce no output, the
1410 * banner with their name in it never appears). This is an attempt to
1411 * provide that feedback, even if nothing follows it.
1412 */
1413 if (job->echo)
1414 SwitchOutputTo(job->node);
1415
1416 /* No interruptions until this job is on the `jobs' list */
1417 JobSigLock(&mask);
1418
1419 /* Pre-emptively mark job running, pid still zero though */
1420 job->status = JOB_ST_RUNNING;
1421
1422 Var_ReexportVars(job->node);
1423
1424 cpid = FORK_FUNCTION();
1425 if (cpid == -1)
1426 Punt("Cannot fork: %s", strerror(errno));
1427
1428 if (cpid == 0) {
1429 /* Child */
1430 sigset_t tmask;
1431
1432 #ifdef USE_META
1433 if (useMeta)
1434 meta_job_child(job);
1435 #endif
1436 /*
1437 * Reset all signal handlers; this is necessary because we
1438 * also need to unblock signals before we exec(2).
1439 */
1440 JobSigReset();
1441
1442 /* Now unblock signals */
1443 sigemptyset(&tmask);
1444 JobSigUnlock(&tmask);
1445
1446 /*
1447 * Must duplicate the input stream down to the child's input
1448 * and reset it to the beginning (again). Since the stream
1449 * was marked close-on-exec, we must clear that bit in the
1450 * new input.
1451 */
1452 if (dup2(fileno(job->cmdFILE), STDIN_FILENO) == -1)
1453 execDie("dup2", "job->cmdFILE");
1454 if (fcntl(STDIN_FILENO, F_SETFD, 0) == -1)
1455 execDie("fcntl clear close-on-exec", "stdin");
1456 if (lseek(STDIN_FILENO, 0, SEEK_SET) == -1)
1457 execDie("lseek to 0", "stdin");
1458
1459 if (job->node->type & (OP_MAKE | OP_SUBMAKE)) {
1460 /* Pass job token pipe to submakes. */
1461 if (fcntl(tokenWaitJob.inPipe, F_SETFD, 0) == -1)
1462 execDie("clear close-on-exec",
1463 "tokenWaitJob.inPipe");
1464 if (fcntl(tokenWaitJob.outPipe, F_SETFD, 0) == -1)
1465 execDie("clear close-on-exec",
1466 "tokenWaitJob.outPipe");
1467 }
1468
1469 /*
1470 * Set up the child's output to be routed through the pipe
1471 * we've created for it.
1472 */
1473 if (dup2(job->outPipe, STDOUT_FILENO) == -1)
1474 execDie("dup2", "job->outPipe");
1475
1476 /*
1477 * The output channels are marked close on exec. This bit
1478 * was duplicated by dup2 (on some systems), so we have
1479 * to clear it before routing the shell's error output to
1480 * the same place as its standard output.
1481 */
1482 if (fcntl(STDOUT_FILENO, F_SETFD, 0) == -1)
1483 execDie("clear close-on-exec", "stdout");
1484 if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
1485 execDie("dup2", "1, 2");
1486
1487 /*
1488 * We want to switch the child into a different process
1489 * family so we can kill it and all its descendants in
1490 * one fell swoop, by killing its process family, but not
1491 * commit suicide.
1492 */
1493 #if defined(MAKE_NATIVE) || defined(HAVE_SETPGID)
1494 # if defined(SYSV)
1495 /* XXX: dsl - I'm sure this should be setpgrp()... */
1496 (void)setsid();
1497 # else
1498 (void)setpgid(0, getpid());
1499 # endif
1500 #endif
1501
1502 (void)execv(shellPath, argv);
1503 execDie("exec", shellPath);
1504 }
1505
1506 /* Parent, continuing after the child exec */
1507 job->pid = cpid;
1508
1509 Trace_Log(JOBSTART, job);
1510
1511 #ifdef USE_META
1512 if (useMeta)
1513 meta_job_parent(job, cpid);
1514 #endif
1515
1516 /*
1517 * Set the current position in the buffer to the beginning
1518 * and mark another stream to watch in the outputs mask
1519 */
1520 job->curPos = 0;
1521
1522 watchfd(job);
1523
1524 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1525 if (fclose(job->cmdFILE) != 0)
1526 Punt("Cannot write shell script for '%s': %s",
1527 job->node->name, strerror(errno));
1528 job->cmdFILE = NULL;
1529 }
1530
1531 /* Now that the job is actually running, add it to the table. */
1532 if (DEBUG(JOB)) {
1533 debug_printf("JobExec(%s): pid %d added to jobs table\n",
1534 job->node->name, job->pid);
1535 DumpJobs("job started");
1536 }
1537 JobSigUnlock(&mask);
1538 }
1539
1540 /* Create the argv needed to execute the shell for a given job. */
1541 static void
1542 JobMakeArgv(Job *job, char **argv)
1543 {
1544 int argc;
1545 static char args[10]; /* For merged arguments */
1546
1547 argv[0] = UNCONST(shellName);
1548 argc = 1;
1549
1550 if ((shell->errFlag != NULL && shell->errFlag[0] != '-') ||
1551 (shell->echoFlag != NULL && shell->echoFlag[0] != '-')) {
1552 /*
1553 * At least one of the flags doesn't have a minus before it,
1554 * so merge them together. Have to do this because the Bourne
1555 * shell thinks its second argument is a file to source.
1556 * Grrrr. Note the ten-character limitation on the combined
1557 * arguments.
1558 *
1559 * TODO: Research until when the above comments were
1560 * practically relevant.
1561 */
1562 (void)snprintf(args, sizeof args, "-%s%s",
1563 (job->ignerr ? "" :
1564 (shell->errFlag != NULL ? shell->errFlag : "")),
1565 (!job->echo ? "" :
1566 (shell->echoFlag != NULL ? shell->echoFlag : "")));
1567
1568 if (args[1] != '\0') {
1569 argv[argc] = args;
1570 argc++;
1571 }
1572 } else {
1573 if (!job->ignerr && shell->errFlag != NULL) {
1574 argv[argc] = UNCONST(shell->errFlag);
1575 argc++;
1576 }
1577 if (job->echo && shell->echoFlag != NULL) {
1578 argv[argc] = UNCONST(shell->echoFlag);
1579 argc++;
1580 }
1581 }
1582 argv[argc] = NULL;
1583 }
1584
1585 static void
1586 JobWriteShellCommands(Job *job, GNode *gn, bool *out_run)
1587 {
1588 /*
1589 * tfile is the name of a file into which all shell commands
1590 * are put. It is removed before the child shell is executed,
1591 * unless DEBUG(SCRIPT) is set.
1592 */
1593 char tfile[MAXPATHLEN];
1594 int tfd; /* File descriptor to the temp file */
1595
1596 tfd = Job_TempFile(TMPPAT, tfile, sizeof tfile);
1597
1598 job->cmdFILE = fdopen(tfd, "w+");
1599 if (job->cmdFILE == NULL)
1600 Punt("Could not fdopen %s", tfile);
1601
1602 (void)fcntl(fileno(job->cmdFILE), F_SETFD, FD_CLOEXEC);
1603
1604 #ifdef USE_META
1605 if (useMeta) {
1606 meta_job_start(job, gn);
1607 if (gn->type & OP_SILENT) /* might have changed */
1608 job->echo = false;
1609 }
1610 #endif
1611
1612 *out_run = JobWriteCommands(job);
1613 }
1614
1615 void
1616 Job_Make(GNode *gn)
1617 {
1618 Job *job; /* new job descriptor */
1619 char *argv[10]; /* Argument vector to shell */
1620 bool cmdsOK; /* true if the nodes commands were all right */
1621 bool run;
1622
1623 for (job = job_table; job < job_table_end; job++) {
1624 if (job->status == JOB_ST_FREE)
1625 break;
1626 }
1627 if (job >= job_table_end)
1628 Punt("Job_Make no job slots vacant");
1629
1630 memset(job, 0, sizeof *job);
1631 job->node = gn;
1632 job->tailCmds = NULL;
1633 job->status = JOB_ST_SET_UP;
1634
1635 job->special = (gn->type & OP_SPECIAL) != OP_NONE;
1636 job->ignerr = opts.ignoreErrors || gn->type & OP_IGNORE;
1637 job->echo = !(opts.silent || gn->type & OP_SILENT);
1638
1639 /*
1640 * Check the commands now so any attributes from .DEFAULT have a
1641 * chance to migrate to the node.
1642 */
1643 cmdsOK = Job_CheckCommands(gn, Error);
1644
1645 job->inPollfd = NULL;
1646
1647 if (Lst_IsEmpty(&gn->commands)) {
1648 job->cmdFILE = stdout;
1649 run = false;
1650
1651 /*
1652 * We're serious here, but if the commands were bogus, we're
1653 * also dead...
1654 */
1655 if (!cmdsOK) {
1656 PrintOnError(gn, "\n"); /* provide some clue */
1657 DieHorribly();
1658 }
1659 } else if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) ||
1660 (!opts.noExecute && !opts.touch)) {
1661 /*
1662 * The above condition looks very similar to
1663 * GNode_ShouldExecute but is subtly different. It prevents
1664 * that .MAKE targets are touched since these are usually
1665 * virtual targets.
1666 */
1667
1668 int parseErrorsBefore;
1669
1670 /*
1671 * We're serious here, but if the commands were bogus, we're
1672 * also dead...
1673 */
1674 if (!cmdsOK) {
1675 PrintOnError(gn, "\n"); /* provide some clue */
1676 DieHorribly();
1677 }
1678
1679 parseErrorsBefore = parseErrors;
1680 JobWriteShellCommands(job, gn, &run);
1681 if (parseErrors != parseErrorsBefore)
1682 run = false;
1683 (void)fflush(job->cmdFILE);
1684 } else if (!GNode_ShouldExecute(gn)) {
1685 /*
1686 * Just write all the commands to stdout in one fell swoop.
1687 * This still sets up job->tailCmds correctly.
1688 */
1689 SwitchOutputTo(gn);
1690 job->cmdFILE = stdout;
1691 if (cmdsOK)
1692 JobWriteCommands(job);
1693 run = false;
1694 (void)fflush(job->cmdFILE);
1695 } else {
1696 Job_Touch(gn, job->echo);
1697 run = false;
1698 }
1699
1700 /* If we're not supposed to execute a shell, don't. */
1701 if (!run) {
1702 if (!job->special)
1703 Job_TokenReturn();
1704 /* Unlink and close the command file if we opened one */
1705 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1706 (void)fclose(job->cmdFILE);
1707 job->cmdFILE = NULL;
1708 }
1709
1710 /*
1711 * We only want to work our way up the graph if we aren't
1712 * here because the commands for the job were no good.
1713 */
1714 if (cmdsOK && aborting == ABORT_NONE) {
1715 JobSaveCommands(job);
1716 job->node->made = MADE;
1717 Make_Update(job->node);
1718 }
1719 job->status = JOB_ST_FREE;
1720 return;
1721 }
1722
1723 /*
1724 * Set up the control arguments to the shell. This is based on the
1725 * flags set earlier for this job.
1726 */
1727 JobMakeArgv(job, argv);
1728
1729 /* Create the pipe by which we'll get the shell's output. */
1730 JobCreatePipe(job, 3);
1731
1732 JobExec(job, argv);
1733 }
1734
1735 /*
1736 * If the shell has an output filter (which only csh and ksh have by default),
1737 * print the output of the child process, skipping the noPrint text of the
1738 * shell.
1739 *
1740 * Return the part of the output that the calling function needs to output by
1741 * itself.
1742 */
1743 static char *
1744 PrintFilteredOutput(char *p, const char *endp) /* XXX: p should be const */
1745 {
1746 char *ep; /* XXX: should be const */
1747
1748 if (shell->noPrint == NULL || shell->noPrint[0] == '\0')
1749 return p;
1750
1751 /*
1752 * XXX: What happens if shell->noPrint occurs on the boundary of
1753 * the buffer? To work correctly in all cases, this should rather
1754 * be a proper stream filter instead of doing string matching on
1755 * selected chunks of the output.
1756 */
1757 while ((ep = strstr(p, shell->noPrint)) != NULL) {
1758 if (ep != p) {
1759 *ep = '\0'; /* XXX: avoid writing to the buffer */
1760 /*
1761 * The only way there wouldn't be a newline after
1762 * this line is if it were the last in the buffer.
1763 * however, since the noPrint output comes after it,
1764 * there must be a newline, so we don't print one.
1765 */
1766 /* XXX: What about null bytes in the output? */
1767 (void)fprintf(stdout, "%s", p);
1768 (void)fflush(stdout);
1769 }
1770 p = ep + shell->noPrintLen;
1771 if (p == endp)
1772 break;
1773 p++; /* skip over the (XXX: assumed) newline */
1774 pp_skip_whitespace(&p);
1775 }
1776 return p;
1777 }
1778
1779 /*
1780 * This function is called whenever there is something to read on the pipe.
1781 * We collect more output from the given job and store it in the job's
1782 * outBuf. If this makes up a line, we print it tagged by the job's
1783 * identifier, as necessary.
1784 *
1785 * In the output of the shell, the 'noPrint' lines are removed. If the
1786 * command is not alone on the line (the character after it is not \0 or
1787 * \n), we do print whatever follows it.
1788 *
1789 * Input:
1790 * job the job whose output needs printing
1791 * finish true if this is the last time we'll be called
1792 * for this job
1793 */
1794 static void
1795 CollectOutput(Job *job, bool finish)
1796 {
1797 bool gotNL; /* true if got a newline */
1798 bool fbuf; /* true if our buffer filled up */
1799 size_t nr; /* number of bytes read */
1800 size_t i; /* auxiliary index into outBuf */
1801 size_t max; /* limit for i (end of current data) */
1802 ssize_t nRead; /* (Temporary) number of bytes read */
1803
1804 /* Read as many bytes as will fit in the buffer. */
1805 again:
1806 gotNL = false;
1807 fbuf = false;
1808
1809 nRead = read(job->inPipe, &job->outBuf[job->curPos],
1810 JOB_BUFSIZE - job->curPos);
1811 if (nRead < 0) {
1812 if (errno == EAGAIN)
1813 return;
1814 if (DEBUG(JOB))
1815 perror("CollectOutput(piperead)");
1816 nr = 0;
1817 } else
1818 nr = (size_t)nRead;
1819
1820 if (nr == 0)
1821 finish = false; /* stop looping */
1822
1823 /*
1824 * If we hit the end-of-file (the job is dead), we must flush its
1825 * remaining output, so pretend we read a newline if there's any
1826 * output remaining in the buffer.
1827 */
1828 if (nr == 0 && job->curPos != 0) {
1829 job->outBuf[job->curPos] = '\n';
1830 nr = 1;
1831 }
1832
1833 max = job->curPos + nr;
1834 for (i = job->curPos; i < max; i++)
1835 if (job->outBuf[i] == '\0')
1836 job->outBuf[i] = ' ';
1837
1838 /* Look for the last newline in the bytes we just got. */
1839 for (i = job->curPos + nr - 1;
1840 i >= job->curPos && i != (size_t)-1; i--) {
1841 if (job->outBuf[i] == '\n') {
1842 gotNL = true;
1843 break;
1844 }
1845 }
1846
1847 if (!gotNL) {
1848 job->curPos += nr;
1849 if (job->curPos == JOB_BUFSIZE) {
1850 /*
1851 * If we've run out of buffer space, we have no choice
1852 * but to print the stuff. sigh.
1853 */
1854 fbuf = true;
1855 i = job->curPos;
1856 }
1857 }
1858 if (gotNL || fbuf) {
1859 /*
1860 * Need to send the output to the screen. Null terminate it
1861 * first, overwriting the newline character if there was one.
1862 * So long as the line isn't one we should filter (according
1863 * to the shell description), we print the line, preceded
1864 * by a target banner if this target isn't the same as the
1865 * one for which we last printed something.
1866 * The rest of the data in the buffer are then shifted down
1867 * to the start of the buffer and curPos is set accordingly.
1868 */
1869 job->outBuf[i] = '\0';
1870 if (i >= job->curPos) {
1871 char *p;
1872
1873 /*
1874 * FIXME: SwitchOutputTo should be here, according to
1875 * the comment above. But since PrintOutput does not
1876 * do anything in the default shell, this bug has gone
1877 * unnoticed until now.
1878 */
1879 p = PrintFilteredOutput(job->outBuf, &job->outBuf[i]);
1880
1881 /*
1882 * There's still more in the output buffer. This time,
1883 * though, we know there's no newline at the end, so
1884 * we add one of our own free will.
1885 */
1886 if (*p != '\0') {
1887 if (!opts.silent)
1888 SwitchOutputTo(job->node);
1889 #ifdef USE_META
1890 if (useMeta) {
1891 meta_job_output(job, p,
1892 gotNL ? "\n" : "");
1893 }
1894 #endif
1895 (void)fprintf(stdout, "%s%s", p,
1896 gotNL ? "\n" : "");
1897 (void)fflush(stdout);
1898 }
1899 }
1900 /*
1901 * max is the last offset still in the buffer. Move any
1902 * remaining characters to the start of the buffer and
1903 * update the end marker curPos.
1904 */
1905 if (i < max) {
1906 (void)memmove(job->outBuf, &job->outBuf[i + 1],
1907 max - (i + 1));
1908 job->curPos = max - (i + 1);
1909 } else {
1910 assert(i == max);
1911 job->curPos = 0;
1912 }
1913 }
1914 if (finish) {
1915 /*
1916 * If the finish flag is true, we must loop until we hit
1917 * end-of-file on the pipe. This is guaranteed to happen
1918 * eventually since the other end of the pipe is now closed
1919 * (we closed it explicitly and the child has exited). When
1920 * we do get an EOF, finish will be set false and we'll fall
1921 * through and out.
1922 */
1923 goto again;
1924 }
1925 }
1926
1927 static void
1928 JobRun(GNode *targ)
1929 {
1930 /* Don't let these special jobs overlap with other unrelated jobs. */
1931 Compat_Make(targ, targ);
1932 if (GNode_IsError(targ)) {
1933 PrintOnError(targ, "\n\nStop.\n");
1934 exit(1);
1935 }
1936 }
1937
1938 void
1939 Job_CatchChildren(void)
1940 {
1941 int pid;
1942 int status;
1943
1944 if (jobTokensRunning == 0)
1945 return;
1946 if (caught_sigchld == 0)
1947 return;
1948 caught_sigchld = 0;
1949
1950 while ((pid = waitpid((pid_t)-1, &status, WNOHANG | WUNTRACED)) > 0) {
1951 DEBUG2(JOB, "Process %d exited/stopped status %x.\n",
1952 pid, status);
1953 JobReapChild(pid, status, true);
1954 }
1955 }
1956
1957 /*
1958 * It is possible that wait[pid]() was called from elsewhere,
1959 * this lets us reap jobs regardless.
1960 */
1961 void
1962 JobReapChild(pid_t pid, int status, bool isJobs)
1963 {
1964 Job *job;
1965
1966 if (jobTokensRunning == 0)
1967 return;
1968
1969 job = JobFindPid(pid, JOB_ST_RUNNING, isJobs);
1970 if (job == NULL) {
1971 if (isJobs && !lurking_children)
1972 Error("Child (%d) status %x not in table?",
1973 pid, status);
1974 return;
1975 }
1976
1977 if (WIFSTOPPED(status)) {
1978 DEBUG2(JOB, "Process %d (%s) stopped.\n",
1979 job->pid, job->node->name);
1980 if (!make_suspended) {
1981 switch (WSTOPSIG(status)) {
1982 case SIGTSTP:
1983 (void)printf("*** [%s] Suspended\n",
1984 job->node->name);
1985 break;
1986 case SIGSTOP:
1987 (void)printf("*** [%s] Stopped\n",
1988 job->node->name);
1989 break;
1990 default:
1991 (void)printf("*** [%s] Stopped -- signal %d\n",
1992 job->node->name, WSTOPSIG(status));
1993 }
1994 job->suspended = true;
1995 }
1996 (void)fflush(stdout);
1997 return;
1998 }
1999
2000 job->status = JOB_ST_FINISHED;
2001 job->exit_status = status;
2002 if (WIFEXITED(status))
2003 job->node->exit_status = WEXITSTATUS(status);
2004
2005 JobFinish(job, status);
2006 }
2007
2008 void
2009 Job_CatchOutput(void)
2010 {
2011 int nready;
2012 Job *job;
2013 unsigned int i;
2014
2015 (void)fflush(stdout);
2016
2017 /* Skip the first fd in the list, as it is the job token pipe. */
2018 do {
2019 nready = poll(fds + 1 - wantToken, fdsLen - 1 + wantToken,
2020 POLL_MSEC);
2021 } while (nready < 0 && errno == EINTR);
2022
2023 if (nready < 0)
2024 Punt("poll: %s", strerror(errno));
2025
2026 if (nready > 0 && readyfd(&childExitJob)) {
2027 char token = 0;
2028 ssize_t count = read(childExitJob.inPipe, &token, 1);
2029 if (count == 1) {
2030 if (token == DO_JOB_RESUME[0])
2031 /*
2032 * Complete relay requested from our SIGCONT
2033 * handler.
2034 */
2035 JobRestartJobs();
2036 } else if (count == 0)
2037 Punt("unexpected eof on token pipe");
2038 else
2039 Punt("token pipe read: %s", strerror(errno));
2040 nready--;
2041 }
2042
2043 Job_CatchChildren();
2044 if (nready == 0)
2045 return;
2046
2047 for (i = npseudojobs * nfds_per_job(); i < fdsLen; i++) {
2048 if (fds[i].revents == 0)
2049 continue;
2050 job = jobByFdIndex[i];
2051 if (job->status == JOB_ST_RUNNING)
2052 CollectOutput(job, false);
2053 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
2054 /*
2055 * With meta mode, we may have activity on the job's filemon
2056 * descriptor too, which at the moment is any pollfd other
2057 * than job->inPollfd.
2058 */
2059 if (useMeta && job->inPollfd != &fds[i]) {
2060 if (meta_job_event(job) <= 0)
2061 fds[i].events = 0; /* never mind */
2062 }
2063 #endif
2064 if (--nready == 0)
2065 return;
2066 }
2067 }
2068
2069 static void
2070 InitShellNameAndPath(void)
2071 {
2072 shellName = shell->name;
2073
2074 #ifdef DEFSHELL_CUSTOM
2075 if (shellName[0] == '/') {
2076 shellPath = bmake_strdup(shellName);
2077 shellName = str_basename(shellPath);
2078 return;
2079 }
2080 #endif
2081
2082 shellPath = str_concat3(_PATH_DEFSHELLDIR, "/", shellName);
2083 }
2084
2085 void
2086 Shell_Init(void)
2087 {
2088 if (shellPath == NULL)
2089 InitShellNameAndPath();
2090
2091 Var_SetWithFlags(SCOPE_CMDLINE, ".SHELL", shellPath,
2092 VAR_SET_INTERNAL|VAR_SET_READONLY);
2093 if (shell->errFlag == NULL)
2094 shell->errFlag = "";
2095 if (shell->echoFlag == NULL)
2096 shell->echoFlag = "";
2097 if (shell->hasErrCtl && shell->errFlag[0] != '\0') {
2098 if (shellErrFlag != NULL &&
2099 strcmp(shell->errFlag, &shellErrFlag[1]) != 0) {
2100 free(shellErrFlag);
2101 shellErrFlag = NULL;
2102 }
2103 if (shellErrFlag == NULL)
2104 shellErrFlag = str_concat2("-", shell->errFlag);
2105 } else if (shellErrFlag != NULL) {
2106 free(shellErrFlag);
2107 shellErrFlag = NULL;
2108 }
2109 }
2110
2111 /* Return the shell string literal that results in a newline character. */
2112 const char *
2113 Shell_GetNewline(void)
2114 {
2115 return shell->newline;
2116 }
2117
2118 void
2119 Job_SetPrefix(void)
2120 {
2121 if (targPrefix != NULL)
2122 free(targPrefix);
2123 else if (!Var_Exists(SCOPE_GLOBAL, ".MAKE.JOB.PREFIX"))
2124 Global_Set(".MAKE.JOB.PREFIX", "---");
2125
2126 targPrefix = Var_Subst("${.MAKE.JOB.PREFIX}",
2127 SCOPE_GLOBAL, VARE_EVAL);
2128 /* TODO: handle errors */
2129 }
2130
2131 static void
2132 AddSig(int sig, SignalProc handler)
2133 {
2134 if (bmake_signal(sig, SIG_IGN) != SIG_IGN) {
2135 sigaddset(&caught_signals, sig);
2136 (void)bmake_signal(sig, handler);
2137 }
2138 }
2139
2140 void
2141 Job_Init(void)
2142 {
2143 Job_SetPrefix();
2144
2145 job_table = bmake_malloc((size_t)opts.maxJobs * sizeof *job_table);
2146 memset(job_table, 0, (size_t)opts.maxJobs * sizeof *job_table);
2147 job_table_end = job_table + opts.maxJobs;
2148 wantToken = 0;
2149 caught_sigchld = 0;
2150
2151 aborting = ABORT_NONE;
2152 job_errors = 0;
2153
2154 /*
2155 * There is a non-zero chance that we already have children,
2156 * e.g. after 'make -f- <<EOF'.
2157 * Since their termination causes a 'Child (pid) not in table'
2158 * message, Collect the status of any that are already dead, and
2159 * suppress the error message if there are any undead ones.
2160 */
2161 for (;;) {
2162 int rval, status;
2163 rval = waitpid((pid_t)-1, &status, WNOHANG);
2164 if (rval > 0)
2165 continue;
2166 if (rval == 0)
2167 lurking_children = true;
2168 break;
2169 }
2170
2171 Shell_Init();
2172
2173 JobCreatePipe(&childExitJob, 3);
2174
2175 {
2176 size_t nfds = (npseudojobs + (size_t)opts.maxJobs) *
2177 nfds_per_job();
2178 fds = bmake_malloc(sizeof *fds * nfds);
2179 jobByFdIndex = bmake_malloc(sizeof *jobByFdIndex * nfds);
2180 }
2181
2182 /* These are permanent entries and take slots 0 and 1 */
2183 watchfd(&tokenWaitJob);
2184 watchfd(&childExitJob);
2185
2186 sigemptyset(&caught_signals);
2187 (void)bmake_signal(SIGCHLD, JobChildSig);
2188 sigaddset(&caught_signals, SIGCHLD);
2189
2190 /* Handle the signals specified by POSIX. */
2191 AddSig(SIGINT, JobPassSig_int);
2192 AddSig(SIGHUP, JobPassSig_term);
2193 AddSig(SIGTERM, JobPassSig_term);
2194 AddSig(SIGQUIT, JobPassSig_term);
2195
2196 /*
2197 * These signals need to be passed to the jobs, as each job has its
2198 * own process group and thus the terminal driver doesn't forward the
2199 * signals itself.
2200 */
2201 AddSig(SIGTSTP, JobPassSig_suspend);
2202 AddSig(SIGTTOU, JobPassSig_suspend);
2203 AddSig(SIGTTIN, JobPassSig_suspend);
2204 AddSig(SIGWINCH, JobCondPassSig);
2205 AddSig(SIGCONT, JobContinueSig);
2206
2207 (void)Job_RunTarget(".BEGIN", NULL);
2208 /* Create the .END node, see Targ_GetEndNode in Compat_MakeAll. */
2209 (void)Targ_GetEndNode();
2210 }
2211
2212 static void
2213 DelSig(int sig)
2214 {
2215 if (sigismember(&caught_signals, sig) != 0)
2216 (void)bmake_signal(sig, SIG_DFL);
2217 }
2218
2219 static void
2220 JobSigReset(void)
2221 {
2222 DelSig(SIGINT);
2223 DelSig(SIGHUP);
2224 DelSig(SIGQUIT);
2225 DelSig(SIGTERM);
2226 DelSig(SIGTSTP);
2227 DelSig(SIGTTOU);
2228 DelSig(SIGTTIN);
2229 DelSig(SIGWINCH);
2230 DelSig(SIGCONT);
2231 (void)bmake_signal(SIGCHLD, SIG_DFL);
2232 }
2233
2234 static Shell *
2235 FindShellByName(const char *name)
2236 {
2237 Shell *sh = shells;
2238 const Shell *shellsEnd = sh + sizeof shells / sizeof shells[0];
2239
2240 for (sh = shells; sh < shellsEnd; sh++) {
2241 if (strcmp(name, sh->name) == 0)
2242 return sh;
2243 }
2244 return NULL;
2245 }
2246
2247 /*
2248 * Parse a shell specification and set up 'shell', shellPath and
2249 * shellName appropriately.
2250 *
2251 * Input:
2252 * line The shell spec
2253 *
2254 * Results:
2255 * Returns false if the specification was incorrect.
2256 * If successful, 'shell' is usable, shellPath is the full path of the
2257 * shell described by 'shell', and shellName is the final component of
2258 * shellPath.
2259 *
2260 * Notes:
2261 * A shell specification has the form ".SHELL: keyword=value...". Double
2262 * quotes can be used to enclose blanks in words. A backslash escapes
2263 * anything (most notably a double-quote and a space) and
2264 * provides the usual escape sequences from C. There should be no
2265 * unnecessary spaces in the word. The keywords are:
2266 * name Name of shell.
2267 * path Location of shell.
2268 * quiet Command to turn off echoing.
2269 * echo Command to turn echoing on
2270 * filter The output from the shell command that turns off
2271 * echoing, to be filtered from the final output.
2272 * echoFlag Flag to turn echoing on at the start.
2273 * errFlag Flag to turn error checking on at the start.
2274 * hasErrCtl True if the shell has error checking control.
2275 * newline String literal to represent a newline character.
2276 * check If hasErrCtl is true: The command to turn on error
2277 * checking. If hasErrCtl is false: The template for a
2278 * shell command that echoes a command for which error
2279 * checking is off.
2280 * ignore If hasErrCtl is true: The command to turn off error
2281 * checking. If hasErrCtl is false: The template for a
2282 * shell command that executes a command so as to ignore
2283 * any errors it returns.
2284 */
2285 bool
2286 Job_ParseShell(char *line)
2287 {
2288 Words wordsList;
2289 char **words;
2290 char **argv;
2291 size_t argc;
2292 char *path;
2293 Shell newShell;
2294 bool fullSpec = false;
2295 Shell *sh;
2296
2297 /* XXX: don't use line as an iterator variable */
2298 pp_skip_whitespace(&line);
2299
2300 free(shell_freeIt);
2301
2302 memset(&newShell, 0, sizeof newShell);
2303
2304 wordsList = Str_Words(line, true);
2305 words = wordsList.words;
2306 argc = wordsList.len;
2307 path = wordsList.freeIt;
2308 if (words == NULL) {
2309 Error("Unterminated quoted string [%s]", line);
2310 return false;
2311 }
2312 shell_freeIt = path;
2313
2314 for (path = NULL, argv = words; argc != 0; argc--, argv++) {
2315 char *arg = *argv;
2316 if (strncmp(arg, "path=", 5) == 0) {
2317 path = arg + 5;
2318 } else if (strncmp(arg, "name=", 5) == 0) {
2319 newShell.name = arg + 5;
2320 } else {
2321 if (strncmp(arg, "quiet=", 6) == 0) {
2322 newShell.echoOff = arg + 6;
2323 } else if (strncmp(arg, "echo=", 5) == 0) {
2324 newShell.echoOn = arg + 5;
2325 } else if (strncmp(arg, "filter=", 7) == 0) {
2326 newShell.noPrint = arg + 7;
2327 newShell.noPrintLen = strlen(newShell.noPrint);
2328 } else if (strncmp(arg, "echoFlag=", 9) == 0) {
2329 newShell.echoFlag = arg + 9;
2330 } else if (strncmp(arg, "errFlag=", 8) == 0) {
2331 newShell.errFlag = arg + 8;
2332 } else if (strncmp(arg, "hasErrCtl=", 10) == 0) {
2333 char c = arg[10];
2334 newShell.hasErrCtl = c == 'Y' || c == 'y' ||
2335 c == 'T' || c == 't';
2336 } else if (strncmp(arg, "newline=", 8) == 0) {
2337 newShell.newline = arg + 8;
2338 } else if (strncmp(arg, "check=", 6) == 0) {
2339 /*
2340 * Before 2020-12-10, these two variables had
2341 * been a single variable.
2342 */
2343 newShell.errOn = arg + 6;
2344 newShell.echoTmpl = arg + 6;
2345 } else if (strncmp(arg, "ignore=", 7) == 0) {
2346 /*
2347 * Before 2020-12-10, these two variables had
2348 * been a single variable.
2349 */
2350 newShell.errOff = arg + 7;
2351 newShell.runIgnTmpl = arg + 7;
2352 } else if (strncmp(arg, "errout=", 7) == 0) {
2353 newShell.runChkTmpl = arg + 7;
2354 } else if (strncmp(arg, "comment=", 8) == 0) {
2355 newShell.commentChar = arg[8];
2356 } else {
2357 Parse_Error(PARSE_FATAL,
2358 "Unknown keyword \"%s\"", arg);
2359 free(words);
2360 return false;
2361 }
2362 fullSpec = true;
2363 }
2364 }
2365
2366 if (path == NULL) {
2367 if (newShell.name == NULL) {
2368 Parse_Error(PARSE_FATAL,
2369 "Neither path nor name specified");
2370 free(words);
2371 return false;
2372 } else {
2373 if ((sh = FindShellByName(newShell.name)) == NULL) {
2374 Parse_Error(PARSE_WARNING,
2375 "%s: No matching shell", newShell.name);
2376 free(words);
2377 return false;
2378 }
2379 shell = sh;
2380 shellName = newShell.name;
2381 if (shellPath != NULL) {
2382 free(shellPath);
2383 shellPath = NULL;
2384 Shell_Init();
2385 }
2386 }
2387 } else {
2388 free(shellPath);
2389 shellPath = bmake_strdup(path);
2390 shellName = newShell.name != NULL ? newShell.name
2391 : str_basename(path);
2392 if (!fullSpec) {
2393 if ((sh = FindShellByName(shellName)) == NULL) {
2394 Parse_Error(PARSE_WARNING,
2395 "%s: No matching shell", shellName);
2396 free(words);
2397 return false;
2398 }
2399 shell = sh;
2400 } else {
2401 shell = bmake_malloc(sizeof *shell);
2402 *shell = newShell;
2403 }
2404 /* This will take care of shellErrFlag. */
2405 Shell_Init();
2406 }
2407
2408 if (shell->echoOn != NULL && shell->echoOff != NULL)
2409 shell->hasEchoCtl = true;
2410
2411 if (!shell->hasErrCtl) {
2412 if (shell->echoTmpl == NULL)
2413 shell->echoTmpl = "";
2414 if (shell->runIgnTmpl == NULL)
2415 shell->runIgnTmpl = "%s\n";
2416 }
2417
2418 /*
2419 * Do not free up the words themselves, since they may be in use
2420 * by the shell specification.
2421 */
2422 free(words);
2423 return true;
2424 }
2425
2426 /*
2427 * After receiving an interrupt signal, terminate all child processes and if
2428 * necessary make the .INTERRUPT target.
2429 */
2430 static void
2431 JobInterrupt(bool runINTERRUPT, int signo)
2432 {
2433 Job *job;
2434 GNode *interrupt;
2435 sigset_t mask;
2436
2437 aborting = ABORT_INTERRUPT;
2438
2439 JobSigLock(&mask);
2440
2441 for (job = job_table; job < job_table_end; job++) {
2442 if (job->status == JOB_ST_RUNNING && job->pid != 0) {
2443 DEBUG2(JOB,
2444 "JobInterrupt passing signal %d to child %d.\n",
2445 signo, job->pid);
2446 KILLPG(job->pid, signo);
2447 }
2448 }
2449
2450 for (job = job_table; job < job_table_end; job++) {
2451 if (job->status == JOB_ST_RUNNING && job->pid != 0) {
2452 int status;
2453 (void)waitpid(job->pid, &status, 0);
2454 JobDeleteTarget(job->node);
2455 }
2456 }
2457
2458 JobSigUnlock(&mask);
2459
2460 if (runINTERRUPT && !opts.touch) {
2461 interrupt = Targ_FindNode(".INTERRUPT");
2462 if (interrupt != NULL) {
2463 opts.ignoreErrors = false;
2464 JobRun(interrupt);
2465 }
2466 }
2467 Trace_Log(MAKEINTR, NULL);
2468 exit(signo); /* XXX: why signo? */
2469 }
2470
2471 /* Make the .END target, returning the number of job-related errors. */
2472 int
2473 Job_Finish(void)
2474 {
2475 GNode *endNode = Targ_GetEndNode();
2476 if (!Lst_IsEmpty(&endNode->commands) ||
2477 !Lst_IsEmpty(&endNode->children)) {
2478 if (job_errors != 0)
2479 Error("Errors reported so .END ignored");
2480 else
2481 JobRun(endNode);
2482 }
2483 return job_errors;
2484 }
2485
2486 #ifdef CLEANUP
2487 void
2488 Job_End(void)
2489 {
2490 free(shell_freeIt);
2491 }
2492 #endif
2493
2494 /* Waits for all running jobs to finish. */
2495 void
2496 Job_Wait(void)
2497 {
2498 aborting = ABORT_WAIT; /* Prevent other jobs from starting. */
2499 while (jobTokensRunning != 0) {
2500 Job_CatchOutput();
2501 }
2502 aborting = ABORT_NONE;
2503 }
2504
2505 /*
2506 * Abort all currently running jobs without handling output or anything.
2507 * This function is to be called only in the event of a major error.
2508 * Most definitely NOT to be called from JobInterrupt.
2509 */
2510 void
2511 Job_AbortAll(void)
2512 {
2513 Job *job;
2514 int status;
2515
2516 aborting = ABORT_ERROR;
2517
2518 if (jobTokensRunning != 0) {
2519 for (job = job_table; job < job_table_end; job++) {
2520 if (job->status != JOB_ST_RUNNING)
2521 continue;
2522 KILLPG(job->pid, SIGINT);
2523 KILLPG(job->pid, SIGKILL);
2524 }
2525 }
2526
2527 while (waitpid(-1, &status, WNOHANG) > 0)
2528 continue;
2529 }
2530
2531 /*
2532 * Tries to restart stopped jobs if there are slots available.
2533 * Called in response to a SIGCONT.
2534 */
2535 static void
2536 JobRestartJobs(void)
2537 {
2538 Job *job;
2539
2540 for (job = job_table; job < job_table_end; job++) {
2541 if (job->status == JOB_ST_RUNNING &&
2542 (make_suspended || job->suspended)) {
2543 DEBUG1(JOB, "Restarting stopped job pid %d.\n",
2544 job->pid);
2545 if (job->suspended) {
2546 (void)printf("*** [%s] Continued\n",
2547 job->node->name);
2548 (void)fflush(stdout);
2549 }
2550 job->suspended = false;
2551 if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) {
2552 debug_printf("Failed to send SIGCONT to %d\n",
2553 job->pid);
2554 }
2555 }
2556 if (job->status == JOB_ST_FINISHED) {
2557 /*
2558 * Job exit deferred after calling waitpid() in a
2559 * signal handler
2560 */
2561 JobFinish(job, job->exit_status);
2562 }
2563 }
2564 make_suspended = false;
2565 }
2566
2567 static void
2568 watchfd(Job *job)
2569 {
2570 if (job->inPollfd != NULL)
2571 Punt("Watching watched job");
2572
2573 fds[fdsLen].fd = job->inPipe;
2574 fds[fdsLen].events = POLLIN;
2575 jobByFdIndex[fdsLen] = job;
2576 job->inPollfd = &fds[fdsLen];
2577 fdsLen++;
2578 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
2579 if (useMeta) {
2580 fds[fdsLen].fd = meta_job_fd(job);
2581 fds[fdsLen].events = fds[fdsLen].fd == -1 ? 0 : POLLIN;
2582 jobByFdIndex[fdsLen] = job;
2583 fdsLen++;
2584 }
2585 #endif
2586 }
2587
2588 static void
2589 clearfd(Job *job)
2590 {
2591 size_t i;
2592 if (job->inPollfd == NULL)
2593 Punt("Unwatching unwatched job");
2594 i = (size_t)(job->inPollfd - fds);
2595 fdsLen--;
2596 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
2597 if (useMeta) {
2598 assert(nfds_per_job() == 2);
2599 if (i % 2 != 0)
2600 Punt("odd-numbered fd with meta");
2601 fdsLen--;
2602 }
2603 #endif
2604 /* Move last job in table into hole made by dead job. */
2605 if (fdsLen != i) {
2606 fds[i] = fds[fdsLen];
2607 jobByFdIndex[i] = jobByFdIndex[fdsLen];
2608 jobByFdIndex[i]->inPollfd = &fds[i];
2609 #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
2610 if (useMeta) {
2611 fds[i + 1] = fds[fdsLen + 1];
2612 jobByFdIndex[i + 1] = jobByFdIndex[fdsLen + 1];
2613 }
2614 #endif
2615 }
2616 job->inPollfd = NULL;
2617 }
2618
2619 static bool
2620 readyfd(Job *job)
2621 {
2622 if (job->inPollfd == NULL)
2623 Punt("Polling unwatched job");
2624 return (job->inPollfd->revents & POLLIN) != 0;
2625 }
2626
2627 /*
2628 * Put a token (back) into the job pipe.
2629 * This allows a make process to start a build job.
2630 */
2631 static void
2632 JobTokenAdd(void)
2633 {
2634 char tok = JOB_TOKENS[aborting], tok1;
2635
2636 /* If we are depositing an error token, flush everything else. */
2637 while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1)
2638 continue;
2639
2640 DEBUG3(JOB, "(%d) aborting %d, deposit token %c\n",
2641 getpid(), aborting, JOB_TOKENS[aborting]);
2642 while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
2643 continue;
2644 }
2645
2646 int
2647 Job_TempFile(const char *pattern, char *tfile, size_t tfile_sz)
2648 {
2649 int fd;
2650 sigset_t mask;
2651
2652 JobSigLock(&mask);
2653 fd = mkTempFile(pattern, tfile, tfile_sz);
2654 if (tfile != NULL && !DEBUG(SCRIPT))
2655 unlink(tfile);
2656 JobSigUnlock(&mask);
2657
2658 return fd;
2659 }
2660
2661 /* Prepare the job token pipe in the root make process. */
2662 void
2663 Job_ServerStart(int max_tokens, int jp_0, int jp_1)
2664 {
2665 int i;
2666 char jobarg[64];
2667
2668 if (jp_0 >= 0 && jp_1 >= 0) {
2669 tokenWaitJob.inPipe = jp_0;
2670 tokenWaitJob.outPipe = jp_1;
2671 (void)fcntl(jp_0, F_SETFD, FD_CLOEXEC);
2672 (void)fcntl(jp_1, F_SETFD, FD_CLOEXEC);
2673 return;
2674 }
2675
2676 JobCreatePipe(&tokenWaitJob, 15);
2677
2678 snprintf(jobarg, sizeof jobarg, "%d,%d",
2679 tokenWaitJob.inPipe, tokenWaitJob.outPipe);
2680
2681 Global_Append(MAKEFLAGS, "-J");
2682 Global_Append(MAKEFLAGS, jobarg);
2683
2684 /*
2685 * Preload the job pipe with one token per job, save the one
2686 * "extra" token for the primary job.
2687 *
2688 * XXX should clip maxJobs against PIPE_BUF -- if max_tokens is
2689 * larger than the write buffer size of the pipe, we will
2690 * deadlock here.
2691 */
2692 for (i = 1; i < max_tokens; i++)
2693 JobTokenAdd();
2694 }
2695
2696 /* Return a withdrawn token to the pool. */
2697 void
2698 Job_TokenReturn(void)
2699 {
2700 jobTokensRunning--;
2701 if (jobTokensRunning < 0)
2702 Punt("token botch");
2703 if (jobTokensRunning != 0 || JOB_TOKENS[aborting] != '+')
2704 JobTokenAdd();
2705 }
2706
2707 /*
2708 * Attempt to withdraw a token from the pool.
2709 *
2710 * If the pool is empty, set wantToken so that we wake up when a token is
2711 * released.
2712 *
2713 * Returns true if a token was withdrawn, and false if the pool is currently
2714 * empty.
2715 */
2716 bool
2717 Job_TokenWithdraw(void)
2718 {
2719 char tok, tok1;
2720 ssize_t count;
2721
2722 wantToken = 0;
2723 DEBUG3(JOB, "Job_TokenWithdraw(%d): aborting %d, running %d\n",
2724 getpid(), aborting, jobTokensRunning);
2725
2726 if (aborting != ABORT_NONE || (jobTokensRunning >= opts.maxJobs))
2727 return false;
2728
2729 count = read(tokenWaitJob.inPipe, &tok, 1);
2730 if (count == 0)
2731 Fatal("eof on job pipe!");
2732 if (count < 0 && jobTokensRunning != 0) {
2733 if (errno != EAGAIN)
2734 Fatal("job pipe read: %s", strerror(errno));
2735 DEBUG1(JOB, "(%d) blocked for token\n", getpid());
2736 wantToken = 1;
2737 return false;
2738 }
2739
2740 if (count == 1 && tok != '+') {
2741 /* make being aborted - remove any other job tokens */
2742 DEBUG2(JOB, "(%d) aborted by token %c\n", getpid(), tok);
2743 while (read(tokenWaitJob.inPipe, &tok1, 1) == 1)
2744 continue;
2745 /* And put the stopper back */
2746 while (write(tokenWaitJob.outPipe, &tok, 1) == -1 &&
2747 errno == EAGAIN)
2748 continue;
2749 if (shouldDieQuietly(NULL, 1)) {
2750 Job_Wait();
2751 exit(6);
2752 }
2753 Fatal("A failure has been detected "
2754 "in another branch of the parallel make");
2755 }
2756
2757 if (count == 1 && jobTokensRunning == 0)
2758 /* We didn't want the token really */
2759 while (write(tokenWaitJob.outPipe, &tok, 1) == -1 &&
2760 errno == EAGAIN)
2761 continue;
2762
2763 jobTokensRunning++;
2764 DEBUG1(JOB, "(%d) withdrew token\n", getpid());
2765 return true;
2766 }
2767
2768 /* Make the named target if found, exit if the target fails. */
2769 bool
2770 Job_RunTarget(const char *target, const char *fname)
2771 {
2772 GNode *gn = Targ_FindNode(target);
2773 if (gn == NULL)
2774 return false;
2775
2776 if (fname != NULL)
2777 Var_Set(gn, ALLSRC, fname);
2778
2779 JobRun(gn);
2780 return true;
2781 }
2782
2783 #ifdef USE_SELECT
2784 int
2785 emul_poll(struct pollfd *fd, int nfd, int timeout)
2786 {
2787 fd_set rfds, wfds;
2788 int i, maxfd, nselect, npoll;
2789 struct timeval tv, *tvp;
2790 long usecs;
2791
2792 FD_ZERO(&rfds);
2793 FD_ZERO(&wfds);
2794
2795 maxfd = -1;
2796 for (i = 0; i < nfd; i++) {
2797 fd[i].revents = 0;
2798
2799 if (fd[i].events & POLLIN)
2800 FD_SET(fd[i].fd, &rfds);
2801
2802 if (fd[i].events & POLLOUT)
2803 FD_SET(fd[i].fd, &wfds);
2804
2805 if (fd[i].fd > maxfd)
2806 maxfd = fd[i].fd;
2807 }
2808
2809 if (maxfd >= FD_SETSIZE) {
2810 Punt("Ran out of fd_set slots; "
2811 "recompile with a larger FD_SETSIZE.");
2812 }
2813
2814 if (timeout < 0) {
2815 tvp = NULL;
2816 } else {
2817 usecs = timeout * 1000;
2818 tv.tv_sec = usecs / 1000000;
2819 tv.tv_usec = usecs % 1000000;
2820 tvp = &tv;
2821 }
2822
2823 nselect = select(maxfd + 1, &rfds, &wfds, NULL, tvp);
2824
2825 if (nselect <= 0)
2826 return nselect;
2827
2828 npoll = 0;
2829 for (i = 0; i < nfd; i++) {
2830 if (FD_ISSET(fd[i].fd, &rfds))
2831 fd[i].revents |= POLLIN;
2832
2833 if (FD_ISSET(fd[i].fd, &wfds))
2834 fd[i].revents |= POLLOUT;
2835
2836 if (fd[i].revents)
2837 npoll++;
2838 }
2839
2840 return npoll;
2841 }
2842 #endif /* USE_SELECT */
2843