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