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