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