job.c revision 1.10 1 /* $NetBSD: job.c,v 1.10 1995/06/14 15:19:21 christos 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 #ifndef lint
42 #if 0
43 static char sccsid[] = "@(#)job.c 5.15 (Berkeley) 3/1/91";
44 #else
45 static char rcsid[] = "$NetBSD: job.c,v 1.10 1995/06/14 15:19:21 christos Exp $";
46 #endif
47 #endif /* not lint */
48
49 /*-
50 * job.c --
51 * handle the creation etc. of our child processes.
52 *
53 * Interface:
54 * Job_Make Start the creation of the given target.
55 *
56 * Job_CatchChildren Check for and handle the termination of any
57 * children. This must be called reasonably
58 * frequently to keep the whole make going at
59 * a decent clip, since job table entries aren't
60 * removed until their process is caught this way.
61 * Its single argument is TRUE if the function
62 * should block waiting for a child to terminate.
63 *
64 * Job_CatchOutput Print any output our children have produced.
65 * Should also be called fairly frequently to
66 * keep the user informed of what's going on.
67 * If no output is waiting, it will block for
68 * a time given by the SEL_* constants, below,
69 * or until output is ready.
70 *
71 * Job_Init Called to intialize this module. in addition,
72 * any commands attached to the .BEGIN target
73 * are executed before this function returns.
74 * Hence, the makefile must have been parsed
75 * before this function is called.
76 *
77 * Job_Full Return TRUE if the job table is filled.
78 *
79 * Job_Empty Return TRUE if the job table is completely
80 * empty.
81 *
82 * Job_ParseShell Given the line following a .SHELL target, parse
83 * the line as a shell specification. Returns
84 * FAILURE if the spec was incorrect.
85 *
86 * Job_End Perform any final processing which needs doing.
87 * This includes the execution of any commands
88 * which have been/were attached to the .END
89 * target. It should only be called when the
90 * job table is empty.
91 *
92 * Job_AbortAll Abort all currently running jobs. It doesn't
93 * handle output or do anything for the jobs,
94 * just kills them. It should only be called in
95 * an emergency, as it were.
96 *
97 * Job_CheckCommands Verify that the commands for a target are
98 * ok. Provide them if necessary and possible.
99 *
100 * Job_Touch Update a target without really updating it.
101 *
102 * Job_Wait Wait for all currently-running jobs to finish.
103 */
104
105 #include <sys/types.h>
106 #include <sys/signal.h>
107 #include <sys/stat.h>
108 #include <sys/file.h>
109 #include <sys/time.h>
110 #include <sys/wait.h>
111 #include <fcntl.h>
112 #include <errno.h>
113 #include <stdio.h>
114 #include <string.h>
115 #include <signal.h>
116 #include "make.h"
117 #include "hash.h"
118 #include "dir.h"
119 #include "job.h"
120 #include "pathnames.h"
121
122 extern int errno;
123
124 /*
125 * error handling variables
126 */
127 static int errors = 0; /* number of errors reported */
128 static int aborting = 0; /* why is the make aborting? */
129 #define ABORT_ERROR 1 /* Because of an error */
130 #define ABORT_INTERRUPT 2 /* Because it was interrupted */
131 #define ABORT_WAIT 3 /* Waiting for jobs to finish */
132
133
134 /*
135 * post-make command processing. The node postCommands is really just the
136 * .END target but we keep it around to avoid having to search for it
137 * all the time.
138 */
139 static GNode *postCommands; /* node containing commands to execute when
140 * everything else is done */
141 static int numCommands; /* The number of commands actually printed
142 * for a target. Should this number be
143 * 0, no shell will be executed. */
144
145
146 /*
147 * Return values from JobStart.
148 */
149 #define JOB_RUNNING 0 /* Job is running */
150 #define JOB_ERROR 1 /* Error in starting the job */
151 #define JOB_FINISHED 2 /* The job is already finished */
152 #define JOB_STOPPED 3 /* The job is stopped */
153
154 /*
155 * tfile is the name of a file into which all shell commands are put. It is
156 * used over by removing it before the child shell is executed. The XXXXX in
157 * the string are replaced by the pid of the make process in a 5-character
158 * field with leading zeroes.
159 */
160 static char tfile[] = TMPPAT;
161
162
163 /*
164 * Descriptions for various shells.
165 */
166 static Shell shells[] = {
167 /*
168 * CSH description. The csh can do echo control by playing
169 * with the setting of the 'echo' shell variable. Sadly,
170 * however, it is unable to do error control nicely.
171 */
172 {
173 "csh",
174 TRUE, "unset verbose", "set verbose", "unset verbose", 10,
175 FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"",
176 "v", "e",
177 },
178 /*
179 * SH description. Echo control is also possible and, under
180 * sun UNIX anyway, one can even control error checking.
181 */
182 {
183 "sh",
184 TRUE, "set -", "set -v", "set -", 5,
185 FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n",
186 "v", "e",
187 },
188 /*
189 * UNKNOWN.
190 */
191 {
192 (char *)0,
193 FALSE, (char *)0, (char *)0, (char *)0, 0,
194 FALSE, (char *)0, (char *)0,
195 (char *)0, (char *)0,
196 }
197 };
198 static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to
199 * which we pass all
200 * commands in the Makefile.
201 * It is set by the
202 * Job_ParseShell function */
203 static char *shellPath = (char *) NULL, /* full pathname of
204 * executable image */
205 *shellName; /* last component of shell */
206
207
208 static int maxJobs; /* The most children we can run at once */
209 static int maxLocal; /* The most local ones we can have */
210 int nJobs; /* The number of children currently running */
211 int nLocal; /* The number of local children */
212 Lst jobs; /* The structures that describe them */
213 Boolean jobFull; /* Flag to tell when the job table is full. It
214 * is set TRUE when (1) the total number of
215 * running jobs equals the maximum allowed or
216 * (2) a job can only be run locally, but
217 * nLocal equals maxLocal */
218 #ifndef RMT_WILL_WATCH
219 static fd_set outputs; /* Set of descriptors of pipes connected to
220 * the output channels of children */
221 #endif
222
223 GNode *lastNode; /* The node for which output was most recently
224 * produced. */
225 char *targFmt; /* Format string to use to head output from a
226 * job when it's not the most-recent job heard
227 * from */
228 #define TARG_FMT "--- %s ---\n" /* Default format */
229
230 /*
231 * When JobStart attempts to run a job remotely but can't, and isn't allowed
232 * to run the job locally, or when Job_CatchChildren detects a job that has
233 * been migrated home, the job is placed on the stoppedJobs queue to be run
234 * when the next job finishes.
235 */
236 Lst stoppedJobs; /* Lst of Job structures describing
237 * jobs that were stopped due to concurrency
238 * limits or migration home */
239
240
241 #if defined(USE_PGRP) && defined(SYSV)
242 #define KILL(pid,sig) killpg (-(pid),(sig))
243 #else
244 # if defined(USE_PGRP)
245 #define KILL(pid,sig) killpg ((pid),(sig))
246 # else
247 #define KILL(pid,sig) kill ((pid),(sig))
248 # endif
249 #endif
250
251 static int JobCondPassSig __P((ClientData, ClientData));
252 static void JobPassSig __P((int));
253 static int JobCmpPid __P((ClientData, ClientData));
254 static int JobPrintCommand __P((ClientData, ClientData));
255 static int JobSaveCommand __P((ClientData, ClientData));
256 static void JobFinish __P((Job *, union wait));
257 static void JobExec __P((Job *, char **));
258 static void JobMakeArgv __P((Job *, char **));
259 static void JobRestart __P((Job *));
260 static int JobStart __P((GNode *, int, Job *));
261 static void JobDoOutput __P((Job *, Boolean));
262 static Shell *JobMatchShell __P((char *));
263 static void JobInterrupt __P((int));
264
265 /*-
266 *-----------------------------------------------------------------------
267 * JobCondPassSig --
268 * Pass a signal to a job if the job is remote or if USE_PGRP
269 * is defined.
270 *
271 * Results:
272 * === 0
273 *
274 * Side Effects:
275 * None, except the job may bite it.
276 *
277 *-----------------------------------------------------------------------
278 */
279 static int
280 JobCondPassSig(jobp, signop)
281 ClientData jobp; /* Job to biff */
282 ClientData signop; /* Signal to send it */
283 {
284 Job *job = (Job *) jobp;
285 int signo = *(int *) signop;
286 #ifdef RMT_WANTS_SIGNALS
287 if (job->flags & JOB_REMOTE) {
288 (void)Rmt_Signal(job, signo);
289 } else {
290 KILL(job->pid, signo);
291 }
292 #else
293 /*
294 * Assume that sending the signal to job->pid will signal any remote
295 * job as well.
296 */
297 KILL(job->pid, signo);
298 #endif
299 return(0);
300 }
301
302 /*-
303 *-----------------------------------------------------------------------
304 * JobPassSig --
305 * Pass a signal on to all remote jobs and to all local jobs if
306 * USE_PGRP is defined, then die ourselves.
307 *
308 * Results:
309 * None.
310 *
311 * Side Effects:
312 * We die by the same signal.
313 *
314 *-----------------------------------------------------------------------
315 */
316 static void
317 JobPassSig(signo)
318 int signo; /* The signal number we've received */
319 {
320 int mask;
321
322 Lst_ForEach(jobs, JobCondPassSig, (ClientData)(long)signo);
323
324 /*
325 * Deal with proper cleanup based on the signal received. We only run
326 * the .INTERRUPT target if the signal was in fact an interrupt. The other
327 * three termination signals are more of a "get out *now*" command.
328 */
329 if (signo == SIGINT) {
330 JobInterrupt(TRUE);
331 } else if ((signo == SIGHUP) || (signo == SIGTERM) || (signo == SIGQUIT)) {
332 JobInterrupt(FALSE);
333 }
334
335 /*
336 * Leave gracefully if SIGQUIT, rather than core dumping.
337 */
338 if (signo == SIGQUIT) {
339 Finish(0);
340 }
341
342 /*
343 * Send ourselves the signal now we've given the message to everyone else.
344 * Note we block everything else possible while we're getting the signal.
345 * This ensures that all our jobs get continued when we wake up before
346 * we take any other signal.
347 */
348 mask = sigblock(0);
349 (void) sigsetmask(~0 & ~(1 << (signo-1)));
350 signal(signo, SIG_DFL);
351
352 kill(getpid(), signo);
353
354 signo = SIGCONT;
355 Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
356
357 sigsetmask(mask);
358 signal(signo, JobPassSig);
359
360 }
361
362 /*-
363 *-----------------------------------------------------------------------
364 * JobCmpPid --
365 * Compare the pid of the job with the given pid and return 0 if they
366 * are equal. This function is called from Job_CatchChildren via
367 * Lst_Find to find the job descriptor of the finished job.
368 *
369 * Results:
370 * 0 if the pid's match
371 *
372 * Side Effects:
373 * None
374 *-----------------------------------------------------------------------
375 */
376 static int
377 JobCmpPid (job, pid)
378 ClientData job; /* job to examine */
379 ClientData pid; /* process id desired */
380 {
381 return ( *(int *) pid - ((Job *) job)->pid);
382 }
383
384 /*-
385 *-----------------------------------------------------------------------
386 * JobPrintCommand --
387 * Put out another command for the given job. If the command starts
388 * with an @ or a - we process it specially. In the former case,
389 * so long as the -s and -n flags weren't given to make, we stick
390 * a shell-specific echoOff command in the script. In the latter,
391 * we ignore errors for the entire job, unless the shell has error
392 * control.
393 * If the command is just "..." we take all future commands for this
394 * job to be commands to be executed once the entire graph has been
395 * made and return non-zero to signal that the end of the commands
396 * was reached. These commands are later attached to the postCommands
397 * node and executed by Job_End when all things are done.
398 * This function is called from JobStart via Lst_ForEach.
399 *
400 * Results:
401 * Always 0, unless the command was "..."
402 *
403 * Side Effects:
404 * If the command begins with a '-' and the shell has no error control,
405 * the JOB_IGNERR flag is set in the job descriptor.
406 * If the command is "..." and we're not ignoring such things,
407 * tailCmds is set to the successor node of the cmd.
408 * numCommands is incremented if the command is actually printed.
409 *-----------------------------------------------------------------------
410 */
411 static int
412 JobPrintCommand (cmdp, jobp)
413 ClientData cmdp; /* command string to print */
414 ClientData jobp; /* job for which to print it */
415 {
416 Boolean noSpecials; /* true if we shouldn't worry about
417 * inserting special commands into
418 * the input stream. */
419 Boolean shutUp = FALSE; /* true if we put a no echo command
420 * into the command file */
421 Boolean errOff = FALSE; /* true if we turned error checking
422 * off before printing the command
423 * and need to turn it back on */
424 char *cmdTemplate; /* Template to use when printing the
425 * command */
426 char *cmdStart; /* Start of expanded command */
427 LstNode cmdNode; /* Node for replacing the command */
428 char *cmd = (char *) cmdp;
429 Job *job = (Job *) jobp;
430
431 noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
432
433 if (strcmp (cmd, "...") == 0) {
434 job->node->type |= OP_SAVE_CMDS;
435 if ((job->flags & JOB_IGNDOTS) == 0) {
436 job->tailCmds = Lst_Succ (Lst_Member (job->node->commands,
437 (ClientData)cmd));
438 return (1);
439 }
440 return (0);
441 }
442
443 #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) printf (fmt, arg); fprintf (job->cmdFILE, fmt, arg)
444
445 numCommands += 1;
446
447 /*
448 * For debugging, we replace each command with the result of expanding
449 * the variables in the command.
450 */
451 cmdNode = Lst_Member (job->node->commands, (ClientData)cmd);
452 cmdStart = cmd = Var_Subst (NULL, cmd, job->node, FALSE);
453 Lst_Replace (cmdNode, (ClientData)cmdStart);
454
455 cmdTemplate = "%s\n";
456
457 /*
458 * Check for leading @' and -'s to control echoing and error checking.
459 */
460 while (*cmd == '@' || *cmd == '-') {
461 if (*cmd == '@') {
462 shutUp = TRUE;
463 } else {
464 errOff = TRUE;
465 }
466 cmd++;
467 }
468
469 while (isspace((unsigned char) *cmd))
470 cmd++;
471
472 if (shutUp) {
473 if (! (job->flags & JOB_SILENT) && !noSpecials &&
474 commandShell->hasEchoCtl) {
475 DBPRINTF ("%s\n", commandShell->echoOff);
476 } else {
477 shutUp = FALSE;
478 }
479 }
480
481 if (errOff) {
482 if ( ! (job->flags & JOB_IGNERR) && !noSpecials) {
483 if (commandShell->hasErrCtl) {
484 /*
485 * we don't want the error-control commands showing
486 * up either, so we turn off echoing while executing
487 * them. We could put another field in the shell
488 * structure to tell JobDoOutput to look for this
489 * string too, but why make it any more complex than
490 * it already is?
491 */
492 if (! (job->flags & JOB_SILENT) && !shutUp &&
493 commandShell->hasEchoCtl) {
494 DBPRINTF ("%s\n", commandShell->echoOff);
495 DBPRINTF ("%s\n", commandShell->ignErr);
496 DBPRINTF ("%s\n", commandShell->echoOn);
497 } else {
498 DBPRINTF ("%s\n", commandShell->ignErr);
499 }
500 } else if (commandShell->ignErr &&
501 (*commandShell->ignErr != '\0'))
502 {
503 /*
504 * The shell has no error control, so we need to be
505 * weird to get it to ignore any errors from the command.
506 * If echoing is turned on, we turn it off and use the
507 * errCheck template to echo the command. Leave echoing
508 * off so the user doesn't see the weirdness we go through
509 * to ignore errors. Set cmdTemplate to use the weirdness
510 * instead of the simple "%s\n" template.
511 */
512 if (! (job->flags & JOB_SILENT) && !shutUp &&
513 commandShell->hasEchoCtl) {
514 DBPRINTF ("%s\n", commandShell->echoOff);
515 DBPRINTF (commandShell->errCheck, cmd);
516 shutUp = TRUE;
517 }
518 cmdTemplate = commandShell->ignErr;
519 /*
520 * The error ignoration (hee hee) is already taken care
521 * of by the ignErr template, so pretend error checking
522 * is still on.
523 */
524 errOff = FALSE;
525 } else {
526 errOff = FALSE;
527 }
528 } else {
529 errOff = FALSE;
530 }
531 }
532
533 DBPRINTF (cmdTemplate, cmd);
534
535 if (errOff) {
536 /*
537 * If echoing is already off, there's no point in issuing the
538 * echoOff command. Otherwise we issue it and pretend it was on
539 * for the whole command...
540 */
541 if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
542 DBPRINTF ("%s\n", commandShell->echoOff);
543 shutUp = TRUE;
544 }
545 DBPRINTF ("%s\n", commandShell->errCheck);
546 }
547 if (shutUp) {
548 DBPRINTF ("%s\n", commandShell->echoOn);
549 }
550 return (0);
551 }
552
553 /*-
554 *-----------------------------------------------------------------------
555 * JobSaveCommand --
556 * Save a command to be executed when everything else is done.
557 * Callback function for JobFinish...
558 *
559 * Results:
560 * Always returns 0
561 *
562 * Side Effects:
563 * The command is tacked onto the end of postCommands's commands list.
564 *
565 *-----------------------------------------------------------------------
566 */
567 static int
568 JobSaveCommand (cmd, gn)
569 ClientData cmd;
570 ClientData gn;
571 {
572 cmd = (ClientData) Var_Subst (NULL, (char *) cmd, (GNode *) gn, FALSE);
573 (void)Lst_AtEnd (postCommands->commands, cmd);
574 return (0);
575 }
576
577 /*-
578 *-----------------------------------------------------------------------
579 * JobFinish --
580 * Do final processing for the given job including updating
581 * parents and starting new jobs as available/necessary. Note
582 * that we pay no attention to the JOB_IGNERR flag here.
583 * This is because when we're called because of a noexecute flag
584 * or something, jstat.w_status is 0 and when called from
585 * Job_CatchChildren, the status is zeroed if it s/b ignored.
586 *
587 * Results:
588 * None
589 *
590 * Side Effects:
591 * Some nodes may be put on the toBeMade queue.
592 * Final commands for the job are placed on postCommands.
593 *
594 * If we got an error and are aborting (aborting == ABORT_ERROR) and
595 * the job list is now empty, we are done for the day.
596 * If we recognized an error (errors !=0), we set the aborting flag
597 * to ABORT_ERROR so no more jobs will be started.
598 *-----------------------------------------------------------------------
599 */
600 /*ARGSUSED*/
601 static void
602 JobFinish (job, status)
603 Job *job; /* job to finish */
604 union wait status; /* sub-why job went away */
605 {
606 Boolean done;
607
608 if ((WIFEXITED(status) &&
609 (((status.w_retcode != 0) && !(job->flags & JOB_IGNERR)))) ||
610 (WIFSIGNALED(status) && (status.w_termsig != SIGCONT)))
611 {
612 /*
613 * If it exited non-zero and either we're doing things our
614 * way or we're not ignoring errors, the job is finished.
615 * Similarly, if the shell died because of a signal
616 * the job is also finished. In these
617 * cases, finish out the job's output before printing the exit
618 * status...
619 */
620 if (usePipes) {
621 #ifdef RMT_WILL_WATCH
622 Rmt_Ignore(job->inPipe);
623 #else
624 FD_CLR(job->inPipe, &outputs);
625 #endif /* RMT_WILL_WATCH */
626 if (job->outPipe != job->inPipe) {
627 (void)close (job->outPipe);
628 }
629 JobDoOutput (job, TRUE);
630 (void)close (job->inPipe);
631 } else {
632 (void)close (job->outFd);
633 JobDoOutput (job, TRUE);
634 }
635
636 if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
637 fclose(job->cmdFILE);
638 }
639 done = TRUE;
640 } else if (WIFEXITED(status) && status.w_retcode != 0) {
641 /*
642 * Deal with ignored errors in -B mode. We need to print a message
643 * telling of the ignored error as well as setting status.w_status
644 * to 0 so the next command gets run. To do this, we set done to be
645 * TRUE if in -B mode and the job exited non-zero. Note we don't
646 * want to close down any of the streams until we know we're at the
647 * end.
648 */
649 done = TRUE;
650 } else {
651 /*
652 * No need to close things down or anything.
653 */
654 done = FALSE;
655 }
656
657 if (done ||
658 WIFSTOPPED(status) ||
659 (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) ||
660 DEBUG(JOB))
661 {
662 FILE *out;
663
664 if (!usePipes && (job->flags & JOB_IGNERR)) {
665 /*
666 * If output is going to a file and this job is ignoring
667 * errors, arrange to have the exit status sent to the
668 * output file as well.
669 */
670 out = fdopen (job->outFd, "w");
671 } else {
672 out = stdout;
673 }
674
675 if (WIFEXITED(status)) {
676 if (status.w_retcode != 0) {
677 if (usePipes && job->node != lastNode) {
678 fprintf (out, targFmt, job->node->name);
679 lastNode = job->node;
680 }
681 fprintf (out, "*** Error code %d%s\n", status.w_retcode,
682 (job->flags & JOB_IGNERR) ? " (ignored)" : "");
683
684 if (job->flags & JOB_IGNERR) {
685 status.w_status = 0;
686 }
687 } else if (DEBUG(JOB)) {
688 if (usePipes && job->node != lastNode) {
689 fprintf (out, targFmt, job->node->name);
690 lastNode = job->node;
691 }
692 fprintf (out, "*** Completed successfully\n");
693 }
694 } else if (WIFSTOPPED(status)) {
695 if (usePipes && job->node != lastNode) {
696 fprintf (out, targFmt, job->node->name);
697 lastNode = job->node;
698 }
699 if (! (job->flags & JOB_REMIGRATE)) {
700 fprintf (out, "*** Stopped -- signal %d\n", status.w_stopsig);
701 }
702 job->flags |= JOB_RESUME;
703 (void)Lst_AtEnd(stoppedJobs, (ClientData)job);
704 fflush(out);
705 return;
706 } else if (status.w_termsig == SIGCONT) {
707 /*
708 * If the beastie has continued, shift the Job from the stopped
709 * list to the running one (or re-stop it if concurrency is
710 * exceeded) and go and get another child.
711 */
712 if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) {
713 if (usePipes && job->node != lastNode) {
714 fprintf (out, targFmt, job->node->name);
715 lastNode = job->node;
716 }
717 fprintf (out, "*** Continued\n");
718 }
719 if (! (job->flags & JOB_CONTINUING)) {
720 JobRestart(job);
721 } else {
722 Lst_AtEnd(jobs, (ClientData)job);
723 nJobs += 1;
724 if (! (job->flags & JOB_REMOTE)) {
725 nLocal += 1;
726 }
727 if (nJobs == maxJobs) {
728 jobFull = TRUE;
729 if (DEBUG(JOB)) {
730 printf("Job queue is full.\n");
731 }
732 }
733 }
734 fflush(out);
735 return;
736 } else {
737 if (usePipes && job->node != lastNode) {
738 fprintf (out, targFmt, job->node->name);
739 lastNode = job->node;
740 }
741 fprintf (out, "*** Signal %d\n", status.w_termsig);
742 }
743
744 fflush (out);
745 }
746
747 /*
748 * Now handle the -B-mode stuff. If the beast still isn't finished,
749 * try and restart the job on the next command. If JobStart says it's
750 * ok, it's ok. If there's an error, this puppy is done.
751 */
752 if ((status.w_status == 0) &&
753 !Lst_IsAtEnd (job->node->commands))
754 {
755 switch (JobStart (job->node,
756 job->flags & JOB_IGNDOTS,
757 job))
758 {
759 case JOB_RUNNING:
760 done = FALSE;
761 break;
762 case JOB_ERROR:
763 done = TRUE;
764 status.w_retcode = 1;
765 break;
766 case JOB_FINISHED:
767 /*
768 * If we got back a JOB_FINISHED code, JobStart has already
769 * called Make_Update and freed the job descriptor. We set
770 * done to false here to avoid fake cycles and double frees.
771 * JobStart needs to do the update so we can proceed up the
772 * graph when given the -n flag..
773 */
774 done = FALSE;
775 break;
776 }
777 } else {
778 done = TRUE;
779 }
780
781
782 if (done &&
783 (aborting != ABORT_ERROR) &&
784 (aborting != ABORT_INTERRUPT) &&
785 (status.w_status == 0))
786 {
787 /*
788 * As long as we aren't aborting and the job didn't return a non-zero
789 * status that we shouldn't ignore, we call Make_Update to update
790 * the parents. In addition, any saved commands for the node are placed
791 * on the .END target.
792 */
793 if (job->tailCmds != NILLNODE) {
794 Lst_ForEachFrom (job->node->commands, job->tailCmds,
795 JobSaveCommand,
796 (ClientData)job->node);
797 }
798 job->node->made = MADE;
799 Make_Update (job->node);
800 free((Address)job);
801 } else if (status.w_status) {
802 errors += 1;
803 free((Address)job);
804 }
805
806 while (!errors && !jobFull && !Lst_IsEmpty(stoppedJobs)) {
807 JobRestart((Job *)Lst_DeQueue(stoppedJobs));
808 }
809
810 /*
811 * Set aborting if any error.
812 */
813 if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) {
814 /*
815 * If we found any errors in this batch of children and the -k flag
816 * wasn't given, we set the aborting flag so no more jobs get
817 * started.
818 */
819 aborting = ABORT_ERROR;
820 }
821
822 if ((aborting == ABORT_ERROR) && Job_Empty()) {
823 /*
824 * If we are aborting and the job table is now empty, we finish.
825 */
826 (void) unlink (tfile);
827 Finish (errors);
828 }
829 }
830
831 /*-
832 *-----------------------------------------------------------------------
833 * Job_Touch --
834 * Touch the given target. Called by JobStart when the -t flag was
835 * given
836 *
837 * Results:
838 * None
839 *
840 * Side Effects:
841 * The data modification of the file is changed. In addition, if the
842 * file did not exist, it is created.
843 *-----------------------------------------------------------------------
844 */
845 void
846 Job_Touch (gn, silent)
847 GNode *gn; /* the node of the file to touch */
848 Boolean silent; /* TRUE if should not print messages */
849 {
850 int streamID; /* ID of stream opened to do the touch */
851 struct timeval times[2]; /* Times for utimes() call */
852
853 if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
854 /*
855 * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets
856 * and, as such, shouldn't really be created.
857 */
858 return;
859 }
860
861 if (!silent) {
862 printf ("touch %s\n", gn->name);
863 }
864
865 if (noExecute) {
866 return;
867 }
868
869 if (gn->type & OP_ARCHV) {
870 Arch_Touch (gn);
871 } else if (gn->type & OP_LIB) {
872 Arch_TouchLib (gn);
873 } else {
874 char *file = gn->path ? gn->path : gn->name;
875
876 times[0].tv_sec = times[1].tv_sec = now;
877 times[0].tv_usec = times[1].tv_usec = 0;
878 if (utimes(file, times) < 0){
879 streamID = open (file, O_RDWR | O_CREAT, 0666);
880
881 if (streamID >= 0) {
882 char c;
883
884 /*
885 * Read and write a byte to the file to change the
886 * modification time, then close the file.
887 */
888 if (read(streamID, &c, 1) == 1) {
889 lseek(streamID, 0L, L_SET);
890 write(streamID, &c, 1);
891 }
892
893 (void)close (streamID);
894 } else
895 printf("*** couldn't touch %s: %s", file, strerror(errno));
896 }
897 }
898 }
899
900 /*-
901 *-----------------------------------------------------------------------
902 * Job_CheckCommands --
903 * Make sure the given node has all the commands it needs.
904 *
905 * Results:
906 * TRUE if the commands list is/was ok.
907 *
908 * Side Effects:
909 * The node will have commands from the .DEFAULT rule added to it
910 * if it needs them.
911 *-----------------------------------------------------------------------
912 */
913 Boolean
914 Job_CheckCommands (gn, abortProc)
915 GNode *gn; /* The target whose commands need
916 * verifying */
917 void (*abortProc) __P((char *, ...));
918 /* Function to abort with message */
919 {
920 if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
921 (gn->type & OP_LIB) == 0) {
922 /*
923 * No commands. Look for .DEFAULT rule from which we might infer
924 * commands
925 */
926 if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) {
927 char *p1;
928 /*
929 * Make only looks for a .DEFAULT if the node was never the
930 * target of an operator, so that's what we do too. If
931 * a .DEFAULT was given, we substitute its commands for gn's
932 * commands and set the IMPSRC variable to be the target's name
933 * The DEFAULT node acts like a transformation rule, in that
934 * gn also inherits any attributes or sources attached to
935 * .DEFAULT itself.
936 */
937 Make_HandleUse(DEFAULT, gn);
938 Var_Set (IMPSRC, Var_Value (TARGET, gn, &p1), gn);
939 if (p1)
940 free(p1);
941 } else if (Dir_MTime (gn) == 0) {
942 /*
943 * The node wasn't the target of an operator we have no .DEFAULT
944 * rule to go on and the target doesn't already exist. There's
945 * nothing more we can do for this branch. If the -k flag wasn't
946 * given, we stop in our tracks, otherwise we just don't update
947 * this node's parents so they never get examined.
948 */
949 if (gn->type & OP_OPTIONAL) {
950 printf ("make: don't know how to make %s (ignored)\n",
951 gn->name);
952 } else if (keepgoing) {
953 printf ("make: don't know how to make %s (continuing)\n",
954 gn->name);
955 return (FALSE);
956 } else {
957 (*abortProc) ("make: don't know how to make %s. Stop",
958 gn->name);
959 return(FALSE);
960 }
961 }
962 }
963 return (TRUE);
964 }
965 #ifdef RMT_WILL_WATCH
966 /*-
967 *-----------------------------------------------------------------------
968 * JobLocalInput --
969 * Handle a pipe becoming readable. Callback function for Rmt_Watch
970 *
971 * Results:
972 * None
973 *
974 * Side Effects:
975 * JobDoOutput is called.
976 *
977 *-----------------------------------------------------------------------
978 */
979 /*ARGSUSED*/
980 static void
981 JobLocalInput(stream, job)
982 int stream; /* Stream that's ready (ignored) */
983 Job *job; /* Job to which the stream belongs */
984 {
985 JobDoOutput(job, FALSE);
986 }
987 #endif /* RMT_WILL_WATCH */
988
989 /*-
990 *-----------------------------------------------------------------------
991 * JobExec --
992 * Execute the shell for the given job. Called from JobStart and
993 * JobRestart.
994 *
995 * Results:
996 * None.
997 *
998 * Side Effects:
999 * A shell is executed, outputs is altered and the Job structure added
1000 * to the job table.
1001 *
1002 *-----------------------------------------------------------------------
1003 */
1004 static void
1005 JobExec(job, argv)
1006 Job *job; /* Job to execute */
1007 char **argv;
1008 {
1009 int cpid; /* ID of new child */
1010
1011 if (DEBUG(JOB)) {
1012 int i;
1013
1014 printf("Running %s %sly\n", job->node->name,
1015 job->flags&JOB_REMOTE?"remote":"local");
1016 printf("\tCommand: ");
1017 for (i = 0; argv[i] != (char *)NULL; i++) {
1018 printf("%s ", argv[i]);
1019 }
1020 printf("\n");
1021 }
1022
1023 /*
1024 * Some jobs produce no output and it's disconcerting to have
1025 * no feedback of their running (since they produce no output, the
1026 * banner with their name in it never appears). This is an attempt to
1027 * provide that feedback, even if nothing follows it.
1028 */
1029 if ((lastNode != job->node) && (job->flags & JOB_FIRST) &&
1030 !(job->flags & JOB_SILENT))
1031 {
1032 printf(targFmt, job->node->name);
1033 lastNode = job->node;
1034 }
1035
1036 #ifdef RMT_NO_EXEC
1037 if (job->flags & JOB_REMOTE) {
1038 goto jobExecFinish;
1039 }
1040 #endif /* RMT_NO_EXEC */
1041
1042 if ((cpid = vfork()) == -1) {
1043 Punt ("Cannot fork");
1044 } else if (cpid == 0) {
1045
1046 /*
1047 * Must duplicate the input stream down to the child's input and
1048 * reset it to the beginning (again). Since the stream was marked
1049 * close-on-exec, we must clear that bit in the new input.
1050 */
1051 (void) dup2(fileno(job->cmdFILE), 0);
1052 fcntl(0, F_SETFD, 0);
1053 lseek(0, 0, L_SET);
1054
1055 if (usePipes) {
1056 /*
1057 * Set up the child's output to be routed through the pipe
1058 * we've created for it.
1059 */
1060 (void) dup2 (job->outPipe, 1);
1061 } else {
1062 /*
1063 * We're capturing output in a file, so we duplicate the
1064 * descriptor to the temporary file into the standard
1065 * output.
1066 */
1067 (void) dup2 (job->outFd, 1);
1068 }
1069 /*
1070 * The output channels are marked close on exec. This bit was
1071 * duplicated by the dup2 (on some systems), so we have to clear
1072 * it before routing the shell's error output to the same place as
1073 * its standard output.
1074 */
1075 fcntl(1, F_SETFD, 0);
1076 (void) dup2 (1, 2);
1077
1078 #ifdef USE_PGRP
1079 /*
1080 * We want to switch the child into a different process family so
1081 * we can kill it and all its descendants in one fell swoop,
1082 * by killing its process family, but not commit suicide.
1083 */
1084
1085 (void) setpgrp(0, getpid());
1086 #endif USE_PGRP
1087
1088 (void) execv (shellPath, argv);
1089 (void) write (2, "Could not execute shell\n",
1090 sizeof ("Could not execute shell"));
1091 _exit (1);
1092 } else {
1093 job->pid = cpid;
1094
1095 if (usePipes && (job->flags & JOB_FIRST) ) {
1096 /*
1097 * The first time a job is run for a node, we set the current
1098 * position in the buffer to the beginning and mark another
1099 * stream to watch in the outputs mask
1100 */
1101 job->curPos = 0;
1102
1103 #ifdef RMT_WILL_WATCH
1104 Rmt_Watch(job->inPipe, JobLocalInput, job);
1105 #else
1106 FD_SET(job->inPipe, &outputs);
1107 #endif /* RMT_WILL_WATCH */
1108 }
1109
1110 if (job->flags & JOB_REMOTE) {
1111 job->rmtID = 0;
1112 } else {
1113 nLocal += 1;
1114 /*
1115 * XXX: Used to not happen if CUSTOMS. Why?
1116 */
1117 if (job->cmdFILE != stdout) {
1118 fclose(job->cmdFILE);
1119 job->cmdFILE = NULL;
1120 }
1121 }
1122 }
1123
1124 #ifdef RMT_NO_EXEC
1125 jobExecFinish:
1126 #endif
1127 /*
1128 * Now the job is actually running, add it to the table.
1129 */
1130 nJobs += 1;
1131 (void)Lst_AtEnd (jobs, (ClientData)job);
1132 if (nJobs == maxJobs) {
1133 jobFull = TRUE;
1134 }
1135 }
1136
1137 /*-
1138 *-----------------------------------------------------------------------
1139 * JobMakeArgv --
1140 * Create the argv needed to execute the shell for a given job.
1141 *
1142 *
1143 * Results:
1144 *
1145 * Side Effects:
1146 *
1147 *-----------------------------------------------------------------------
1148 */
1149 static void
1150 JobMakeArgv(job, argv)
1151 Job *job;
1152 char **argv;
1153 {
1154 int argc;
1155 static char args[10]; /* For merged arguments */
1156
1157 argv[0] = shellName;
1158 argc = 1;
1159
1160 if ((commandShell->exit && (*commandShell->exit != '-')) ||
1161 (commandShell->echo && (*commandShell->echo != '-')))
1162 {
1163 /*
1164 * At least one of the flags doesn't have a minus before it, so
1165 * merge them together. Have to do this because the *(&(@*#*&#$#
1166 * Bourne shell thinks its second argument is a file to source.
1167 * Grrrr. Note the ten-character limitation on the combined arguments.
1168 */
1169 (void)sprintf(args, "-%s%s",
1170 ((job->flags & JOB_IGNERR) ? "" :
1171 (commandShell->exit ? commandShell->exit : "")),
1172 ((job->flags & JOB_SILENT) ? "" :
1173 (commandShell->echo ? commandShell->echo : "")));
1174
1175 if (args[1]) {
1176 argv[argc] = args;
1177 argc++;
1178 }
1179 } else {
1180 if (!(job->flags & JOB_IGNERR) && commandShell->exit) {
1181 argv[argc] = commandShell->exit;
1182 argc++;
1183 }
1184 if (!(job->flags & JOB_SILENT) && commandShell->echo) {
1185 argv[argc] = commandShell->echo;
1186 argc++;
1187 }
1188 }
1189 argv[argc] = (char *)NULL;
1190 }
1191
1192 /*-
1193 *-----------------------------------------------------------------------
1194 * JobRestart --
1195 * Restart a job that stopped for some reason.
1196 *
1197 * Results:
1198 * None.
1199 *
1200 * Side Effects:
1201 * jobFull will be set if the job couldn't be run.
1202 *
1203 *-----------------------------------------------------------------------
1204 */
1205 static void
1206 JobRestart(job)
1207 Job *job; /* Job to restart */
1208 {
1209 if (job->flags & JOB_REMIGRATE) {
1210 if (DEBUG(JOB)) {
1211 printf("Remigrating %x\n", job->pid);
1212 }
1213 if (nLocal != maxLocal) {
1214 /*
1215 * Job cannot be remigrated, but there's room on the local
1216 * machine, so resume the job and note that another
1217 * local job has started.
1218 */
1219 if (DEBUG(JOB)) {
1220 printf("resuming on local machine\n");
1221 }
1222 KILL(job->pid, SIGCONT);
1223 nLocal +=1;
1224 job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
1225 } else {
1226 /*
1227 * Job cannot be restarted. Mark the table as full and
1228 * place the job back on the list of stopped jobs.
1229 */
1230 if (DEBUG(JOB)) {
1231 printf("holding\n");
1232 }
1233 (void)Lst_AtFront(stoppedJobs, (ClientData)job);
1234 jobFull = TRUE;
1235 if (DEBUG(JOB)) {
1236 printf("Job queue is full.\n");
1237 }
1238 return;
1239 }
1240
1241 (void)Lst_AtEnd(jobs, (ClientData)job);
1242 nJobs += 1;
1243 if (nJobs == maxJobs) {
1244 jobFull = TRUE;
1245 if (DEBUG(JOB)) {
1246 printf("Job queue is full.\n");
1247 }
1248 }
1249 } else if (job->flags & JOB_RESTART) {
1250 /*
1251 * Set up the control arguments to the shell. This is based on the
1252 * flags set earlier for this job. If the JOB_IGNERR flag is clear,
1253 * the 'exit' flag of the commandShell is used to cause it to exit
1254 * upon receiving an error. If the JOB_SILENT flag is clear, the
1255 * 'echo' flag of the commandShell is used to get it to start echoing
1256 * as soon as it starts processing commands.
1257 */
1258 char *argv[4];
1259
1260 JobMakeArgv(job, argv);
1261
1262 if (DEBUG(JOB)) {
1263 printf("Restarting %s...", job->node->name);
1264 }
1265 if (((nLocal >= maxLocal) && ! (job->flags & JOB_SPECIAL))) {
1266 /*
1267 * Can't be exported and not allowed to run locally -- put it
1268 * back on the hold queue and mark the table full
1269 */
1270 if (DEBUG(JOB)) {
1271 printf("holding\n");
1272 }
1273 (void)Lst_AtFront(stoppedJobs, (ClientData)job);
1274 jobFull = TRUE;
1275 if (DEBUG(JOB)) {
1276 printf("Job queue is full.\n");
1277 }
1278 return;
1279 } else {
1280 /*
1281 * Job may be run locally.
1282 */
1283 if (DEBUG(JOB)) {
1284 printf("running locally\n");
1285 }
1286 job->flags &= ~JOB_REMOTE;
1287 }
1288 JobExec(job, argv);
1289 } else {
1290 /*
1291 * The job has stopped and needs to be restarted. Why it stopped,
1292 * we don't know...
1293 */
1294 if (DEBUG(JOB)) {
1295 printf("Resuming %s...", job->node->name);
1296 }
1297 if (((job->flags & JOB_REMOTE) ||
1298 (nLocal < maxLocal) ||
1299 (((job->flags & JOB_SPECIAL)) &&
1300 (maxLocal == 0))) &&
1301 (nJobs != maxJobs))
1302 {
1303 /*
1304 * If the job is remote, it's ok to resume it as long as the
1305 * maximum concurrency won't be exceeded. If it's local and
1306 * we haven't reached the local concurrency limit already (or the
1307 * job must be run locally and maxLocal is 0), it's also ok to
1308 * resume it.
1309 */
1310 Boolean error;
1311 extern int errno;
1312 union wait status;
1313
1314 #ifdef RMT_WANTS_SIGNALS
1315 if (job->flags & JOB_REMOTE) {
1316 error = !Rmt_Signal(job, SIGCONT);
1317 } else
1318 #endif /* RMT_WANTS_SIGNALS */
1319 error = (KILL(job->pid, SIGCONT) != 0);
1320
1321 if (!error) {
1322 /*
1323 * Make sure the user knows we've continued the beast and
1324 * actually put the thing in the job table.
1325 */
1326 job->flags |= JOB_CONTINUING;
1327 status.w_termsig = SIGCONT;
1328 JobFinish(job, status);
1329
1330 job->flags &= ~(JOB_RESUME|JOB_CONTINUING);
1331 if (DEBUG(JOB)) {
1332 printf("done\n");
1333 }
1334 } else {
1335 Error("couldn't resume %s: %s",
1336 job->node->name, strerror(errno));
1337 status.w_status = 0;
1338 status.w_retcode = 1;
1339 JobFinish(job, status);
1340 }
1341 } else {
1342 /*
1343 * Job cannot be restarted. Mark the table as full and
1344 * place the job back on the list of stopped jobs.
1345 */
1346 if (DEBUG(JOB)) {
1347 printf("table full\n");
1348 }
1349 (void)Lst_AtFront(stoppedJobs, (ClientData)job);
1350 jobFull = TRUE;
1351 if (DEBUG(JOB)) {
1352 printf("Job queue is full.\n");
1353 }
1354 }
1355 }
1356 }
1357
1358 /*-
1359 *-----------------------------------------------------------------------
1360 * JobStart --
1361 * Start a target-creation process going for the target described
1362 * by the graph node gn.
1363 *
1364 * Results:
1365 * JOB_ERROR if there was an error in the commands, JOB_FINISHED
1366 * if there isn't actually anything left to do for the job and
1367 * JOB_RUNNING if the job has been started.
1368 *
1369 * Side Effects:
1370 * A new Job node is created and added to the list of running
1371 * jobs. PMake is forked and a child shell created.
1372 *-----------------------------------------------------------------------
1373 */
1374 static int
1375 JobStart (gn, flags, previous)
1376 GNode *gn; /* target to create */
1377 int flags; /* flags for the job to override normal ones.
1378 * e.g. JOB_SPECIAL or JOB_IGNDOTS */
1379 Job *previous; /* The previous Job structure for this node,
1380 * if any. */
1381 {
1382 register Job *job; /* new job descriptor */
1383 char *argv[4]; /* Argument vector to shell */
1384 static int jobno = 0; /* job number of catching output in a file */
1385 Boolean cmdsOK; /* true if the nodes commands were all right */
1386 Boolean local; /* Set true if the job was run locally */
1387 Boolean noExec; /* Set true if we decide not to run the job */
1388
1389 if (previous != (Job *)NULL) {
1390 previous->flags &= ~ (JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
1391 job = previous;
1392 } else {
1393 job = (Job *) emalloc (sizeof (Job));
1394 if (job == (Job *)NULL) {
1395 Punt("JobStart out of memory");
1396 }
1397 flags |= JOB_FIRST;
1398 }
1399
1400 job->node = gn;
1401 job->tailCmds = NILLNODE;
1402
1403 /*
1404 * Set the initial value of the flags for this job based on the global
1405 * ones and the node's attributes... Any flags supplied by the caller
1406 * are also added to the field.
1407 */
1408 job->flags = 0;
1409 if (Targ_Ignore (gn)) {
1410 job->flags |= JOB_IGNERR;
1411 }
1412 if (Targ_Silent (gn)) {
1413 job->flags |= JOB_SILENT;
1414 }
1415 job->flags |= flags;
1416
1417 /*
1418 * Check the commands now so any attributes from .DEFAULT have a chance
1419 * to migrate to the node
1420 */
1421 if (job->flags & JOB_FIRST) {
1422 cmdsOK = Job_CheckCommands(gn, Error);
1423 } else {
1424 cmdsOK = TRUE;
1425 }
1426
1427 /*
1428 * If the -n flag wasn't given, we open up OUR (not the child's)
1429 * temporary file to stuff commands in it. The thing is rd/wr so we don't
1430 * need to reopen it to feed it to the shell. If the -n flag *was* given,
1431 * we just set the file to be stdout. Cute, huh?
1432 */
1433 if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) {
1434 /*
1435 * We're serious here, but if the commands were bogus, we're
1436 * also dead...
1437 */
1438 if (!cmdsOK) {
1439 DieHorribly();
1440 }
1441
1442 job->cmdFILE = fopen (tfile, "w+");
1443 if (job->cmdFILE == (FILE *) NULL) {
1444 Punt ("Could not open %s", tfile);
1445 }
1446 fcntl(fileno(job->cmdFILE), F_SETFD, 1);
1447 /*
1448 * Send the commands to the command file, flush all its buffers then
1449 * rewind and remove the thing.
1450 */
1451 noExec = FALSE;
1452
1453 /*
1454 * used to be backwards; replace when start doing multiple commands
1455 * per shell.
1456 */
1457 if (compatMake) {
1458 /*
1459 * Be compatible: If this is the first time for this node,
1460 * verify its commands are ok and open the commands list for
1461 * sequential access by later invocations of JobStart.
1462 * Once that is done, we take the next command off the list
1463 * and print it to the command file. If the command was an
1464 * ellipsis, note that there's nothing more to execute.
1465 */
1466 if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){
1467 cmdsOK = FALSE;
1468 } else {
1469 LstNode ln = Lst_Next (gn->commands);
1470
1471 if ((ln == NILLNODE) ||
1472 JobPrintCommand ((char *)Lst_Datum (ln), job))
1473 {
1474 noExec = TRUE;
1475 Lst_Close (gn->commands);
1476 }
1477 if (noExec && !(job->flags & JOB_FIRST)) {
1478 /*
1479 * If we're not going to execute anything, the job
1480 * is done and we need to close down the various
1481 * file descriptors we've opened for output, then
1482 * call JobDoOutput to catch the final characters or
1483 * send the file to the screen... Note that the i/o streams
1484 * are only open if this isn't the first job.
1485 * Note also that this could not be done in
1486 * Job_CatchChildren b/c it wasn't clear if there were
1487 * more commands to execute or not...
1488 */
1489 if (usePipes) {
1490 #ifdef RMT_WILL_WATCH
1491 Rmt_Ignore(job->inPipe);
1492 #else
1493 FD_CLR(job->inPipe, &outputs);
1494 #endif
1495 if (job->outPipe != job->inPipe) {
1496 (void)close (job->outPipe);
1497 }
1498 JobDoOutput (job, TRUE);
1499 (void)close (job->inPipe);
1500 } else {
1501 (void)close (job->outFd);
1502 JobDoOutput (job, TRUE);
1503 }
1504 }
1505 }
1506 } else {
1507 /*
1508 * We can do all the commands at once. hooray for sanity
1509 */
1510 numCommands = 0;
1511 Lst_ForEach (gn->commands, JobPrintCommand, (ClientData)job);
1512
1513 /*
1514 * If we didn't print out any commands to the shell script,
1515 * there's not much point in executing the shell, is there?
1516 */
1517 if (numCommands == 0) {
1518 noExec = TRUE;
1519 }
1520 }
1521 } else if (noExecute) {
1522 /*
1523 * Not executing anything -- just print all the commands to stdout
1524 * in one fell swoop. This will still set up job->tailCmds correctly.
1525 */
1526 if (lastNode != gn) {
1527 printf (targFmt, gn->name);
1528 lastNode = gn;
1529 }
1530 job->cmdFILE = stdout;
1531 /*
1532 * Only print the commands if they're ok, but don't die if they're
1533 * not -- just let the user know they're bad and keep going. It
1534 * doesn't do any harm in this case and may do some good.
1535 */
1536 if (cmdsOK) {
1537 Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job);
1538 }
1539 /*
1540 * Don't execute the shell, thank you.
1541 */
1542 noExec = TRUE;
1543 } else {
1544 /*
1545 * Just touch the target and note that no shell should be executed.
1546 * Set cmdFILE to stdout to make life easier. Check the commands, too,
1547 * but don't die if they're no good -- it does no harm to keep working
1548 * up the graph.
1549 */
1550 job->cmdFILE = stdout;
1551 Job_Touch (gn, job->flags&JOB_SILENT);
1552 noExec = TRUE;
1553 }
1554
1555 /*
1556 * If we're not supposed to execute a shell, don't.
1557 */
1558 if (noExec) {
1559 /*
1560 * Unlink and close the command file if we opened one
1561 */
1562 if (job->cmdFILE != stdout) {
1563 (void) unlink (tfile);
1564 fclose(job->cmdFILE);
1565 } else {
1566 fflush (stdout);
1567 }
1568
1569 /*
1570 * We only want to work our way up the graph if we aren't here because
1571 * the commands for the job were no good.
1572 */
1573 if (cmdsOK) {
1574 if (aborting == 0) {
1575 if (job->tailCmds != NILLNODE) {
1576 Lst_ForEachFrom(job->node->commands, job->tailCmds,
1577 JobSaveCommand,
1578 (ClientData)job->node);
1579 }
1580 Make_Update(job->node);
1581 }
1582 free((Address)job);
1583 return(JOB_FINISHED);
1584 } else {
1585 free((Address)job);
1586 return(JOB_ERROR);
1587 }
1588 } else {
1589 fflush (job->cmdFILE);
1590 (void) unlink (tfile);
1591 }
1592
1593 /*
1594 * Set up the control arguments to the shell. This is based on the flags
1595 * set earlier for this job.
1596 */
1597 JobMakeArgv(job, argv);
1598
1599 /*
1600 * If we're using pipes to catch output, create the pipe by which we'll
1601 * get the shell's output. If we're using files, print out that we're
1602 * starting a job and then set up its temporary-file name. This is just
1603 * tfile with two extra digits tacked on -- jobno.
1604 */
1605 if (job->flags & JOB_FIRST) {
1606 if (usePipes) {
1607 int fd[2];
1608 (void) pipe(fd);
1609 job->inPipe = fd[0];
1610 job->outPipe = fd[1];
1611 (void)fcntl (job->inPipe, F_SETFD, 1);
1612 (void)fcntl (job->outPipe, F_SETFD, 1);
1613 } else {
1614 printf ("Remaking `%s'\n", gn->name);
1615 fflush (stdout);
1616 sprintf (job->outFile, "%s%02d", tfile, jobno);
1617 jobno = (jobno + 1) % 100;
1618 job->outFd = open(job->outFile,O_WRONLY|O_CREAT|O_APPEND,0600);
1619 (void)fcntl (job->outFd, F_SETFD, 1);
1620 }
1621 }
1622
1623 local = TRUE;
1624
1625 if (local && (((nLocal >= maxLocal) &&
1626 !(job->flags & JOB_SPECIAL) &&
1627 (maxLocal != 0))))
1628 {
1629 /*
1630 * The job can only be run locally, but we've hit the limit of
1631 * local concurrency, so put the job on hold until some other job
1632 * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END)
1633 * may be run locally even when the local limit has been reached
1634 * (e.g. when maxLocal == 0), though they will be exported if at
1635 * all possible.
1636 */
1637 jobFull = TRUE;
1638
1639 if (DEBUG(JOB)) {
1640 printf("Can only run job locally.\n");
1641 }
1642 job->flags |= JOB_RESTART;
1643 (void)Lst_AtEnd(stoppedJobs, (ClientData)job);
1644 } else {
1645 if ((nLocal >= maxLocal) && local) {
1646 /*
1647 * If we're running this job locally as a special case (see above),
1648 * at least say the table is full.
1649 */
1650 jobFull = TRUE;
1651 if (DEBUG(JOB)) {
1652 printf("Local job queue is full.\n");
1653 }
1654 }
1655 JobExec(job, argv);
1656 }
1657 return(JOB_RUNNING);
1658 }
1659
1660 /*-
1661 *-----------------------------------------------------------------------
1662 * JobDoOutput --
1663 * This function is called at different times depending on
1664 * whether the user has specified that output is to be collected
1665 * via pipes or temporary files. In the former case, we are called
1666 * whenever there is something to read on the pipe. We collect more
1667 * output from the given job and store it in the job's outBuf. If
1668 * this makes up a line, we print it tagged by the job's identifier,
1669 * as necessary.
1670 * If output has been collected in a temporary file, we open the
1671 * file and read it line by line, transfering it to our own
1672 * output channel until the file is empty. At which point we
1673 * remove the temporary file.
1674 * In both cases, however, we keep our figurative eye out for the
1675 * 'noPrint' line for the shell from which the output came. If
1676 * we recognize a line, we don't print it. If the command is not
1677 * alone on the line (the character after it is not \0 or \n), we
1678 * do print whatever follows it.
1679 *
1680 * Results:
1681 * None
1682 *
1683 * Side Effects:
1684 * curPos may be shifted as may the contents of outBuf.
1685 *-----------------------------------------------------------------------
1686 */
1687 static void
1688 JobDoOutput (job, finish)
1689 register Job *job; /* the job whose output needs printing */
1690 Boolean finish; /* TRUE if this is the last time we'll be
1691 * called for this job */
1692 {
1693 Boolean gotNL = FALSE; /* true if got a newline */
1694 register int nr; /* number of bytes read */
1695 register int i; /* auxiliary index into outBuf */
1696 register int max; /* limit for i (end of current data) */
1697 int nRead; /* (Temporary) number of bytes read */
1698
1699 FILE *oFILE; /* Stream pointer to shell's output file */
1700 char inLine[132];
1701
1702
1703 if (usePipes) {
1704 /*
1705 * Read as many bytes as will fit in the buffer.
1706 */
1707 end_loop:
1708
1709 nRead = read (job->inPipe, &job->outBuf[job->curPos],
1710 JOB_BUFSIZE - job->curPos);
1711 if (nRead < 0) {
1712 if (DEBUG(JOB)) {
1713 perror("JobDoOutput(piperead)");
1714 }
1715 nr = 0;
1716 } else {
1717 nr = nRead;
1718 }
1719
1720 /*
1721 * If we hit the end-of-file (the job is dead), we must flush its
1722 * remaining output, so pretend we read a newline if there's any
1723 * output remaining in the buffer.
1724 * Also clear the 'finish' flag so we stop looping.
1725 */
1726 if ((nr == 0) && (job->curPos != 0)) {
1727 job->outBuf[job->curPos] = '\n';
1728 nr = 1;
1729 finish = FALSE;
1730 } else if (nr == 0) {
1731 finish = FALSE;
1732 }
1733
1734 /*
1735 * Look for the last newline in the bytes we just got. If there is
1736 * one, break out of the loop with 'i' as its index and gotNL set
1737 * TRUE.
1738 */
1739 max = job->curPos + nr;
1740 for (i = job->curPos + nr - 1; i >= job->curPos; i--) {
1741 if (job->outBuf[i] == '\n') {
1742 gotNL = TRUE;
1743 break;
1744 } else if (job->outBuf[i] == '\0') {
1745 /*
1746 * Why?
1747 */
1748 job->outBuf[i] = ' ';
1749 }
1750 }
1751
1752 if (!gotNL) {
1753 job->curPos += nr;
1754 if (job->curPos == JOB_BUFSIZE) {
1755 /*
1756 * If we've run out of buffer space, we have no choice
1757 * but to print the stuff. sigh.
1758 */
1759 gotNL = TRUE;
1760 i = job->curPos;
1761 }
1762 }
1763 if (gotNL) {
1764 /*
1765 * Need to send the output to the screen. Null terminate it
1766 * first, overwriting the newline character if there was one.
1767 * So long as the line isn't one we should filter (according
1768 * to the shell description), we print the line, preceeded
1769 * by a target banner if this target isn't the same as the
1770 * one for which we last printed something.
1771 * The rest of the data in the buffer are then shifted down
1772 * to the start of the buffer and curPos is set accordingly.
1773 */
1774 job->outBuf[i] = '\0';
1775 if (i >= job->curPos) {
1776 register char *cp, *ecp;
1777
1778 cp = job->outBuf;
1779 if (commandShell->noPrint) {
1780 ecp = Str_FindSubstring(job->outBuf,
1781 commandShell->noPrint);
1782 while (ecp != (char *)NULL) {
1783 if (cp != ecp) {
1784 *ecp = '\0';
1785 if (job->node != lastNode) {
1786 printf (targFmt, job->node->name);
1787 lastNode = job->node;
1788 }
1789 /*
1790 * The only way there wouldn't be a newline after
1791 * this line is if it were the last in the buffer.
1792 * however, since the non-printable comes after it,
1793 * there must be a newline, so we don't print one.
1794 */
1795 printf ("%s", cp);
1796 }
1797 cp = ecp + commandShell->noPLen;
1798 if (cp != &job->outBuf[i]) {
1799 /*
1800 * Still more to print, look again after skipping
1801 * the whitespace following the non-printable
1802 * command....
1803 */
1804 cp++;
1805 while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
1806 cp++;
1807 }
1808 ecp = Str_FindSubstring (cp,
1809 commandShell->noPrint);
1810 } else {
1811 break;
1812 }
1813 }
1814 }
1815
1816 /*
1817 * There's still more in that thar buffer. This time, though,
1818 * we know there's no newline at the end, so we add one of
1819 * our own free will.
1820 */
1821 if (*cp != '\0') {
1822 if (job->node != lastNode) {
1823 printf (targFmt, job->node->name);
1824 lastNode = job->node;
1825 }
1826 printf ("%s\n", cp);
1827 }
1828
1829 fflush (stdout);
1830 }
1831 if (i < max - 1) {
1832 /* shift the remaining characters down */
1833 memcpy ( job->outBuf, &job->outBuf[i + 1], max - (i + 1));
1834 job->curPos = max - (i + 1);
1835
1836 } else {
1837 /*
1838 * We have written everything out, so we just start over
1839 * from the start of the buffer. No copying. No nothing.
1840 */
1841 job->curPos = 0;
1842 }
1843 }
1844 if (finish) {
1845 /*
1846 * If the finish flag is true, we must loop until we hit
1847 * end-of-file on the pipe. This is guaranteed to happen eventually
1848 * since the other end of the pipe is now closed (we closed it
1849 * explicitly and the child has exited). When we do get an EOF,
1850 * finish will be set FALSE and we'll fall through and out.
1851 */
1852 goto end_loop;
1853 }
1854 } else {
1855 /*
1856 * We've been called to retrieve the output of the job from the
1857 * temporary file where it's been squirreled away. This consists of
1858 * opening the file, reading the output line by line, being sure not
1859 * to print the noPrint line for the shell we used, then close and
1860 * remove the temporary file. Very simple.
1861 *
1862 * Change to read in blocks and do FindSubString type things as for
1863 * pipes? That would allow for "@echo -n..."
1864 */
1865 oFILE = fopen (job->outFile, "r");
1866 if (oFILE != (FILE *) NULL) {
1867 printf ("Results of making %s:\n", job->node->name);
1868 while (fgets (inLine, sizeof(inLine), oFILE) != NULL) {
1869 register char *cp, *ecp, *endp;
1870
1871 cp = inLine;
1872 endp = inLine + strlen(inLine);
1873 if (endp[-1] == '\n') {
1874 *--endp = '\0';
1875 }
1876 if (commandShell->noPrint) {
1877 ecp = Str_FindSubstring(cp, commandShell->noPrint);
1878 while (ecp != (char *)NULL) {
1879 if (cp != ecp) {
1880 *ecp = '\0';
1881 /*
1882 * The only way there wouldn't be a newline after
1883 * this line is if it were the last in the buffer.
1884 * however, since the non-printable comes after it,
1885 * there must be a newline, so we don't print one.
1886 */
1887 printf ("%s", cp);
1888 }
1889 cp = ecp + commandShell->noPLen;
1890 if (cp != endp) {
1891 /*
1892 * Still more to print, look again after skipping
1893 * the whitespace following the non-printable
1894 * command....
1895 */
1896 cp++;
1897 while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
1898 cp++;
1899 }
1900 ecp = Str_FindSubstring(cp, commandShell->noPrint);
1901 } else {
1902 break;
1903 }
1904 }
1905 }
1906
1907 /*
1908 * There's still more in that thar buffer. This time, though,
1909 * we know there's no newline at the end, so we add one of
1910 * our own free will.
1911 */
1912 if (*cp != '\0') {
1913 printf ("%s\n", cp);
1914 }
1915 }
1916 fclose (oFILE);
1917 (void) unlink (job->outFile);
1918 }
1919 }
1920 fflush(stdout);
1921 }
1922
1923 /*-
1924 *-----------------------------------------------------------------------
1925 * Job_CatchChildren --
1926 * Handle the exit of a child. Called from Make_Make.
1927 *
1928 * Results:
1929 * none.
1930 *
1931 * Side Effects:
1932 * The job descriptor is removed from the list of children.
1933 *
1934 * Notes:
1935 * We do waits, blocking or not, according to the wisdom of our
1936 * caller, until there are no more children to report. For each
1937 * job, call JobFinish to finish things off. This will take care of
1938 * putting jobs on the stoppedJobs queue.
1939 *
1940 *-----------------------------------------------------------------------
1941 */
1942 void
1943 Job_CatchChildren (block)
1944 Boolean block; /* TRUE if should block on the wait. */
1945 {
1946 int pid; /* pid of dead child */
1947 register Job *job; /* job descriptor for dead child */
1948 LstNode jnode; /* list element for finding job */
1949 union wait status; /* Exit/termination status */
1950
1951 /*
1952 * Don't even bother if we know there's no one around.
1953 */
1954 if (nLocal == 0) {
1955 return;
1956 }
1957
1958 while ((pid = wait3((int *)&status, (block?0:WNOHANG)|WUNTRACED,
1959 (struct rusage *)0)) > 0)
1960 {
1961 if (DEBUG(JOB))
1962 printf("Process %d exited or stopped.\n", pid);
1963
1964
1965 jnode = Lst_Find (jobs, (ClientData)&pid, JobCmpPid);
1966
1967 if (jnode == NILLNODE) {
1968 if (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) {
1969 jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid);
1970 if (jnode == NILLNODE) {
1971 Error("Resumed child (%d) not in table", pid);
1972 continue;
1973 }
1974 job = (Job *)Lst_Datum(jnode);
1975 (void)Lst_Remove(stoppedJobs, jnode);
1976 } else {
1977 Error ("Child (%d) not in table?", pid);
1978 continue;
1979 }
1980 } else {
1981 job = (Job *) Lst_Datum (jnode);
1982 (void)Lst_Remove (jobs, jnode);
1983 nJobs -= 1;
1984 if (jobFull && DEBUG(JOB)) {
1985 printf("Job queue is no longer full.\n");
1986 }
1987 jobFull = FALSE;
1988 nLocal -= 1;
1989 }
1990
1991 JobFinish (job, status);
1992 }
1993 }
1994
1995 /*-
1996 *-----------------------------------------------------------------------
1997 * Job_CatchOutput --
1998 * Catch the output from our children, if we're using
1999 * pipes do so. Otherwise just block time until we get a
2000 * signal (most likely a SIGCHLD) since there's no point in
2001 * just spinning when there's nothing to do and the reaping
2002 * of a child can wait for a while.
2003 *
2004 * Results:
2005 * None
2006 *
2007 * Side Effects:
2008 * Output is read from pipes if we're piping.
2009 * -----------------------------------------------------------------------
2010 */
2011 void
2012 Job_CatchOutput ()
2013 {
2014 int nfds;
2015 struct timeval timeout;
2016 fd_set readfds;
2017 register LstNode ln;
2018 register Job *job;
2019 #ifdef RMT_WILL_WATCH
2020 int pnJobs; /* Previous nJobs */
2021 #endif
2022
2023 fflush(stdout);
2024 #ifdef RMT_WILL_WATCH
2025 pnJobs = nJobs;
2026
2027 /*
2028 * It is possible for us to be called with nJobs equal to 0. This happens
2029 * if all the jobs finish and a job that is stopped cannot be run
2030 * locally (eg if maxLocal is 0) and cannot be exported. The job will
2031 * be placed back on the stoppedJobs queue, Job_Empty() will return false,
2032 * Make_Run will call us again when there's nothing for which to wait.
2033 * nJobs never changes, so we loop forever. Hence the check. It could
2034 * be argued that we should sleep for a bit so as not to swamp the
2035 * exportation system with requests. Perhaps we should.
2036 *
2037 * NOTE: IT IS THE RESPONSIBILITY OF Rmt_Wait TO CALL Job_CatchChildren
2038 * IN A TIMELY FASHION TO CATCH ANY LOCALLY RUNNING JOBS THAT EXIT.
2039 * It may use the variable nLocal to determine if it needs to call
2040 * Job_CatchChildren (if nLocal is 0, there's nothing for which to
2041 * wait...)
2042 */
2043 while (nJobs != 0 && pnJobs == nJobs) {
2044 Rmt_Wait();
2045 }
2046 #else
2047 if (usePipes) {
2048 readfds = outputs;
2049 timeout.tv_sec = SEL_SEC;
2050 timeout.tv_usec = SEL_USEC;
2051
2052 if ((nfds = select (FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0)
2053 {
2054 return;
2055 } else {
2056 if (Lst_Open (jobs) == FAILURE) {
2057 Punt ("Cannot open job table");
2058 }
2059 while (nfds && (ln = Lst_Next (jobs)) != NILLNODE) {
2060 job = (Job *) Lst_Datum (ln);
2061 if (FD_ISSET(job->inPipe, &readfds)) {
2062 JobDoOutput (job, FALSE);
2063 nfds -= 1;
2064 }
2065 }
2066 Lst_Close (jobs);
2067 }
2068 }
2069 #endif /* RMT_WILL_WATCH */
2070 }
2071
2072 /*-
2073 *-----------------------------------------------------------------------
2074 * Job_Make --
2075 * Start the creation of a target. Basically a front-end for
2076 * JobStart used by the Make module.
2077 *
2078 * Results:
2079 * None.
2080 *
2081 * Side Effects:
2082 * Another job is started.
2083 *
2084 *-----------------------------------------------------------------------
2085 */
2086 void
2087 Job_Make (gn)
2088 GNode *gn;
2089 {
2090 (void)JobStart (gn, 0, (Job *)NULL);
2091 }
2092
2093 /*-
2094 *-----------------------------------------------------------------------
2095 * Job_Init --
2096 * Initialize the process module
2097 *
2098 * Results:
2099 * none
2100 *
2101 * Side Effects:
2102 * lists and counters are initialized
2103 *-----------------------------------------------------------------------
2104 */
2105 void
2106 Job_Init (maxproc, maxlocal)
2107 int maxproc; /* the greatest number of jobs which may be
2108 * running at one time */
2109 int maxlocal; /* the greatest number of local jobs which may
2110 * be running at once. */
2111 {
2112 GNode *begin; /* node for commands to do at the very start */
2113
2114 sprintf (tfile, "/tmp/make%05d", getpid());
2115
2116 jobs = Lst_Init (FALSE);
2117 stoppedJobs = Lst_Init(FALSE);
2118 maxJobs = maxproc;
2119 maxLocal = maxlocal;
2120 nJobs = 0;
2121 nLocal = 0;
2122 jobFull = FALSE;
2123
2124 aborting = 0;
2125 errors = 0;
2126
2127 lastNode = NILGNODE;
2128
2129 if (maxJobs == 1) {
2130 /*
2131 * If only one job can run at a time, there's no need for a banner,
2132 * no is there?
2133 */
2134 targFmt = "";
2135 } else {
2136 targFmt = TARG_FMT;
2137 }
2138
2139 if (shellPath == (char *) NULL) {
2140 /*
2141 * The user didn't specify a shell to use, so we are using the
2142 * default one... Both the absolute path and the last component
2143 * must be set. The last component is taken from the 'name' field
2144 * of the default shell description pointed-to by commandShell.
2145 * All default shells are located in _PATH_DEFSHELLDIR.
2146 */
2147 shellName = commandShell->name;
2148 shellPath = str_concat (_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
2149 }
2150
2151 if (commandShell->exit == (char *)NULL) {
2152 commandShell->exit = "";
2153 }
2154 if (commandShell->echo == (char *)NULL) {
2155 commandShell->echo = "";
2156 }
2157
2158 /*
2159 * Catch the four signals that POSIX specifies if they aren't ignored.
2160 * JobPassSig will take care of calling JobInterrupt if appropriate.
2161 */
2162 if (signal (SIGINT, SIG_IGN) != SIG_IGN) {
2163 signal (SIGINT, JobPassSig);
2164 }
2165 if (signal (SIGHUP, SIG_IGN) != SIG_IGN) {
2166 signal (SIGHUP, JobPassSig);
2167 }
2168 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) {
2169 signal (SIGQUIT, JobPassSig);
2170 }
2171 if (signal (SIGTERM, SIG_IGN) != SIG_IGN) {
2172 signal (SIGTERM, JobPassSig);
2173 }
2174 /*
2175 * There are additional signals that need to be caught and passed if
2176 * either the export system wants to be told directly of signals or if
2177 * we're giving each job its own process group (since then it won't get
2178 * signals from the terminal driver as we own the terminal)
2179 */
2180 #if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP)
2181 if (signal (SIGTSTP, SIG_IGN) != SIG_IGN) {
2182 signal (SIGTSTP, JobPassSig);
2183 }
2184 if (signal (SIGTTOU, SIG_IGN) != SIG_IGN) {
2185 signal (SIGTTOU, JobPassSig);
2186 }
2187 if (signal (SIGTTIN, SIG_IGN) != SIG_IGN) {
2188 signal (SIGTTIN, JobPassSig);
2189 }
2190 if (signal (SIGWINCH, SIG_IGN) != SIG_IGN) {
2191 signal (SIGWINCH, JobPassSig);
2192 }
2193 #endif
2194
2195 begin = Targ_FindNode (".BEGIN", TARG_NOCREATE);
2196
2197 if (begin != NILGNODE) {
2198 JobStart (begin, JOB_SPECIAL, (Job *)0);
2199 while (nJobs) {
2200 Job_CatchOutput();
2201 #ifndef RMT_WILL_WATCH
2202 Job_CatchChildren (!usePipes);
2203 #endif /* RMT_WILL_WATCH */
2204 }
2205 }
2206 postCommands = Targ_FindNode (".END", TARG_CREATE);
2207 }
2208
2209 /*-
2210 *-----------------------------------------------------------------------
2211 * Job_Full --
2212 * See if the job table is full. It is considered full if it is OR
2213 * if we are in the process of aborting OR if we have
2214 * reached/exceeded our local quota. This prevents any more jobs
2215 * from starting up.
2216 *
2217 * Results:
2218 * TRUE if the job table is full, FALSE otherwise
2219 * Side Effects:
2220 * None.
2221 *-----------------------------------------------------------------------
2222 */
2223 Boolean
2224 Job_Full ()
2225 {
2226 return (aborting || jobFull);
2227 }
2228
2229 /*-
2230 *-----------------------------------------------------------------------
2231 * Job_Empty --
2232 * See if the job table is empty. Because the local concurrency may
2233 * be set to 0, it is possible for the job table to become empty,
2234 * while the list of stoppedJobs remains non-empty. In such a case,
2235 * we want to restart as many jobs as we can.
2236 *
2237 * Results:
2238 * TRUE if it is. FALSE if it ain't.
2239 *
2240 * Side Effects:
2241 * None.
2242 *
2243 * -----------------------------------------------------------------------
2244 */
2245 Boolean
2246 Job_Empty ()
2247 {
2248 if (nJobs == 0) {
2249 if (!Lst_IsEmpty(stoppedJobs) && !aborting) {
2250 /*
2251 * The job table is obviously not full if it has no jobs in
2252 * it...Try and restart the stopped jobs.
2253 */
2254 jobFull = FALSE;
2255 while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
2256 JobRestart((Job *)Lst_DeQueue(stoppedJobs));
2257 }
2258 return(FALSE);
2259 } else {
2260 return(TRUE);
2261 }
2262 } else {
2263 return(FALSE);
2264 }
2265 }
2266
2267 /*-
2268 *-----------------------------------------------------------------------
2269 * JobMatchShell --
2270 * Find a matching shell in 'shells' given its final component.
2271 *
2272 * Results:
2273 * A pointer to the Shell structure.
2274 *
2275 * Side Effects:
2276 * None.
2277 *
2278 *-----------------------------------------------------------------------
2279 */
2280 static Shell *
2281 JobMatchShell (name)
2282 char *name; /* Final component of shell path */
2283 {
2284 register Shell *sh; /* Pointer into shells table */
2285 Shell *match; /* Longest-matching shell */
2286 register char *cp1,
2287 *cp2;
2288 char *eoname;
2289
2290 eoname = name + strlen (name);
2291
2292 match = (Shell *) NULL;
2293
2294 for (sh = shells; sh->name != NULL; sh++) {
2295 for (cp1 = eoname - strlen (sh->name), cp2 = sh->name;
2296 *cp1 != '\0' && *cp1 == *cp2;
2297 cp1++, cp2++) {
2298 continue;
2299 }
2300 if (*cp1 != *cp2) {
2301 continue;
2302 } else if (match == (Shell *) NULL ||
2303 strlen (match->name) < strlen (sh->name)) {
2304 match = sh;
2305 }
2306 }
2307 return (match == (Shell *) NULL ? sh : match);
2308 }
2309
2310 /*-
2311 *-----------------------------------------------------------------------
2312 * Job_ParseShell --
2313 * Parse a shell specification and set up commandShell, shellPath
2314 * and shellName appropriately.
2315 *
2316 * Results:
2317 * FAILURE if the specification was incorrect.
2318 *
2319 * Side Effects:
2320 * commandShell points to a Shell structure (either predefined or
2321 * created from the shell spec), shellPath is the full path of the
2322 * shell described by commandShell, while shellName is just the
2323 * final component of shellPath.
2324 *
2325 * Notes:
2326 * A shell specification consists of a .SHELL target, with dependency
2327 * operator, followed by a series of blank-separated words. Double
2328 * quotes can be used to use blanks in words. A backslash escapes
2329 * anything (most notably a double-quote and a space) and
2330 * provides the functionality it does in C. Each word consists of
2331 * keyword and value separated by an equal sign. There should be no
2332 * unnecessary spaces in the word. The keywords are as follows:
2333 * name Name of shell.
2334 * path Location of shell. Overrides "name" if given
2335 * quiet Command to turn off echoing.
2336 * echo Command to turn echoing on
2337 * filter Result of turning off echoing that shouldn't be
2338 * printed.
2339 * echoFlag Flag to turn echoing on at the start
2340 * errFlag Flag to turn error checking on at the start
2341 * hasErrCtl True if shell has error checking control
2342 * check Command to turn on error checking if hasErrCtl
2343 * is TRUE or template of command to echo a command
2344 * for which error checking is off if hasErrCtl is
2345 * FALSE.
2346 * ignore Command to turn off error checking if hasErrCtl
2347 * is TRUE or template of command to execute a
2348 * command so as to ignore any errors it returns if
2349 * hasErrCtl is FALSE.
2350 *
2351 *-----------------------------------------------------------------------
2352 */
2353 ReturnStatus
2354 Job_ParseShell (line)
2355 char *line; /* The shell spec */
2356 {
2357 char **words;
2358 int wordCount;
2359 register char **argv;
2360 register int argc;
2361 char *path;
2362 Shell newShell;
2363 Boolean fullSpec = FALSE;
2364
2365 while (isspace (*line)) {
2366 line++;
2367 }
2368 words = brk_string (line, &wordCount, TRUE);
2369
2370 memset ((Address)&newShell, 0, sizeof(newShell));
2371
2372 /*
2373 * Parse the specification by keyword
2374 */
2375 for (path = (char *)NULL, argc = wordCount - 1, argv = words + 1;
2376 argc != 0;
2377 argc--, argv++) {
2378 if (strncmp (*argv, "path=", 5) == 0) {
2379 path = &argv[0][5];
2380 } else if (strncmp (*argv, "name=", 5) == 0) {
2381 newShell.name = &argv[0][5];
2382 } else {
2383 if (strncmp (*argv, "quiet=", 6) == 0) {
2384 newShell.echoOff = &argv[0][6];
2385 } else if (strncmp (*argv, "echo=", 5) == 0) {
2386 newShell.echoOn = &argv[0][5];
2387 } else if (strncmp (*argv, "filter=", 7) == 0) {
2388 newShell.noPrint = &argv[0][7];
2389 newShell.noPLen = strlen(newShell.noPrint);
2390 } else if (strncmp (*argv, "echoFlag=", 9) == 0) {
2391 newShell.echo = &argv[0][9];
2392 } else if (strncmp (*argv, "errFlag=", 8) == 0) {
2393 newShell.exit = &argv[0][8];
2394 } else if (strncmp (*argv, "hasErrCtl=", 10) == 0) {
2395 char c = argv[0][10];
2396 newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
2397 (c != 'T') && (c != 't'));
2398 } else if (strncmp (*argv, "check=", 6) == 0) {
2399 newShell.errCheck = &argv[0][6];
2400 } else if (strncmp (*argv, "ignore=", 7) == 0) {
2401 newShell.ignErr = &argv[0][7];
2402 } else {
2403 Parse_Error (PARSE_FATAL, "Unknown keyword \"%s\"",
2404 *argv);
2405 return (FAILURE);
2406 }
2407 fullSpec = TRUE;
2408 }
2409 }
2410
2411 if (path == (char *)NULL) {
2412 /*
2413 * If no path was given, the user wants one of the pre-defined shells,
2414 * yes? So we find the one s/he wants with the help of JobMatchShell
2415 * and set things up the right way. shellPath will be set up by
2416 * Job_Init.
2417 */
2418 if (newShell.name == (char *)NULL) {
2419 Parse_Error (PARSE_FATAL, "Neither path nor name specified");
2420 return (FAILURE);
2421 } else {
2422 commandShell = JobMatchShell (newShell.name);
2423 shellName = newShell.name;
2424 }
2425 } else {
2426 /*
2427 * The user provided a path. If s/he gave nothing else (fullSpec is
2428 * FALSE), try and find a matching shell in the ones we know of.
2429 * Else we just take the specification at its word and copy it
2430 * to a new location. In either case, we need to record the
2431 * path the user gave for the shell.
2432 */
2433 shellPath = path;
2434 path = strrchr (path, '/');
2435 if (path == (char *)NULL) {
2436 path = shellPath;
2437 } else {
2438 path += 1;
2439 }
2440 if (newShell.name != (char *)NULL) {
2441 shellName = newShell.name;
2442 } else {
2443 shellName = path;
2444 }
2445 if (!fullSpec) {
2446 commandShell = JobMatchShell (shellName);
2447 } else {
2448 commandShell = (Shell *) emalloc(sizeof(Shell));
2449 *commandShell = newShell;
2450 }
2451 }
2452
2453 if (commandShell->echoOn && commandShell->echoOff) {
2454 commandShell->hasEchoCtl = TRUE;
2455 }
2456
2457 if (!commandShell->hasErrCtl) {
2458 if (commandShell->errCheck == (char *)NULL) {
2459 commandShell->errCheck = "";
2460 }
2461 if (commandShell->ignErr == (char *)NULL) {
2462 commandShell->ignErr = "%s\n";
2463 }
2464 }
2465
2466 /*
2467 * Do not free up the words themselves, since they might be in use by the
2468 * shell specification...
2469 */
2470 free (words);
2471 return SUCCESS;
2472 }
2473
2474 /*-
2475 *-----------------------------------------------------------------------
2476 * JobInterrupt --
2477 * Handle the receipt of an interrupt.
2478 *
2479 * Results:
2480 * None
2481 *
2482 * Side Effects:
2483 * All children are killed. Another job will be started if the
2484 * .INTERRUPT target was given.
2485 *-----------------------------------------------------------------------
2486 */
2487 static void
2488 JobInterrupt (runINTERRUPT)
2489 int runINTERRUPT; /* Non-zero if commands for the .INTERRUPT
2490 * target should be executed */
2491 {
2492 LstNode ln; /* element in job table */
2493 Job *job; /* job descriptor in that element */
2494 GNode *interrupt; /* the node describing the .INTERRUPT target */
2495
2496 aborting = ABORT_INTERRUPT;
2497
2498 (void)Lst_Open (jobs);
2499 while ((ln = Lst_Next (jobs)) != NILLNODE) {
2500 job = (Job *) Lst_Datum (ln);
2501
2502 if (!Targ_Precious (job->node)) {
2503 char *file = (job->node->path == (char *)NULL ?
2504 job->node->name :
2505 job->node->path);
2506 struct stat st;
2507 if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) &&
2508 unlink(file) != -1) {
2509 Error ("*** %s removed", file);
2510 }
2511 }
2512 #ifdef RMT_WANTS_SIGNALS
2513 if (job->flags & JOB_REMOTE) {
2514 /*
2515 * If job is remote, let the Rmt module do the killing.
2516 */
2517 if (!Rmt_Signal(job, SIGINT)) {
2518 /*
2519 * If couldn't kill the thing, finish it out now with an
2520 * error code, since no exit report will come in likely.
2521 */
2522 union wait status;
2523
2524 status.w_status = 0;
2525 status.w_retcode = 1;
2526 JobFinish(job, status);
2527 }
2528 } else if (job->pid) {
2529 KILL(job->pid, SIGINT);
2530 }
2531 #else
2532 if (job->pid) {
2533 KILL(job->pid, SIGINT);
2534 }
2535 #endif /* RMT_WANTS_SIGNALS */
2536 }
2537 Lst_Close (jobs);
2538
2539 if (runINTERRUPT && !touchFlag) {
2540 interrupt = Targ_FindNode (".INTERRUPT", TARG_NOCREATE);
2541 if (interrupt != NILGNODE) {
2542 ignoreErrors = FALSE;
2543
2544 JobStart (interrupt, JOB_IGNDOTS, (Job *)0);
2545 while (nJobs) {
2546 Job_CatchOutput();
2547 #ifndef RMT_WILL_WATCH
2548 Job_CatchChildren (!usePipes);
2549 #endif /* RMT_WILL_WATCH */
2550 }
2551 }
2552 }
2553 (void) unlink (tfile);
2554 exit (0);
2555 }
2556
2557 /*
2558 *-----------------------------------------------------------------------
2559 * Job_End --
2560 * Do final processing such as the running of the commands
2561 * attached to the .END target.
2562 *
2563 * Results:
2564 * Number of errors reported.
2565 *
2566 * Side Effects:
2567 * The process' temporary file (tfile) is removed if it still
2568 * existed.
2569 *-----------------------------------------------------------------------
2570 */
2571 int
2572 Job_End ()
2573 {
2574 if (postCommands != NILGNODE && !Lst_IsEmpty (postCommands->commands)) {
2575 if (errors) {
2576 Error ("Errors reported so .END ignored");
2577 } else {
2578 JobStart (postCommands, JOB_SPECIAL | JOB_IGNDOTS,
2579 (Job *)0);
2580
2581 while (nJobs) {
2582 Job_CatchOutput();
2583 #ifndef RMT_WILL_WATCH
2584 Job_CatchChildren (!usePipes);
2585 #endif /* RMT_WILL_WATCH */
2586 }
2587 }
2588 }
2589 (void) unlink (tfile);
2590 return(errors);
2591 }
2592
2593 /*-
2594 *-----------------------------------------------------------------------
2595 * Job_Wait --
2596 * Waits for all running jobs to finish and returns. Sets 'aborting'
2597 * to ABORT_WAIT to prevent other jobs from starting.
2598 *
2599 * Results:
2600 * None.
2601 *
2602 * Side Effects:
2603 * Currently running jobs finish.
2604 *
2605 *-----------------------------------------------------------------------
2606 */
2607 void
2608 Job_Wait()
2609 {
2610 aborting = ABORT_WAIT;
2611 while (nJobs != 0) {
2612 Job_CatchOutput();
2613 #ifndef RMT_WILL_WATCH
2614 Job_CatchChildren(!usePipes);
2615 #endif /* RMT_WILL_WATCH */
2616 }
2617 aborting = 0;
2618 }
2619
2620 /*-
2621 *-----------------------------------------------------------------------
2622 * Job_AbortAll --
2623 * Abort all currently running jobs without handling output or anything.
2624 * This function is to be called only in the event of a major
2625 * error. Most definitely NOT to be called from JobInterrupt.
2626 *
2627 * Results:
2628 * None
2629 *
2630 * Side Effects:
2631 * All children are killed, not just the firstborn
2632 *-----------------------------------------------------------------------
2633 */
2634 void
2635 Job_AbortAll ()
2636 {
2637 LstNode ln; /* element in job table */
2638 Job *job; /* the job descriptor in that element */
2639 int foo;
2640
2641 aborting = ABORT_ERROR;
2642
2643 if (nJobs) {
2644
2645 (void)Lst_Open (jobs);
2646 while ((ln = Lst_Next (jobs)) != NILLNODE) {
2647 job = (Job *) Lst_Datum (ln);
2648
2649 /*
2650 * kill the child process with increasingly drastic signals to make
2651 * darn sure it's dead.
2652 */
2653 #ifdef RMT_WANTS_SIGNALS
2654 if (job->flags & JOB_REMOTE) {
2655 Rmt_Signal(job, SIGINT);
2656 Rmt_Signal(job, SIGKILL);
2657 } else {
2658 KILL(job->pid, SIGINT);
2659 KILL(job->pid, SIGKILL);
2660 }
2661 #else
2662 KILL(job->pid, SIGINT);
2663 KILL(job->pid, SIGKILL);
2664 #endif /* RMT_WANTS_SIGNALS */
2665 }
2666 }
2667
2668 /*
2669 * Catch as many children as want to report in at first, then give up
2670 */
2671 while (wait3(&foo, WNOHANG, (struct rusage *)0) > 0)
2672 continue;
2673 (void) unlink (tfile);
2674 }
2675