source: trunk/src/kmk/job.c@ 25

Last change on this file since 25 was 25, checked in by bird, 23 years ago

This commit was generated by cvs2svn to compensate for changes in r24,
which included commits to RCS files with non-trunk default branches.

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