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