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