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