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