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

Last change on this file since 41 was 35, checked in by bird, 22 years ago

emx is kind of working again...

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