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