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