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