Annotation of src/usr.bin/make/job.c, Revision 1.412
1.412 ! rillig 1: /* $NetBSD: job.c,v 1.411 2021/02/01 21:04:10 rillig Exp $ */
1.10 christos 2:
1.1 cgd 3: /*
4: * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
1.82 agc 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: /*
1.1 cgd 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:
1.398 rillig 72: /*
1.1 cgd 73: * job.c --
74: * handle the creation etc. of our child processes.
75: *
76: * Interface:
1.278 rillig 77: * Job_Init Called to initialize this module. In addition,
1.407 rillig 78: * the .BEGIN target is made including all of its
79: * dependencies before this function returns.
1.278 rillig 80: * Hence, the makefiles must have been parsed
81: * before this function is called.
82: *
83: * Job_End Clean up any memory used.
84: *
1.246 rillig 85: * Job_Make Start the creation of the given target.
1.1 cgd 86: *
1.246 rillig 87: * Job_CatchChildren
88: * Check for and handle the termination of any
89: * children. This must be called reasonably
90: * frequently to keep the whole make going at
91: * a decent clip, since job table entries aren't
92: * removed until their process is caught this way.
93: *
94: * Job_CatchOutput
95: * Print any output our children have produced.
96: * Should also be called fairly frequently to
97: * keep the user informed of what's going on.
98: * If no output is waiting, it will block for
99: * a time given by the SEL_* constants, below,
100: * or until output is ready.
101: *
1.407 rillig 102: * Job_ParseShell Given a special dependency line with target '.SHELL',
103: * define the shell that is used for the creation
104: * commands in jobs mode.
1.246 rillig 105: *
106: * Job_Finish Perform any final processing which needs doing.
107: * This includes the execution of any commands
108: * which have been/were attached to the .END
109: * target. It should only be called when the
110: * job table is empty.
111: *
1.407 rillig 112: * Job_AbortAll Abort all currently running jobs. Do not handle
113: * output or do anything for the jobs, just kill them.
114: * Should only be called in an emergency.
1.246 rillig 115: *
116: * Job_CheckCommands
117: * Verify that the commands for a target are
118: * ok. Provide them if necessary and possible.
1.1 cgd 119: *
1.246 rillig 120: * Job_Touch Update a target without really updating it.
1.1 cgd 121: *
1.246 rillig 122: * Job_Wait Wait for all currently-running jobs to finish.
1.1 cgd 123: */
124:
1.5 cgd 125: #include <sys/types.h>
1.1 cgd 126: #include <sys/stat.h>
127: #include <sys/file.h>
128: #include <sys/time.h>
129: #include <sys/wait.h>
1.72 wiz 130:
131: #include <errno.h>
1.35 christos 132: #ifndef USE_SELECT
133: #include <poll.h>
134: #endif
1.72 wiz 135: #include <signal.h>
136: #include <utime.h>
137:
1.5 cgd 138: #include "make.h"
139: #include "dir.h"
1.1 cgd 140: #include "job.h"
141: #include "pathnames.h"
1.40 sommerfe 142: #include "trace.h"
1.232 rillig 143:
144: /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
1.412 ! rillig 145: MAKE_RCSID("$NetBSD: job.c,v 1.411 2021/02/01 21:04:10 rillig Exp $");
1.1 cgd 146:
1.341 rillig 147: /*
148: * A shell defines how the commands are run. All commands for a target are
1.275 rillig 149: * written into a single file, which is then given to the shell to execute
150: * the commands from it. The commands are written to the file using a few
151: * templates for echo control and error control.
152: *
153: * The name of the shell is the basename for the predefined shells, such as
154: * "sh", "csh", "bash". For custom shells, it is the full pathname, and its
155: * basename is used to select the type of shell; the longest match wins.
156: * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh.
157: *
158: * The echoing of command lines is controlled using hasEchoCtl, echoOff,
159: * echoOn, noPrint and noPrintLen. When echoOff is executed by the shell, it
160: * still outputs something, but this something is not interesting, therefore
161: * it is filtered out using noPrint and noPrintLen.
162: *
163: * The error checking for individual commands is controlled using hasErrCtl,
1.364 rillig 164: * errOn, errOff and runChkTmpl.
1.275 rillig 165: *
1.407 rillig 166: * In case a shell doesn't have error control, echoTmpl is a printf template
167: * for echoing the command, should echoing be on; runIgnTmpl is another
168: * printf template for executing the command while ignoring the return
1.364 rillig 169: * status. Finally runChkTmpl is a printf template for running the command and
1.275 rillig 170: * causing the shell to exit on error. If any of these strings are empty when
1.276 rillig 171: * hasErrCtl is FALSE, the command will be executed anyway as is, and if it
1.319 rillig 172: * causes an error, so be it. Any templates set up to echo the command will
1.407 rillig 173: * escape any '$ ` \ "' characters in the command string to avoid unwanted
174: * shell code injection, the escaped command is safe to use in double quotes.
1.275 rillig 175: *
176: * The command-line flags "echo" and "exit" also control the behavior. The
177: * "echo" flag causes the shell to start echoing commands right away. The
178: * "exit" flag causes the shell to exit when an error is detected in one of
179: * the commands.
1.266 rillig 180: */
181: typedef struct Shell {
1.272 rillig 182:
1.341 rillig 183: /*
184: * The name of the shell. For Bourne and C shells, this is used only
185: * to find the shell description when used as the single source of a
186: * .SHELL target. For user-defined shells, this is the full path of
187: * the shell.
188: */
189: const char *name;
190:
1.375 rillig 191: Boolean hasEchoCtl; /* whether both echoOff and echoOn are there */
1.365 rillig 192: const char *echoOff; /* command to turn echoing off */
193: const char *echoOn; /* command to turn echoing back on */
1.375 rillig 194: const char *noPrint; /* text to skip when printing output from the
1.272 rillig 195: * shell. This is usually the same as echoOff */
1.341 rillig 196: size_t noPrintLen; /* length of noPrint command */
1.272 rillig 197:
1.375 rillig 198: Boolean hasErrCtl; /* whether error checking can be controlled
199: * for individual commands */
1.359 rillig 200: const char *errOn; /* command to turn on error checking */
201: const char *errOff; /* command to turn off error checking */
1.364 rillig 202:
203: const char *echoTmpl; /* template to echo a command */
204: const char *runIgnTmpl; /* template to run a command
205: * without error checking */
206: const char *runChkTmpl; /* template to run a command
207: * with error checking */
1.266 rillig 208:
1.341 rillig 209: /* string literal that results in a newline character when it appears
210: * outside of any 'quote' or "quote" characters */
211: const char *newline;
212: char commentChar; /* character used by shell for comment lines */
213:
1.366 rillig 214: const char *echoFlag; /* shell flag to echo commands */
1.375 rillig 215: const char *errFlag; /* shell flag to exit on error */
1.266 rillig 216: } Shell;
217:
1.360 rillig 218: typedef struct CommandFlags {
1.407 rillig 219: /* Whether to echo the command before or instead of running it. */
1.350 rillig 220: Boolean echo;
1.348 rillig 221:
1.360 rillig 222: /* Run the command even in -n or -N mode. */
1.348 rillig 223: Boolean always;
1.349 rillig 224:
225: /*
226: * true if we turned error checking off before printing the command
227: * and need to turn it back on
228: */
229: Boolean ignerr;
1.360 rillig 230: } CommandFlags;
1.347 rillig 231:
1.1 cgd 232: /*
1.371 rillig 233: * Write shell commands to a file.
234: *
235: * TODO: keep track of whether commands are echoed.
236: * TODO: keep track of whether error checking is active.
237: */
238: typedef struct ShellWriter {
239: FILE *f;
1.374 rillig 240:
241: /* we've sent 'set -x' */
242: Boolean xtraced;
243:
1.371 rillig 244: } ShellWriter;
245:
246: /*
1.16 christos 247: * error handling variables
1.1 cgd 248: */
1.331 rillig 249: static int job_errors = 0; /* number of errors reported */
1.283 rillig 250: typedef enum AbortReason { /* why is the make aborting? */
1.341 rillig 251: ABORT_NONE,
252: ABORT_ERROR, /* Because of an error */
253: ABORT_INTERRUPT, /* Because it was interrupted */
254: ABORT_WAIT /* Waiting for jobs to finish */
1.407 rillig 255: /* XXX: "WAIT" is not a _reason_ for aborting, it's rather a status. */
1.283 rillig 256: } AbortReason;
257: static AbortReason aborting = ABORT_NONE;
1.341 rillig 258: #define JOB_TOKENS "+EI+" /* Token to requeue for each abort state */
1.1 cgd 259:
1.16 christos 260: /*
1.103 dsl 261: * this tracks the number of tokens currently "out" to build jobs.
262: */
263: int jobTokensRunning = 0;
264:
1.284 rillig 265: typedef enum JobStartResult {
1.341 rillig 266: JOB_RUNNING, /* Job is running */
267: JOB_ERROR, /* Error in starting the job */
268: JOB_FINISHED /* The job is already finished */
1.284 rillig 269: } JobStartResult;
1.1 cgd 270:
271: /*
272: * Descriptions for various shells.
1.121 apb 273: *
1.133 apb 274: * The build environment may set DEFSHELL_INDEX to one of
275: * DEFSHELL_INDEX_SH, DEFSHELL_INDEX_KSH, or DEFSHELL_INDEX_CSH, to
1.243 rillig 276: * select one of the predefined shells as the default shell.
1.133 apb 277: *
278: * Alternatively, the build environment may set DEFSHELL_CUSTOM to the
279: * name or the full path of a sh-compatible shell, which will be used as
280: * the default shell.
281: *
282: * ".SHELL" lines in Makefiles can choose the default shell from the
1.289 rillig 283: * set defined here, or add additional shells.
1.133 apb 284: */
285:
286: #ifdef DEFSHELL_CUSTOM
287: #define DEFSHELL_INDEX_CUSTOM 0
288: #define DEFSHELL_INDEX_SH 1
289: #define DEFSHELL_INDEX_KSH 2
290: #define DEFSHELL_INDEX_CSH 3
291: #else /* !DEFSHELL_CUSTOM */
292: #define DEFSHELL_INDEX_SH 0
293: #define DEFSHELL_INDEX_KSH 1
294: #define DEFSHELL_INDEX_CSH 2
295: #endif /* !DEFSHELL_CUSTOM */
296:
297: #ifndef DEFSHELL_INDEX
298: #define DEFSHELL_INDEX 0 /* DEFSHELL_INDEX_CUSTOM or DEFSHELL_INDEX_SH */
299: #endif /* !DEFSHELL_INDEX */
300:
1.341 rillig 301: static Shell shells[] = {
1.133 apb 302: #ifdef DEFSHELL_CUSTOM
1.1 cgd 303: /*
1.121 apb 304: * An sh-compatible shell with a non-standard name.
305: *
306: * Keep this in sync with the "sh" description below, but avoid
307: * non-portable features that might not be supplied by all
308: * sh-compatible shells.
1.1 cgd 309: */
1.341 rillig 310: {
311: DEFSHELL_CUSTOM, /* .name */
312: FALSE, /* .hasEchoCtl */
313: "", /* .echoOff */
314: "", /* .echoOn */
315: "", /* .noPrint */
316: 0, /* .noPrintLen */
317: FALSE, /* .hasErrCtl */
1.358 rillig 318: "", /* .errOn */
1.359 rillig 319: "", /* .errOff */
1.364 rillig 320: "echo \"%s\"\n", /* .echoTmpl */
321: "%s\n", /* .runIgnTmpl */
322: "{ %s \n} || exit $?\n", /* .runChkTmpl */
1.341 rillig 323: "'\n'", /* .newline */
324: '#', /* .commentChar */
1.375 rillig 325: "", /* .echoFlag */
326: "", /* .errFlag */
1.341 rillig 327: },
1.133 apb 328: #endif /* DEFSHELL_CUSTOM */
1.1 cgd 329: /*
330: * SH description. Echo control is also possible and, under
331: * sun UNIX anyway, one can even control error checking.
332: */
1.341 rillig 333: {
334: "sh", /* .name */
335: FALSE, /* .hasEchoCtl */
336: "", /* .echoOff */
337: "", /* .echoOn */
338: "", /* .noPrint */
339: 0, /* .noPrintLen */
340: FALSE, /* .hasErrCtl */
1.358 rillig 341: "", /* .errOn */
1.359 rillig 342: "", /* .errOff */
1.364 rillig 343: "echo \"%s\"\n", /* .echoTmpl */
344: "%s\n", /* .runIgnTmpl */
345: "{ %s \n} || exit $?\n", /* .runChkTmpl */
1.341 rillig 346: "'\n'", /* .newline */
347: '#', /* .commentChar*/
1.121 apb 348: #if defined(MAKE_NATIVE) && defined(__NetBSD__)
1.375 rillig 349: /* XXX: -q is not really echoFlag, it's more like noEchoInSysFlag. */
350: "q", /* .echoFlag */
1.27 christos 351: #else
1.375 rillig 352: "", /* .echoFlag */
1.27 christos 353: #endif
1.375 rillig 354: "", /* .errFlag */
1.341 rillig 355: },
1.1 cgd 356: /*
1.201 rillig 357: * KSH description.
1.81 sjg 358: */
1.341 rillig 359: {
360: "ksh", /* .name */
361: TRUE, /* .hasEchoCtl */
362: "set +v", /* .echoOff */
363: "set -v", /* .echoOn */
364: "set +v", /* .noPrint */
365: 6, /* .noPrintLen */
366: FALSE, /* .hasErrCtl */
1.358 rillig 367: "", /* .errOn */
1.359 rillig 368: "", /* .errOff */
1.364 rillig 369: "echo \"%s\"\n", /* .echoTmpl */
370: "%s\n", /* .runIgnTmpl */
371: "{ %s \n} || exit $?\n", /* .runChkTmpl */
1.341 rillig 372: "'\n'", /* .newline */
373: '#', /* .commentChar */
1.375 rillig 374: "v", /* .echoFlag */
375: "", /* .errFlag */
1.341 rillig 376: },
1.81 sjg 377: /*
1.121 apb 378: * CSH description. The csh can do echo control by playing
379: * with the setting of the 'echo' shell variable. Sadly,
380: * however, it is unable to do error control nicely.
381: */
1.341 rillig 382: {
383: "csh", /* .name */
384: TRUE, /* .hasEchoCtl */
385: "unset verbose", /* .echoOff */
386: "set verbose", /* .echoOn */
387: "unset verbose", /* .noPrint */
388: 13, /* .noPrintLen */
389: FALSE, /* .hasErrCtl */
1.358 rillig 390: "", /* .errOn */
1.359 rillig 391: "", /* .errOff */
1.364 rillig 392: "echo \"%s\"\n", /* .echoTmpl */
393: "csh -c \"%s || exit 0\"\n", /* .runIgnTmpl */
394: "", /* .runChkTmpl */
1.341 rillig 395: "'\\\n'", /* .newline */
396: '#', /* .commentChar */
1.375 rillig 397: "v", /* .echoFlag */
398: "e", /* .errFlag */
1.341 rillig 399: }
1.1 cgd 400: };
1.243 rillig 401:
1.391 rillig 402: /*
403: * This is the shell to which we pass all commands in the Makefile.
404: * It is set by the Job_ParseShell function.
405: */
1.355 rillig 406: static Shell *shell = &shells[DEFSHELL_INDEX];
1.243 rillig 407: const char *shellPath = NULL; /* full pathname of executable image */
408: const char *shellName = NULL; /* last component of shellPath */
1.174 sjg 409: char *shellErrFlag = NULL;
1.407 rillig 410: static char *shell_freeIt = NULL; /* Allocated memory for custom .SHELL */
1.1 cgd 411:
412:
1.285 rillig 413: static Job *job_table; /* The structures that describe them */
414: static Job *job_table_end; /* job_table + maxJobs */
1.261 rillig 415: static unsigned int wantToken; /* we want a token */
1.316 rillig 416: static Boolean lurking_children = FALSE;
1.341 rillig 417: static Boolean make_suspended = FALSE; /* Whether we've seen a SIGTSTP (etc) */
1.40 sommerfe 418:
1.35 christos 419: /*
420: * Set of descriptors of pipes connected to
421: * the output channels of children
422: */
423: static struct pollfd *fds = NULL;
1.408 rillig 424: static Job **jobByFdIndex = NULL;
425: static nfds_t fdsLen = 0;
1.72 wiz 426: static void watchfd(Job *);
427: static void clearfd(Job *);
1.396 rillig 428: static Boolean readyfd(Job *);
1.1 cgd 429:
1.339 rillig 430: static char *targPrefix = NULL; /* To identify a job change in the output. */
1.40 sommerfe 431: static Job tokenWaitJob; /* token wait pseudo-job */
1.12 christos 432:
1.73 gson 433: static Job childExitJob; /* child exit pseudo-job */
1.341 rillig 434: #define CHILD_EXIT "."
435: #define DO_JOB_RESUME "R"
1.73 gson 436:
1.341 rillig 437: enum {
438: npseudojobs = 2 /* number of pseudo-jobs */
439: };
1.196 riastrad 440:
1.104 dsl 441: static sigset_t caught_signals; /* Set of signals we handle */
1.406 sjg 442: static volatile sig_atomic_t caught_sigchld;
1.1 cgd 443:
1.72 wiz 444: static void JobDoOutput(Job *, Boolean);
1.396 rillig 445: static void JobInterrupt(Boolean, int) MAKE_ATTR_DEAD;
1.72 wiz 446: static void JobRestartJobs(void);
1.69 pk 447: static void JobSigReset(void);
448:
1.339 rillig 449: static void
1.340 rillig 450: SwitchOutputTo(GNode *gn)
1.339 rillig 451: {
1.340 rillig 452: /* The node for which output was most recently produced. */
453: static GNode *lastNode = NULL;
454:
455: if (gn == lastNode)
456: return;
457: lastNode = gn;
458:
1.339 rillig 459: if (opts.maxJobs != 1 && targPrefix != NULL && targPrefix[0] != '\0')
460: (void)fprintf(stdout, "%s %s ---\n", targPrefix, gn->name);
461: }
462:
1.196 riastrad 463: static unsigned
464: nfds_per_job(void)
465: {
1.197 sjg 466: #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
1.341 rillig 467: if (useMeta)
468: return 2;
1.196 riastrad 469: #endif
1.341 rillig 470: return 1;
1.196 riastrad 471: }
472:
1.354 rillig 473: void
1.356 rillig 474: Job_FlagsToString(const Job *job, char *buf, size_t bufsize)
1.354 rillig 475: {
1.374 rillig 476: snprintf(buf, bufsize, "%c%c%c",
1.356 rillig 477: job->ignerr ? 'i' : '-',
1.357 rillig 478: !job->echo ? 's' : '-',
1.374 rillig 479: job->special ? 'S' : '-');
1.354 rillig 480: }
481:
1.114 dsl 482: static void
483: job_table_dump(const char *where)
484: {
1.341 rillig 485: Job *job;
1.374 rillig 486: char flags[4];
1.114 dsl 487:
1.341 rillig 488: debug_printf("job table @ %s\n", where);
489: for (job = job_table; job < job_table_end; job++) {
1.356 rillig 490: Job_FlagsToString(job, flags, sizeof flags);
1.354 rillig 491: debug_printf("job %d, status %d, flags %s, pid %d\n",
492: (int)(job - job_table), job->status, flags, job->pid);
1.341 rillig 493: }
1.114 dsl 494: }
1.69 pk 495:
496: /*
1.188 dholland 497: * Delete the target of a failed, interrupted, or otherwise
498: * unsuccessful job unless inhibited by .PRECIOUS.
499: */
500: static void
501: JobDeleteTarget(GNode *gn)
502: {
1.341 rillig 503: const char *file;
504:
505: if (gn->type & OP_JOIN)
506: return;
507: if (gn->type & OP_PHONY)
508: return;
509: if (Targ_Precious(gn))
510: return;
511: if (opts.noExecute)
512: return;
1.287 rillig 513:
1.341 rillig 514: file = GNode_Path(gn);
515: if (eunlink(file) != -1)
516: Error("*** %s removed", file);
1.188 dholland 517: }
518:
519: /*
1.69 pk 520: * JobSigLock/JobSigUnlock
521: *
522: * Signal lock routines to get exclusive access. Currently used to
523: * protect `jobs' and `stoppedJobs' list manipulations.
524: */
1.388 rillig 525: static void
526: JobSigLock(sigset_t *omaskp)
1.69 pk 527: {
528: if (sigprocmask(SIG_BLOCK, &caught_signals, omaskp) != 0) {
529: Punt("JobSigLock: sigprocmask: %s", strerror(errno));
1.104 dsl 530: sigemptyset(omaskp);
1.69 pk 531: }
532: }
533:
1.388 rillig 534: static void
535: JobSigUnlock(sigset_t *omaskp)
1.69 pk 536: {
1.96 christos 537: (void)sigprocmask(SIG_SETMASK, omaskp, NULL);
1.69 pk 538: }
1.1 cgd 539:
1.122 dsl 540: static void
541: JobCreatePipe(Job *job, int minfd)
542: {
1.341 rillig 543: int i, fd, flags;
544: int pipe_fds[2];
1.122 dsl 545:
1.341 rillig 546: if (pipe(pipe_fds) == -1)
547: Punt("Cannot create pipe: %s", strerror(errno));
1.122 dsl 548:
1.341 rillig 549: for (i = 0; i < 2; i++) {
550: /* Avoid using low numbered fds */
551: fd = fcntl(pipe_fds[i], F_DUPFD, minfd);
552: if (fd != -1) {
553: close(pipe_fds[i]);
554: pipe_fds[i] = fd;
555: }
1.247 rillig 556: }
1.201 rillig 557:
1.341 rillig 558: job->inPipe = pipe_fds[0];
559: job->outPipe = pipe_fds[1];
1.249 rillig 560:
1.341 rillig 561: /* Set close-on-exec flag for both */
562: if (fcntl(job->inPipe, F_SETFD, FD_CLOEXEC) == -1)
563: Punt("Cannot set close-on-exec: %s", strerror(errno));
564: if (fcntl(job->outPipe, F_SETFD, FD_CLOEXEC) == -1)
565: Punt("Cannot set close-on-exec: %s", strerror(errno));
566:
567: /*
568: * We mark the input side of the pipe non-blocking; we poll(2) the
569: * pipe when we're waiting for a job token, but we might lose the
570: * race for the token when a new one becomes available, so the read
571: * from the pipe should not block.
572: */
573: flags = fcntl(job->inPipe, F_GETFL, 0);
574: if (flags == -1)
575: Punt("Cannot get flags: %s", strerror(errno));
576: flags |= O_NONBLOCK;
577: if (fcntl(job->inPipe, F_SETFL, flags) == -1)
578: Punt("Cannot set flags: %s", strerror(errno));
1.122 dsl 579: }
580:
1.243 rillig 581: /* Pass the signal to each running job. */
1.114 dsl 582: static void
583: JobCondPassSig(int signo)
1.1 cgd 584: {
1.341 rillig 585: Job *job;
1.106 dsl 586:
1.341 rillig 587: DEBUG1(JOB, "JobCondPassSig(%d) called.\n", signo);
1.116 dsl 588:
1.341 rillig 589: for (job = job_table; job < job_table_end; job++) {
590: if (job->status != JOB_ST_RUNNING)
591: continue;
592: DEBUG2(JOB, "JobCondPassSig passing signal %d to child %d.\n",
593: signo, job->pid);
594: KILLPG(job->pid, signo);
595: }
1.1 cgd 596: }
597:
1.341 rillig 598: /*
599: * SIGCHLD handler.
1.37 sommerfe 600: *
1.341 rillig 601: * Sends a token on the child exit pipe to wake us up from select()/poll().
602: */
1.395 rillig 603: /*ARGSUSED*/
1.37 sommerfe 604: static void
1.162 joerg 605: JobChildSig(int signo MAKE_ATTR_UNUSED)
1.37 sommerfe 606: {
1.405 sjg 607: caught_sigchld = 1;
1.341 rillig 608: while (write(childExitJob.outPipe, CHILD_EXIT, 1) == -1 &&
609: errno == EAGAIN)
610: continue;
1.37 sommerfe 611: }
612:
613:
1.243 rillig 614: /* Resume all stopped jobs. */
1.395 rillig 615: /*ARGSUSED*/
1.47 sommerfe 616: static void
1.162 joerg 617: JobContinueSig(int signo MAKE_ATTR_UNUSED)
1.47 sommerfe 618: {
1.341 rillig 619: /*
620: * Defer sending SIGCONT to our stopped children until we return
621: * from the signal handler.
622: */
623: while (write(childExitJob.outPipe, DO_JOB_RESUME, 1) == -1 &&
624: errno == EAGAIN)
625: continue;
1.47 sommerfe 626: }
1.37 sommerfe 627:
1.341 rillig 628: /*
629: * Pass a signal on to all jobs, then resend to ourselves.
630: * We die by the same signal.
631: */
1.162 joerg 632: MAKE_ATTR_DEAD static void
1.116 dsl 633: JobPassSig_int(int signo)
634: {
1.341 rillig 635: /* Run .INTERRUPT target then exit */
636: JobInterrupt(TRUE, signo);
1.116 dsl 637: }
638:
1.341 rillig 639: /*
640: * Pass a signal on to all jobs, then resend to ourselves.
641: * We die by the same signal.
642: */
1.162 joerg 643: MAKE_ATTR_DEAD static void
1.116 dsl 644: JobPassSig_term(int signo)
645: {
1.341 rillig 646: /* Dont run .INTERRUPT target then exit */
647: JobInterrupt(FALSE, signo);
1.116 dsl 648: }
649:
650: static void
651: JobPassSig_suspend(int signo)
1.1 cgd 652: {
1.341 rillig 653: sigset_t nmask, omask;
654: struct sigaction act;
1.118 dsl 655:
1.341 rillig 656: /* Suppress job started/continued messages */
657: make_suspended = TRUE;
1.16 christos 658:
1.341 rillig 659: /* Pass the signal onto every job */
660: JobCondPassSig(signo);
1.1 cgd 661:
1.341 rillig 662: /*
663: * Send ourselves the signal now we've given the message to everyone
664: * else. Note we block everything else possible while we're getting
665: * the signal. This ensures that all our jobs get continued when we
666: * wake up before we take any other signal.
667: */
668: sigfillset(&nmask);
669: sigdelset(&nmask, signo);
670: (void)sigprocmask(SIG_SETMASK, &nmask, &omask);
671:
672: act.sa_handler = SIG_DFL;
673: sigemptyset(&act.sa_mask);
674: act.sa_flags = 0;
675: (void)sigaction(signo, &act, NULL);
1.13 christos 676:
1.343 rillig 677: DEBUG1(JOB, "JobPassSig passing signal %d to self.\n", signo);
1.1 cgd 678:
1.341 rillig 679: (void)kill(getpid(), signo);
1.115 dsl 680:
1.341 rillig 681: /*
682: * We've been continued.
683: *
684: * A whole host of signals continue to happen!
685: * SIGCHLD for any processes that actually suspended themselves.
686: * SIGCHLD for any processes that exited while we were alseep.
687: * The SIGCONT that actually caused us to wakeup.
688: *
689: * Since we defer passing the SIGCONT on to our children until
690: * the main processing loop, we can be sure that all the SIGCHLD
691: * events will have happened by then - and that the waitpid() will
692: * collect the child 'suspended' events.
693: * For correct sequencing we just need to ensure we process the
694: * waitpid() before passing on the SIGCONT.
695: *
696: * In any case nothing else is needed here.
697: */
1.1 cgd 698:
1.341 rillig 699: /* Restore handler and signal mask */
700: act.sa_handler = JobPassSig_suspend;
701: (void)sigaction(signo, &act, NULL);
702: (void)sigprocmask(SIG_SETMASK, &omask, NULL);
1.1 cgd 703: }
704:
1.114 dsl 705: static Job *
1.317 rillig 706: JobFindPid(int pid, JobStatus status, Boolean isJobs)
1.1 cgd 707: {
1.341 rillig 708: Job *job;
1.114 dsl 709:
1.341 rillig 710: for (job = job_table; job < job_table_end; job++) {
711: if (job->status == status && job->pid == pid)
712: return job;
713: }
714: if (DEBUG(JOB) && isJobs)
715: job_table_dump("no pid");
716: return NULL;
1.12 christos 717: }
718:
1.298 rillig 719: /* Parse leading '@', '-' and '+', which control the exact execution mode. */
720: static void
1.383 rillig 721: ParseCommandFlags(char **pp, CommandFlags *out_cmdFlags)
1.341 rillig 722: {
723: char *p = *pp;
1.360 rillig 724: out_cmdFlags->echo = TRUE;
725: out_cmdFlags->ignerr = FALSE;
726: out_cmdFlags->always = FALSE;
1.341 rillig 727:
728: for (;;) {
729: if (*p == '@')
1.360 rillig 730: out_cmdFlags->echo = DEBUG(LOUD);
1.341 rillig 731: else if (*p == '-')
1.360 rillig 732: out_cmdFlags->ignerr = TRUE;
1.341 rillig 733: else if (*p == '+')
1.360 rillig 734: out_cmdFlags->always = TRUE;
1.341 rillig 735: else
736: break;
737: p++;
738: }
1.298 rillig 739:
1.341 rillig 740: pp_skip_whitespace(&p);
1.298 rillig 741:
1.341 rillig 742: *pp = p;
1.298 rillig 743: }
744:
1.299 rillig 745: /* Escape a string for a double-quoted string literal in sh, csh and ksh. */
746: static char *
747: EscapeShellDblQuot(const char *cmd)
748: {
1.341 rillig 749: size_t i, j;
1.299 rillig 750:
1.341 rillig 751: /* Worst that could happen is every char needs escaping. */
752: char *esc = bmake_malloc(strlen(cmd) * 2 + 1);
753: for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) {
754: if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' ||
755: cmd[i] == '"')
756: esc[j++] = '\\';
757: esc[j] = cmd[i];
758: }
759: esc[j] = '\0';
1.299 rillig 760:
1.341 rillig 761: return esc;
1.299 rillig 762: }
763:
1.318 rillig 764: static void
1.371 rillig 765: ShellWriter_PrintFmt(ShellWriter *wr, const char *fmt, const char *arg)
1.318 rillig 766: {
1.343 rillig 767: DEBUG1(JOB, fmt, arg);
1.318 rillig 768:
1.371 rillig 769: (void)fprintf(wr->f, fmt, arg);
770: /* XXX: Is flushing needed in any case, or only if f == stdout? */
771: (void)fflush(wr->f);
772: }
773:
774: static void
775: ShellWriter_Println(ShellWriter *wr, const char *line)
1.318 rillig 776: {
1.371 rillig 777: ShellWriter_PrintFmt(wr, "%s\n", line);
1.318 rillig 778: }
779:
1.373 rillig 780: static void
781: ShellWriter_EchoOff(ShellWriter *wr)
782: {
783: if (shell->hasEchoCtl)
784: ShellWriter_Println(wr, shell->echoOff);
785: }
786:
787: static void
788: ShellWriter_EchoCmd(ShellWriter *wr, const char *escCmd)
789: {
1.376 rillig 790: ShellWriter_PrintFmt(wr, shell->echoTmpl, escCmd);
1.373 rillig 791: }
792:
793: static void
794: ShellWriter_EchoOn(ShellWriter *wr)
795: {
796: if (shell->hasEchoCtl)
797: ShellWriter_Println(wr, shell->echoOn);
798: }
799:
1.374 rillig 800: static void
801: ShellWriter_TraceOn(ShellWriter *wr)
802: {
803: if (!wr->xtraced) {
804: ShellWriter_Println(wr, "set -x");
805: wr->xtraced = TRUE;
806: }
807: }
808:
1.346 rillig 809: static void
1.373 rillig 810: ShellWriter_ErrOff(ShellWriter *wr, Boolean echo)
1.346 rillig 811: {
1.382 rillig 812: if (echo)
1.373 rillig 813: ShellWriter_EchoOff(wr);
1.382 rillig 814: ShellWriter_Println(wr, shell->errOff);
815: if (echo)
816: ShellWriter_EchoOn(wr);
817: }
818:
819: static void
820: ShellWriter_ErrOn(ShellWriter *wr, Boolean echo)
821: {
822: if (echo)
823: ShellWriter_EchoOff(wr);
824: ShellWriter_Println(wr, shell->errOn);
825: if (echo)
1.373 rillig 826: ShellWriter_EchoOn(wr);
1.346 rillig 827: }
828:
829: /*
1.384 rillig 830: * The shell has no built-in error control, so emulate error control by
831: * enclosing each shell command in a template like "{ %s \n } || exit $?"
832: * (configurable per shell).
1.346 rillig 833: */
834: static void
1.371 rillig 835: JobPrintSpecialsEchoCtl(Job *job, ShellWriter *wr, CommandFlags *inout_cmdFlags,
1.360 rillig 836: const char *escCmd, const char **inout_cmdTemplate)
1.346 rillig 837: {
1.372 rillig 838: /* XXX: Why is the job modified at this point? */
1.356 rillig 839: job->ignerr = TRUE;
1.346 rillig 840:
1.360 rillig 841: if (job->echo && inout_cmdFlags->echo) {
1.373 rillig 842: ShellWriter_EchoOff(wr);
843: ShellWriter_EchoCmd(wr, escCmd);
1.384 rillig 844:
845: /*
846: * Leave echoing off so the user doesn't see the commands
847: * for toggling the error checking.
848: */
1.360 rillig 849: inout_cmdFlags->echo = FALSE;
1.346 rillig 850: } else {
1.360 rillig 851: if (inout_cmdFlags->echo)
1.373 rillig 852: ShellWriter_EchoCmd(wr, escCmd);
1.346 rillig 853: }
1.364 rillig 854: *inout_cmdTemplate = shell->runIgnTmpl;
1.346 rillig 855:
856: /*
1.364 rillig 857: * The template runIgnTmpl already takes care of ignoring errors,
858: * so pretend error checking is still on.
859: * XXX: What effects does this have, and why is it necessary?
1.346 rillig 860: */
1.360 rillig 861: inout_cmdFlags->ignerr = FALSE;
1.346 rillig 862: }
863:
1.345 rillig 864: static void
1.371 rillig 865: JobPrintSpecials(Job *job, ShellWriter *wr, const char *escCmd, Boolean run,
1.370 rillig 866: CommandFlags *inout_cmdFlags, const char **inout_cmdTemplate)
1.345 rillig 867: {
1.384 rillig 868: if (!run) {
869: /*
870: * If there is no command to run, there is no need to switch
871: * error checking off and on again for nothing.
872: */
1.360 rillig 873: inout_cmdFlags->ignerr = FALSE;
1.384 rillig 874: } else if (shell->hasErrCtl)
1.373 rillig 875: ShellWriter_ErrOff(wr, job->echo && inout_cmdFlags->echo);
1.364 rillig 876: else if (shell->runIgnTmpl != NULL && shell->runIgnTmpl[0] != '\0') {
1.371 rillig 877: JobPrintSpecialsEchoCtl(job, wr, inout_cmdFlags, escCmd,
1.349 rillig 878: inout_cmdTemplate);
1.346 rillig 879: } else
1.360 rillig 880: inout_cmdFlags->ignerr = FALSE;
1.345 rillig 881: }
882:
1.338 rillig 883: /*
1.358 rillig 884: * Put out another command for the given job.
1.72 wiz 885: *
1.358 rillig 886: * If the command starts with '@' and neither the -s nor the -n flag was
887: * given to make, we stick a shell-specific echoOff command in the script.
888: *
889: * If the command starts with '-' and the shell has no error control (none
890: * of the predefined shells has that), we ignore errors for the entire job.
891: * XXX: Why ignore errors for the entire job?
892: * XXX: Even ignore errors for the commands before this command?
893: *
1.363 rillig 894: * If the command is just "...", all further commands of this job are skipped
895: * for now. They are attached to the .END node and will be run by Job_Finish
896: * after all other targets have been made.
1.1 cgd 897: */
1.270 rillig 898: static void
1.389 rillig 899: JobPrintCommand(Job *job, ShellWriter *wr, StringListNode *ln, const char *ucmd)
1.1 cgd 900: {
1.351 rillig 901: Boolean run;
1.347 rillig 902:
1.360 rillig 903: CommandFlags cmdFlags;
1.363 rillig 904: /* Template for printing a command to the shell file */
1.341 rillig 905: const char *cmdTemplate;
1.363 rillig 906: char *xcmd; /* The expanded command */
907: char *xcmdStart;
908: char *escCmd; /* xcmd escaped to be used in double quotes */
1.1 cgd 909:
1.351 rillig 910: run = GNode_ShouldExecute(job->node);
1.298 rillig 911:
1.363 rillig 912: Var_Subst(ucmd, job->node, VARE_WANTRES, &xcmd);
1.341 rillig 913: /* TODO: handle errors */
1.363 rillig 914: xcmdStart = xcmd;
1.1 cgd 915:
1.341 rillig 916: cmdTemplate = "%s\n";
1.83 jmc 917:
1.383 rillig 918: ParseCommandFlags(&xcmd, &cmdFlags);
1.83 jmc 919:
1.351 rillig 920: /* The '+' command flag overrides the -n or -N options. */
1.360 rillig 921: if (cmdFlags.always && !run) {
1.341 rillig 922: /*
923: * We're not actually executing anything...
924: * but this one needs to be - use compat mode just for it.
925: */
1.389 rillig 926: Compat_RunCommand(ucmd, job->node, ln);
1.363 rillig 927: free(xcmdStart);
1.341 rillig 928: return;
1.1 cgd 929: }
930:
1.341 rillig 931: /*
1.363 rillig 932: * If the shell doesn't have error control, the alternate echoing
933: * will be done (to avoid showing additional error checking code)
934: * and this needs some characters escaped.
1.341 rillig 935: */
1.363 rillig 936: escCmd = shell->hasErrCtl ? NULL : EscapeShellDblQuot(xcmd);
1.341 rillig 937:
1.360 rillig 938: if (!cmdFlags.echo) {
1.357 rillig 939: if (job->echo && run && shell->hasEchoCtl) {
1.373 rillig 940: ShellWriter_EchoOff(wr);
1.1 cgd 941: } else {
1.355 rillig 942: if (shell->hasErrCtl)
1.360 rillig 943: cmdFlags.echo = TRUE;
1.1 cgd 944: }
1.341 rillig 945: }
946:
1.360 rillig 947: if (cmdFlags.ignerr) {
1.371 rillig 948: JobPrintSpecials(job, wr, escCmd, run, &cmdFlags, &cmdTemplate);
1.341 rillig 949: } else {
950:
1.1 cgd 951: /*
1.341 rillig 952: * If errors are being checked and the shell doesn't have
1.364 rillig 953: * error control but does supply an runChkTmpl template, then
1.341 rillig 954: * set up commands to run through it.
955: */
956:
1.396 rillig 957: if (!shell->hasErrCtl && shell->runChkTmpl != NULL &&
1.364 rillig 958: shell->runChkTmpl[0] != '\0') {
1.360 rillig 959: if (job->echo && cmdFlags.echo) {
1.373 rillig 960: ShellWriter_EchoOff(wr);
961: ShellWriter_EchoCmd(wr, escCmd);
1.360 rillig 962: cmdFlags.echo = FALSE;
1.341 rillig 963: }
964: /*
1.367 rillig 965: * If it's a comment line or blank, avoid the possible
1.381 rillig 966: * syntax error generated by "{\n} || exit $?".
1.341 rillig 967: */
1.367 rillig 968: cmdTemplate = escCmd[0] == shell->commentChar ||
969: escCmd[0] == '\0'
970: ? shell->runIgnTmpl
971: : shell->runChkTmpl;
1.360 rillig 972: cmdFlags.ignerr = FALSE;
1.341 rillig 973: }
1.1 cgd 974: }
1.83 jmc 975:
1.374 rillig 976: if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0)
977: ShellWriter_TraceOn(wr);
1.16 christos 978:
1.376 rillig 979: ShellWriter_PrintFmt(wr, cmdTemplate, xcmd);
1.363 rillig 980: free(xcmdStart);
1.341 rillig 981: free(escCmd);
1.382 rillig 982:
983: if (cmdFlags.ignerr)
984: ShellWriter_ErrOn(wr, cmdFlags.echo && job->echo);
985:
1.373 rillig 986: if (!cmdFlags.echo)
987: ShellWriter_EchoOn(wr);
1.269 rillig 988: }
989:
1.341 rillig 990: /*
991: * Print all commands to the shell file that is later executed.
1.270 rillig 992: *
993: * The special command "..." stops printing and saves the remaining commands
1.409 rillig 994: * to be executed later, when the target '.END' is made.
1.362 rillig 995: *
996: * Return whether at least one command was written to the shell file.
1.341 rillig 997: */
1.362 rillig 998: static Boolean
1.269 rillig 999: JobPrintCommands(Job *job)
1000: {
1.341 rillig 1001: StringListNode *ln;
1.362 rillig 1002: Boolean seen = FALSE;
1.374 rillig 1003: ShellWriter wr = { job->cmdFILE, FALSE };
1.341 rillig 1004:
1005: for (ln = job->node->commands.first; ln != NULL; ln = ln->next) {
1006: const char *cmd = ln->datum;
1.269 rillig 1007:
1.341 rillig 1008: if (strcmp(cmd, "...") == 0) {
1009: job->node->type |= OP_SAVE_CMDS;
1010: job->tailCmds = ln->next;
1011: break;
1012: }
1.270 rillig 1013:
1.389 rillig 1014: JobPrintCommand(job, &wr, ln, ln->datum);
1.362 rillig 1015: seen = TRUE;
1.314 rillig 1016: }
1.362 rillig 1017:
1018: return seen;
1.1 cgd 1019: }
1020:
1.403 rillig 1021: /*
1022: * Save the delayed commands (those after '...'), to be executed later in
1023: * the '.END' node, when everything else is done.
1024: */
1.236 rillig 1025: static void
1026: JobSaveCommands(Job *job)
1.1 cgd 1027: {
1.341 rillig 1028: StringListNode *ln;
1.236 rillig 1029:
1.341 rillig 1030: for (ln = job->tailCmds; ln != NULL; ln = ln->next) {
1031: const char *cmd = ln->datum;
1032: char *expanded_cmd;
1.403 rillig 1033: /*
1034: * XXX: This Var_Subst is only intended to expand the dynamic
1.341 rillig 1035: * variables such as .TARGET, .IMPSRC. It is not intended to
1.403 rillig 1036: * expand the other variables as well; see deptgt-end.mk.
1037: */
1.341 rillig 1038: (void)Var_Subst(cmd, job->node, VARE_WANTRES, &expanded_cmd);
1039: /* TODO: handle errors */
1040: Lst_Append(&Targ_GetEndNode()->commands, expanded_cmd);
1041: }
1.12 christos 1042: }
1043:
1044:
1.243 rillig 1045: /* Called to close both input and output pipes when a job is finished. */
1.12 christos 1046: static void
1.320 rillig 1047: JobClosePipes(Job *job)
1.12 christos 1048: {
1.341 rillig 1049: clearfd(job);
1050: (void)close(job->outPipe);
1051: job->outPipe = -1;
1052:
1053: JobDoOutput(job, TRUE);
1054: (void)close(job->inPipe);
1055: job->inPipe = -1;
1.1 cgd 1056: }
1057:
1.378 rillig 1058: static void
1.379 rillig 1059: JobFinishDoneExitedError(Job *job, int *inout_status)
1.378 rillig 1060: {
1.379 rillig 1061: SwitchOutputTo(job->node);
1.378 rillig 1062: #ifdef USE_META
1.379 rillig 1063: if (useMeta) {
1064: meta_job_error(job, job->node,
1065: job->ignerr, WEXITSTATUS(*inout_status));
1066: }
1.378 rillig 1067: #endif
1.379 rillig 1068: if (!shouldDieQuietly(job->node, -1)) {
1069: (void)printf("*** [%s] Error code %d%s\n",
1070: job->node->name, WEXITSTATUS(*inout_status),
1071: job->ignerr ? " (ignored)" : "");
1072: }
1073:
1074: if (job->ignerr)
1075: *inout_status = 0;
1076: else {
1077: if (deleteOnError)
1078: JobDeleteTarget(job->node);
1079: PrintOnError(job->node, NULL);
1080: }
1081: }
1082:
1083: static void
1084: JobFinishDoneExited(Job *job, int *inout_status)
1085: {
1086: DEBUG2(JOB, "Process %d [%s] exited.\n", job->pid, job->node->name);
1087:
1088: if (WEXITSTATUS(*inout_status) != 0)
1089: JobFinishDoneExitedError(job, inout_status);
1090: else if (DEBUG(JOB)) {
1.378 rillig 1091: SwitchOutputTo(job->node);
1.379 rillig 1092: (void)printf("*** [%s] Completed successfully\n",
1093: job->node->name);
1.378 rillig 1094: }
1.379 rillig 1095: }
1096:
1097: static void
1098: JobFinishDoneSignaled(Job *job, int status)
1099: {
1100: SwitchOutputTo(job->node);
1101: (void)printf("*** [%s] Signal %d\n", job->node->name, WTERMSIG(status));
1102: if (deleteOnError)
1103: JobDeleteTarget(job->node);
1104: }
1105:
1106: static void
1107: JobFinishDone(Job *job, int *inout_status)
1108: {
1109: if (WIFEXITED(*inout_status))
1110: JobFinishDoneExited(job, inout_status);
1111: else
1112: JobFinishDoneSignaled(job, *inout_status);
1.378 rillig 1113:
1114: (void)fflush(stdout);
1115: }
1116:
1.341 rillig 1117: /*
1118: * Do final processing for the given job including updating parent nodes and
1.320 rillig 1119: * starting new jobs as available/necessary.
1120: *
1121: * Deferred commands for the job are placed on the .END node.
1122: *
1.331 rillig 1123: * If there was a serious error (job_errors != 0; not an ignored one), no more
1.320 rillig 1124: * jobs will be started.
1.1 cgd 1125: *
1.72 wiz 1126: * Input:
1127: * job job to finish
1128: * status sub-why job went away
1.1 cgd 1129: */
1.5 cgd 1130: static void
1.116 dsl 1131: JobFinish(Job *job, int status)
1.1 cgd 1132: {
1.341 rillig 1133: Boolean done, return_job_token;
1.1 cgd 1134:
1.341 rillig 1135: DEBUG3(JOB, "JobFinish: %d [%s], status %d\n",
1136: job->pid, job->node->name, status);
1.116 dsl 1137:
1.341 rillig 1138: if ((WIFEXITED(status) &&
1.356 rillig 1139: ((WEXITSTATUS(status) != 0 && !job->ignerr))) ||
1.341 rillig 1140: WIFSIGNALED(status)) {
1.377 rillig 1141: /* Finished because of an error. */
1142:
1.341 rillig 1143: JobClosePipes(job);
1144: if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1145: (void)fclose(job->cmdFILE);
1146: job->cmdFILE = NULL;
1147: }
1148: done = TRUE;
1.377 rillig 1149:
1.341 rillig 1150: } else if (WIFEXITED(status)) {
1151: /*
1152: * Deal with ignored errors in -B mode. We need to print a
1153: * message telling of the ignored error as well as to run
1154: * the next command.
1155: */
1156: done = WEXITSTATUS(status) != 0;
1.377 rillig 1157:
1.341 rillig 1158: JobClosePipes(job);
1.377 rillig 1159:
1.341 rillig 1160: } else {
1.377 rillig 1161: /* No need to close things down or anything. */
1.341 rillig 1162: done = FALSE;
1.1 cgd 1163: }
1.16 christos 1164:
1.378 rillig 1165: if (done)
1166: JobFinishDone(job, &status);
1.16 christos 1167:
1.156 sjg 1168: #ifdef USE_META
1.341 rillig 1169: if (useMeta) {
1170: int meta_status = meta_job_finish(job);
1171: if (meta_status != 0 && status == 0)
1172: status = meta_status;
1173: }
1.156 sjg 1174: #endif
1.201 rillig 1175:
1.341 rillig 1176: return_job_token = FALSE;
1.102 dsl 1177:
1.341 rillig 1178: Trace_Log(JOBEND, job);
1.356 rillig 1179: if (!job->special) {
1.341 rillig 1180: if (status != 0 ||
1181: (aborting == ABORT_ERROR) || aborting == ABORT_INTERRUPT)
1182: return_job_token = TRUE;
1183: }
1.1 cgd 1184:
1.341 rillig 1185: if (aborting != ABORT_ERROR && aborting != ABORT_INTERRUPT &&
1186: (status == 0)) {
1187: /*
1188: * As long as we aren't aborting and the job didn't return a
1189: * non-zero status that we shouldn't ignore, we call
1190: * Make_Update to update the parents.
1191: */
1192: JobSaveCommands(job);
1193: job->node->made = MADE;
1.356 rillig 1194: if (!job->special)
1.341 rillig 1195: return_job_token = TRUE;
1196: Make_Update(job->node);
1197: job->status = JOB_ST_FREE;
1198: } else if (status != 0) {
1199: job_errors++;
1200: job->status = JOB_ST_FREE;
1201: }
1202:
1203: if (job_errors > 0 && !opts.keepgoing && aborting != ABORT_INTERRUPT) {
1204: /* Prevent more jobs from getting started. */
1205: aborting = ABORT_ERROR;
1206: }
1.1 cgd 1207:
1.341 rillig 1208: if (return_job_token)
1209: Job_TokenReturn();
1.16 christos 1210:
1.341 rillig 1211: if (aborting == ABORT_ERROR && jobTokensRunning == 0)
1212: Finish(job_errors);
1.321 rillig 1213: }
1214:
1215: static void
1216: TouchRegular(GNode *gn)
1217: {
1.341 rillig 1218: const char *file = GNode_Path(gn);
1219: struct utimbuf times = { now, now };
1220: int fd;
1221: char c;
1222:
1223: if (utime(file, ×) >= 0)
1224: return;
1.321 rillig 1225:
1.341 rillig 1226: fd = open(file, O_RDWR | O_CREAT, 0666);
1227: if (fd < 0) {
1228: (void)fprintf(stderr, "*** couldn't touch %s: %s\n",
1229: file, strerror(errno));
1230: (void)fflush(stderr);
1231: return; /* XXX: What about propagating the error? */
1232: }
1233:
1234: /* Last resort: update the file's time stamps in the traditional way.
1235: * XXX: This doesn't work for empty files, which are sometimes used
1236: * as marker files. */
1237: if (read(fd, &c, 1) == 1) {
1238: (void)lseek(fd, 0, SEEK_SET);
1239: while (write(fd, &c, 1) == -1 && errno == EAGAIN)
1240: continue;
1241: }
1242: (void)close(fd); /* XXX: What about propagating the error? */
1.1 cgd 1243: }
1244:
1.391 rillig 1245: /*
1246: * Touch the given target. Called by JobStart when the -t flag was given.
1.1 cgd 1247: *
1.243 rillig 1248: * The modification date of the file is changed.
1.391 rillig 1249: * If the file did not exist, it is created.
1250: */
1.1 cgd 1251: void
1.357 rillig 1252: Job_Touch(GNode *gn, Boolean echo)
1.1 cgd 1253: {
1.341 rillig 1254: if (gn->type &
1255: (OP_JOIN | OP_USE | OP_USEBEFORE | OP_EXEC | OP_OPTIONAL |
1256: OP_SPECIAL | OP_PHONY)) {
1257: /*
1258: * These are "virtual" targets and should not really be
1259: * created.
1260: */
1261: return;
1262: }
1.16 christos 1263:
1.357 rillig 1264: if (echo || !GNode_ShouldExecute(gn)) {
1.341 rillig 1265: (void)fprintf(stdout, "touch %s\n", gn->name);
1266: (void)fflush(stdout);
1267: }
1.1 cgd 1268:
1.341 rillig 1269: if (!GNode_ShouldExecute(gn))
1270: return;
1.1 cgd 1271:
1.380 rillig 1272: if (gn->type & OP_ARCHV)
1.341 rillig 1273: Arch_Touch(gn);
1.380 rillig 1274: else if (gn->type & OP_LIB)
1.341 rillig 1275: Arch_TouchLib(gn);
1.380 rillig 1276: else
1277: TouchRegular(gn);
1.1 cgd 1278: }
1279:
1.391 rillig 1280: /*
1281: * Make sure the given node has all the commands it needs.
1.243 rillig 1282: *
1283: * The node will have commands from the .DEFAULT rule added to it if it
1284: * needs them.
1.1 cgd 1285: *
1.72 wiz 1286: * Input:
1287: * gn The target whose commands need verifying
1288: * abortProc Function to abort with message
1289: *
1.1 cgd 1290: * Results:
1291: * TRUE if the commands list is/was ok.
1292: */
1293: Boolean
1.77 christos 1294: Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
1.1 cgd 1295: {
1.341 rillig 1296: if (GNode_IsTarget(gn))
1297: return TRUE;
1298: if (!Lst_IsEmpty(&gn->commands))
1299: return TRUE;
1300: if ((gn->type & OP_LIB) && !Lst_IsEmpty(&gn->children))
1301: return TRUE;
1.280 rillig 1302:
1.281 rillig 1303: /*
1.341 rillig 1304: * No commands. Look for .DEFAULT rule from which we might infer
1305: * commands.
1.281 rillig 1306: */
1.341 rillig 1307: if (defaultNode != NULL && !Lst_IsEmpty(&defaultNode->commands) &&
1308: !(gn->type & OP_SPECIAL)) {
1309: /*
1310: * The traditional Make only looks for a .DEFAULT if the node
1311: * was never the target of an operator, so that's what we do
1312: * too.
1313: *
1314: * The .DEFAULT node acts like a transformation rule, in that
1315: * gn also inherits any attributes or sources attached to
1316: * .DEFAULT itself.
1317: */
1318: Make_HandleUse(defaultNode, gn);
1319: Var_Set(IMPSRC, GNode_VarTarget(gn), gn);
1320: return TRUE;
1321: }
1322:
1323: Dir_UpdateMTime(gn, FALSE);
1324: if (gn->mtime != 0 || (gn->type & OP_SPECIAL))
1325: return TRUE;
1.281 rillig 1326:
1.341 rillig 1327: /*
1328: * The node wasn't the target of an operator. We have no .DEFAULT
1329: * rule to go on and the target doesn't already exist. There's
1330: * nothing more we can do for this branch. If the -k flag wasn't
1331: * given, we stop in our tracks, otherwise we just don't update
1332: * this node's parents so they never get examined.
1333: */
1.282 rillig 1334:
1.341 rillig 1335: if (gn->flags & FROM_DEPEND) {
1336: if (!Job_RunTarget(".STALE", gn->fname))
1337: fprintf(stdout,
1338: "%s: %s, %d: ignoring stale %s for %s\n",
1339: progname, gn->fname, gn->lineno, makeDependfile,
1340: gn->name);
1341: return TRUE;
1342: }
1.282 rillig 1343:
1.341 rillig 1344: if (gn->type & OP_OPTIONAL) {
1345: (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n",
1346: progname, gn->name, "ignored");
1347: (void)fflush(stdout);
1348: return TRUE;
1349: }
1.282 rillig 1350:
1.341 rillig 1351: if (opts.keepgoing) {
1352: (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n",
1353: progname, gn->name, "continuing");
1354: (void)fflush(stdout);
1355: return FALSE;
1356: }
1.282 rillig 1357:
1.341 rillig 1358: abortProc("%s: don't know how to make %s. Stop", progname, gn->name);
1.282 rillig 1359: return FALSE;
1.1 cgd 1360: }
1361:
1.391 rillig 1362: /*
1363: * Execute the shell for the given job.
1.1 cgd 1364: *
1.391 rillig 1365: * See Job_CatchOutput for handling the output of the shell.
1366: */
1.1 cgd 1367: static void
1.72 wiz 1368: JobExec(Job *job, char **argv)
1.1 cgd 1369: {
1.341 rillig 1370: int cpid; /* ID of new child */
1371: sigset_t mask;
1.16 christos 1372:
1.341 rillig 1373: if (DEBUG(JOB)) {
1374: int i;
1.16 christos 1375:
1.341 rillig 1376: debug_printf("Running %s\n", job->node->name);
1377: debug_printf("\tCommand: ");
1378: for (i = 0; argv[i] != NULL; i++) {
1379: debug_printf("%s ", argv[i]);
1380: }
1381: debug_printf("\n");
1.1 cgd 1382: }
1.16 christos 1383:
1.341 rillig 1384: /*
1385: * Some jobs produce no output and it's disconcerting to have
1386: * no feedback of their running (since they produce no output, the
1387: * banner with their name in it never appears). This is an attempt to
1388: * provide that feedback, even if nothing follows it.
1389: */
1.357 rillig 1390: if (job->echo)
1.341 rillig 1391: SwitchOutputTo(job->node);
1.16 christos 1392:
1.341 rillig 1393: /* No interruptions until this job is on the `jobs' list */
1394: JobSigLock(&mask);
1.69 pk 1395:
1.341 rillig 1396: /* Pre-emptively mark job running, pid still zero though */
1397: job->status = JOB_ST_RUNNING;
1.116 dsl 1398:
1.390 rillig 1399: Var_ReexportVars();
1400:
1.411 rillig 1401: cpid = vfork();
1.341 rillig 1402: if (cpid == -1)
1403: Punt("Cannot vfork: %s", strerror(errno));
1404:
1405: if (cpid == 0) {
1406: /* Child */
1407: sigset_t tmask;
1.1 cgd 1408:
1.155 sjg 1409: #ifdef USE_META
1.341 rillig 1410: if (useMeta) {
1411: meta_job_child(job);
1412: }
1.155 sjg 1413: #endif
1.341 rillig 1414: /*
1415: * Reset all signal handlers; this is necessary because we
1416: * also need to unblock signals before we exec(2).
1417: */
1418: JobSigReset();
1.69 pk 1419:
1.341 rillig 1420: /* Now unblock signals */
1421: sigemptyset(&tmask);
1422: JobSigUnlock(&tmask);
1.69 pk 1423:
1.341 rillig 1424: /*
1425: * Must duplicate the input stream down to the child's input
1426: * and reset it to the beginning (again). Since the stream
1427: * was marked close-on-exec, we must clear that bit in the
1428: * new input.
1429: */
1430: if (dup2(fileno(job->cmdFILE), 0) == -1)
1431: execDie("dup2", "job->cmdFILE");
1432: if (fcntl(0, F_SETFD, 0) == -1)
1433: execDie("fcntl clear close-on-exec", "stdin");
1434: if (lseek(0, 0, SEEK_SET) == -1)
1435: execDie("lseek to 0", "stdin");
1436:
1437: if (job->node->type & (OP_MAKE | OP_SUBMAKE)) {
1438: /*
1439: * Pass job token pipe to submakes.
1440: */
1441: if (fcntl(tokenWaitJob.inPipe, F_SETFD, 0) == -1)
1442: execDie("clear close-on-exec",
1443: "tokenWaitJob.inPipe");
1444: if (fcntl(tokenWaitJob.outPipe, F_SETFD, 0) == -1)
1445: execDie("clear close-on-exec",
1446: "tokenWaitJob.outPipe");
1447: }
1.16 christos 1448:
1.341 rillig 1449: /*
1450: * Set up the child's output to be routed through the pipe
1451: * we've created for it.
1452: */
1453: if (dup2(job->outPipe, 1) == -1)
1454: execDie("dup2", "job->outPipe");
1.201 rillig 1455:
1.341 rillig 1456: /*
1457: * The output channels are marked close on exec. This bit
1458: * was duplicated by the dup2(on some systems), so we have
1459: * to clear it before routing the shell's error output to
1460: * the same place as its standard output.
1461: */
1462: if (fcntl(1, F_SETFD, 0) == -1)
1463: execDie("clear close-on-exec", "stdout");
1464: if (dup2(1, 2) == -1)
1465: execDie("dup2", "1, 2");
1.264 rillig 1466:
1.341 rillig 1467: /*
1468: * We want to switch the child into a different process
1469: * family so we can kill it and all its descendants in
1470: * one fell swoop, by killing its process family, but not
1471: * commit suicide.
1472: */
1.170 christos 1473: #if defined(MAKE_NATIVE) || defined(HAVE_SETPGID)
1.412 ! rillig 1474: # if defined(SYSV)
1.341 rillig 1475: /* XXX: dsl - I'm sure this should be setpgrp()... */
1476: (void)setsid();
1.412 ! rillig 1477: # else
1.341 rillig 1478: (void)setpgid(0, getpid());
1.412 ! rillig 1479: # endif
1.170 christos 1480: #endif
1.1 cgd 1481:
1.341 rillig 1482: (void)execv(shellPath, argv);
1483: execDie("exec", shellPath);
1484: }
1.116 dsl 1485:
1.341 rillig 1486: /* Parent, continuing after the child exec */
1487: job->pid = cpid;
1.1 cgd 1488:
1.341 rillig 1489: Trace_Log(JOBSTART, job);
1.40 sommerfe 1490:
1.196 riastrad 1491: #ifdef USE_META
1.341 rillig 1492: if (useMeta) {
1493: meta_job_parent(job, cpid);
1494: }
1.196 riastrad 1495: #endif
1496:
1.341 rillig 1497: /*
1498: * Set the current position in the buffer to the beginning
1499: * and mark another stream to watch in the outputs mask
1500: */
1501: job->curPos = 0;
1.16 christos 1502:
1.341 rillig 1503: watchfd(job);
1.1 cgd 1504:
1.341 rillig 1505: if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1506: (void)fclose(job->cmdFILE);
1507: job->cmdFILE = NULL;
1508: }
1.1 cgd 1509:
1.409 rillig 1510: /* Now that the job is actually running, add it to the table. */
1.341 rillig 1511: if (DEBUG(JOB)) {
1512: debug_printf("JobExec(%s): pid %d added to jobs table\n",
1513: job->node->name, job->pid);
1514: job_table_dump("job started");
1515: }
1516: JobSigUnlock(&mask);
1.1 cgd 1517: }
1518:
1.228 rillig 1519: /* Create the argv needed to execute the shell for a given job. */
1.1 cgd 1520: static void
1.72 wiz 1521: JobMakeArgv(Job *job, char **argv)
1.1 cgd 1522: {
1.341 rillig 1523: int argc;
1524: static char args[10]; /* For merged arguments */
1.16 christos 1525:
1.341 rillig 1526: argv[0] = UNCONST(shellName);
1527: argc = 1;
1.1 cgd 1528:
1.375 rillig 1529: if ((shell->errFlag != NULL && shell->errFlag[0] != '-') ||
1.366 rillig 1530: (shell->echoFlag != NULL && shell->echoFlag[0] != '-')) {
1.341 rillig 1531: /*
1532: * At least one of the flags doesn't have a minus before it,
1533: * so merge them together. Have to do this because the Bourne
1534: * shell thinks its second argument is a file to source.
1535: * Grrrr. Note the ten-character limitation on the combined
1536: * arguments.
1537: *
1538: * TODO: Research until when the above comments were
1539: * practically relevant.
1540: */
1541: (void)snprintf(args, sizeof args, "-%s%s",
1.356 rillig 1542: (job->ignerr ? "" :
1.375 rillig 1543: (shell->errFlag != NULL ? shell->errFlag : "")),
1.357 rillig 1544: (!job->echo ? "" :
1.366 rillig 1545: (shell->echoFlag != NULL ? shell->echoFlag : "")));
1.341 rillig 1546:
1.397 rillig 1547: if (args[1] != '\0') {
1.341 rillig 1548: argv[argc] = args;
1549: argc++;
1550: }
1551: } else {
1.396 rillig 1552: if (!job->ignerr && shell->errFlag != NULL) {
1.375 rillig 1553: argv[argc] = UNCONST(shell->errFlag);
1.341 rillig 1554: argc++;
1555: }
1.396 rillig 1556: if (job->echo && shell->echoFlag != NULL) {
1.366 rillig 1557: argv[argc] = UNCONST(shell->echoFlag);
1.341 rillig 1558: argc++;
1559: }
1.1 cgd 1560: }
1.341 rillig 1561: argv[argc] = NULL;
1.1 cgd 1562: }
1563:
1.361 rillig 1564: static void
1.400 rillig 1565: JobWriteShellCommands(Job *job, GNode *gn, Boolean cmdsOK, Boolean *out_run)
1.361 rillig 1566: {
1567: /*
1568: * tfile is the name of a file into which all shell commands
1569: * are put. It is removed before the child shell is executed,
1570: * unless DEBUG(SCRIPT) is set.
1571: */
1572: char *tfile;
1573: sigset_t mask;
1574: int tfd; /* File descriptor to the temp file */
1575:
1576: /*
1577: * We're serious here, but if the commands were bogus, we're
1578: * also dead...
1579: */
1580: if (!cmdsOK) {
1581: PrintOnError(gn, NULL); /* provide some clue */
1582: DieHorribly();
1583: }
1584:
1585: JobSigLock(&mask);
1586: tfd = mkTempFile(TMPPAT, &tfile);
1587: if (!DEBUG(SCRIPT))
1588: (void)eunlink(tfile);
1589: JobSigUnlock(&mask);
1590:
1591: job->cmdFILE = fdopen(tfd, "w+");
1592: if (job->cmdFILE == NULL)
1593: Punt("Could not fdopen %s", tfile);
1594:
1595: (void)fcntl(fileno(job->cmdFILE), F_SETFD, FD_CLOEXEC);
1596:
1597: #ifdef USE_META
1598: if (useMeta) {
1599: meta_job_start(job, gn);
1.369 rillig 1600: if (gn->type & OP_SILENT) /* might have changed */
1.361 rillig 1601: job->echo = FALSE;
1602: }
1603: #endif
1.362 rillig 1604:
1.404 rillig 1605: *out_run = JobPrintCommands(job);
1.361 rillig 1606:
1607: free(tfile);
1608: }
1609:
1.338 rillig 1610: /*
1611: * Start a target-creation process going for the target described by the
1612: * graph node gn.
1.1 cgd 1613: *
1.72 wiz 1614: * Input:
1615: * gn target to create
1616: * flags flags for the job to override normal ones.
1617: * previous The previous Job structure for this node, if any.
1618: *
1.1 cgd 1619: * Results:
1620: * JOB_ERROR if there was an error in the commands, JOB_FINISHED
1621: * if there isn't actually anything left to do for the job and
1622: * JOB_RUNNING if the job has been started.
1623: *
1624: * Side Effects:
1625: * A new Job node is created and added to the list of running
1626: * jobs. PMake is forked and a child shell created.
1.110 dsl 1627: *
1.314 rillig 1628: * NB: The return value is ignored by everyone.
1.1 cgd 1629: */
1.284 rillig 1630: static JobStartResult
1.354 rillig 1631: JobStart(GNode *gn, Boolean special)
1.1 cgd 1632: {
1.341 rillig 1633: Job *job; /* new job descriptor */
1634: char *argv[10]; /* Argument vector to shell */
1635: Boolean cmdsOK; /* true if the nodes commands were all right */
1.353 rillig 1636: Boolean run;
1.341 rillig 1637:
1638: for (job = job_table; job < job_table_end; job++) {
1639: if (job->status == JOB_ST_FREE)
1640: break;
1641: }
1642: if (job >= job_table_end)
1643: Punt("JobStart no job slots vacant");
1.122 dsl 1644:
1.341 rillig 1645: memset(job, 0, sizeof *job);
1646: job->node = gn;
1647: job->tailCmds = NULL;
1648: job->status = JOB_ST_SET_UP;
1.1 cgd 1649:
1.369 rillig 1650: job->special = special || gn->type & OP_SPECIAL;
1651: job->ignerr = opts.ignoreErrors || gn->type & OP_IGNORE;
1652: job->echo = !(opts.beSilent || gn->type & OP_SILENT);
1.16 christos 1653:
1.1 cgd 1654: /*
1.341 rillig 1655: * Check the commands now so any attributes from .DEFAULT have a
1656: * chance to migrate to the node.
1.34 christos 1657: */
1.341 rillig 1658: cmdsOK = Job_CheckCommands(gn, Error);
1659:
1660: job->inPollfd = NULL;
1.403 rillig 1661:
1.399 rillig 1662: if (Lst_IsEmpty(&gn->commands)) {
1663: job->cmdFILE = stdout;
1664: run = FALSE;
1665: } else if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) ||
1.341 rillig 1666: (!opts.noExecute && !opts.touchFlag)) {
1.401 rillig 1667: /*
1.403 rillig 1668: * The above condition looks very similar to
1669: * GNode_ShouldExecute but is subtly different.
1670: * It prevents that .MAKE targets are touched.
1.401 rillig 1671: */
1.402 rillig 1672:
1.400 rillig 1673: JobWriteShellCommands(job, gn, cmdsOK, &run);
1.401 rillig 1674: (void)fflush(job->cmdFILE);
1.341 rillig 1675: } else if (!GNode_ShouldExecute(gn)) {
1676: /*
1677: * Not executing anything -- just print all the commands to
1678: * stdout in one fell swoop. This will still set up
1679: * job->tailCmds correctly.
1680: */
1681: SwitchOutputTo(gn);
1682: job->cmdFILE = stdout;
1683: if (cmdsOK)
1684: JobPrintCommands(job);
1685: /* Don't execute the shell, thank you. */
1.353 rillig 1686: run = FALSE;
1.401 rillig 1687: (void)fflush(job->cmdFILE);
1.341 rillig 1688: } else {
1689: /*
1690: * Just touch the target and note that no shell should be
1691: * executed. Set cmdFILE to stdout to make life easier.
1692: */
1693: job->cmdFILE = stdout;
1.357 rillig 1694: Job_Touch(gn, job->echo);
1.353 rillig 1695: run = FALSE;
1.341 rillig 1696: }
1697:
1698: /* If we're not supposed to execute a shell, don't. */
1.353 rillig 1699: if (!run) {
1.356 rillig 1700: if (!job->special)
1.341 rillig 1701: Job_TokenReturn();
1702: /* Unlink and close the command file if we opened one */
1703: if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
1704: (void)fclose(job->cmdFILE);
1705: job->cmdFILE = NULL;
1706: }
1.1 cgd 1707:
1.341 rillig 1708: /*
1709: * We only want to work our way up the graph if we aren't
1710: * here because the commands for the job were no good.
1711: */
1712: if (cmdsOK && aborting == ABORT_NONE) {
1713: JobSaveCommands(job);
1714: job->node->made = MADE;
1715: Make_Update(job->node);
1716: }
1717: job->status = JOB_ST_FREE;
1718: return cmdsOK ? JOB_FINISHED : JOB_ERROR;
1.1 cgd 1719: }
1720:
1721: /*
1.341 rillig 1722: * Set up the control arguments to the shell. This is based on the
1723: * flags set earlier for this job.
1.1 cgd 1724: */
1.341 rillig 1725: JobMakeArgv(job, argv);
1.1 cgd 1726:
1.341 rillig 1727: /* Create the pipe by which we'll get the shell's output. */
1728: JobCreatePipe(job, 3);
1.1 cgd 1729:
1.341 rillig 1730: JobExec(job, argv);
1731: return JOB_RUNNING;
1.1 cgd 1732: }
1733:
1.341 rillig 1734: /*
1.392 rillig 1735: * Print the output of the shell command, skipping the noPrint text of the
1736: * shell, if any. The default shell does not have noPrint though, which means
1737: * that in all practical cases, handling the output is left to the caller.
1.341 rillig 1738: */
1.16 christos 1739: static char *
1.392 rillig 1740: JobOutput(char *cp, char *endp) /* XXX: should all be const */
1.12 christos 1741: {
1.392 rillig 1742: char *ecp; /* XXX: should be const */
1.12 christos 1743:
1.355 rillig 1744: if (shell->noPrint == NULL || shell->noPrint[0] == '\0')
1.341 rillig 1745: return cp;
1.324 rillig 1746:
1.392 rillig 1747: /*
1748: * XXX: What happens if shell->noPrint occurs on the boundary of
1749: * the buffer? To work correctly in all cases, this should rather
1750: * be a proper stream filter instead of doing string matching on
1751: * selected chunks of the output.
1752: */
1.355 rillig 1753: while ((ecp = strstr(cp, shell->noPrint)) != NULL) {
1.341 rillig 1754: if (ecp != cp) {
1.392 rillig 1755: *ecp = '\0'; /* XXX: avoid writing to the buffer */
1.341 rillig 1756: /*
1757: * The only way there wouldn't be a newline after
1758: * this line is if it were the last in the buffer.
1.392 rillig 1759: * however, since the noPrint output comes after it,
1.341 rillig 1760: * there must be a newline, so we don't print one.
1761: */
1.392 rillig 1762: /* XXX: What about null bytes in the output? */
1.341 rillig 1763: (void)fprintf(stdout, "%s", cp);
1764: (void)fflush(stdout);
1765: }
1.355 rillig 1766: cp = ecp + shell->noPrintLen;
1.392 rillig 1767: if (cp == endp)
1768: break;
1769: cp++; /* skip over the (XXX: assumed) newline */
1770: pp_skip_whitespace(&cp);
1.12 christos 1771: }
1.341 rillig 1772: return cp;
1.12 christos 1773: }
1774:
1.325 rillig 1775: /*
1776: * This function is called whenever there is something to read on the pipe.
1777: * We collect more output from the given job and store it in the job's
1778: * outBuf. If this makes up a line, we print it tagged by the job's
1779: * identifier, as necessary.
1780: *
1781: * In the output of the shell, the 'noPrint' lines are removed. If the
1782: * command is not alone on the line (the character after it is not \0 or
1783: * \n), we do print whatever follows it.
1.1 cgd 1784: *
1.72 wiz 1785: * Input:
1786: * job the job whose output needs printing
1787: * finish TRUE if this is the last time we'll be called
1788: * for this job
1.1 cgd 1789: */
1.285 rillig 1790: static void
1.72 wiz 1791: JobDoOutput(Job *job, Boolean finish)
1.1 cgd 1792: {
1.341 rillig 1793: Boolean gotNL; /* true if got a newline */
1794: Boolean fbuf; /* true if our buffer filled up */
1795: size_t nr; /* number of bytes read */
1796: size_t i; /* auxiliary index into outBuf */
1797: size_t max; /* limit for i (end of current data) */
1798: ssize_t nRead; /* (Temporary) number of bytes read */
1.1 cgd 1799:
1.341 rillig 1800: /* Read as many bytes as will fit in the buffer. */
1.325 rillig 1801: again:
1.341 rillig 1802: gotNL = FALSE;
1803: fbuf = FALSE;
1.16 christos 1804:
1.341 rillig 1805: nRead = read(job->inPipe, &job->outBuf[job->curPos],
1806: JOB_BUFSIZE - job->curPos);
1807: if (nRead < 0) {
1808: if (errno == EAGAIN)
1809: return;
1810: if (DEBUG(JOB)) {
1811: perror("JobDoOutput(piperead)");
1812: }
1813: nr = 0;
1814: } else {
1815: nr = (size_t)nRead;
1.1 cgd 1816: }
1817:
1.341 rillig 1818: /*
1819: * If we hit the end-of-file (the job is dead), we must flush its
1820: * remaining output, so pretend we read a newline if there's any
1821: * output remaining in the buffer.
1822: * Also clear the 'finish' flag so we stop looping.
1823: */
1824: if (nr == 0 && job->curPos != 0) {
1825: job->outBuf[job->curPos] = '\n';
1826: nr = 1;
1827: finish = FALSE;
1828: } else if (nr == 0) {
1829: finish = FALSE;
1830: }
1.16 christos 1831:
1.341 rillig 1832: /*
1833: * Look for the last newline in the bytes we just got. If there is
1834: * one, break out of the loop with 'i' as its index and gotNL set
1835: * TRUE.
1836: */
1837: max = job->curPos + nr;
1838: for (i = job->curPos + nr - 1;
1839: i >= job->curPos && i != (size_t)-1; i--) {
1840: if (job->outBuf[i] == '\n') {
1841: gotNL = TRUE;
1842: break;
1843: } else if (job->outBuf[i] == '\0') {
1844: /*
1845: * Why?
1846: */
1847: job->outBuf[i] = ' ';
1848: }
1.1 cgd 1849: }
1.16 christos 1850:
1.341 rillig 1851: if (!gotNL) {
1852: job->curPos += nr;
1853: if (job->curPos == JOB_BUFSIZE) {
1854: /*
1855: * If we've run out of buffer space, we have no choice
1856: * but to print the stuff. sigh.
1857: */
1858: fbuf = TRUE;
1859: i = job->curPos;
1860: }
1.120 dsl 1861: }
1.341 rillig 1862: if (gotNL || fbuf) {
1863: /*
1864: * Need to send the output to the screen. Null terminate it
1865: * first, overwriting the newline character if there was one.
1866: * So long as the line isn't one we should filter (according
1867: * to the shell description), we print the line, preceded
1868: * by a target banner if this target isn't the same as the
1869: * one for which we last printed something.
1870: * The rest of the data in the buffer are then shifted down
1871: * to the start of the buffer and curPos is set accordingly.
1872: */
1873: job->outBuf[i] = '\0';
1874: if (i >= job->curPos) {
1875: char *cp;
1876:
1877: cp = JobOutput(job->outBuf, &job->outBuf[i]);
1878:
1879: /*
1880: * There's still more in that thar buffer. This time,
1881: * though, we know there's no newline at the end, so
1882: * we add one of our own free will.
1883: */
1884: if (*cp != '\0') {
1885: if (!opts.beSilent)
1886: SwitchOutputTo(job->node);
1.155 sjg 1887: #ifdef USE_META
1.341 rillig 1888: if (useMeta) {
1889: meta_job_output(job, cp,
1890: gotNL ? "\n" : "");
1891: }
1892: #endif
1893: (void)fprintf(stdout, "%s%s", cp,
1894: gotNL ? "\n" : "");
1895: (void)fflush(stdout);
1896: }
1897: }
1898: /*
1899: * max is the last offset still in the buffer. Move any
1900: * remaining characters to the start of the buffer and
1901: * update the end marker curPos.
1902: */
1903: if (i < max) {
1904: (void)memmove(job->outBuf, &job->outBuf[i + 1],
1905: max - (i + 1));
1906: job->curPos = max - (i + 1);
1907: } else {
1908: assert(i == max);
1909: job->curPos = 0;
1.155 sjg 1910: }
1.120 dsl 1911: }
1.341 rillig 1912: if (finish) {
1913: /*
1914: * If the finish flag is true, we must loop until we hit
1915: * end-of-file on the pipe. This is guaranteed to happen
1916: * eventually since the other end of the pipe is now closed
1917: * (we closed it explicitly and the child has exited). When
1918: * we do get an EOF, finish will be set FALSE and we'll fall
1919: * through and out.
1920: */
1921: goto again;
1.180 joerg 1922: }
1.1 cgd 1923: }
1924:
1.91 christos 1925: static void
1926: JobRun(GNode *targ)
1927: {
1.238 rillig 1928: #if 0
1.341 rillig 1929: /*
1930: * Unfortunately it is too complicated to run .BEGIN, .END, and
1931: * .INTERRUPT job in the parallel job module. As of 2020-09-25,
1932: * unit-tests/deptgt-end-jobs.mk hangs in an endless loop.
1933: *
1934: * Running these jobs in compat mode also guarantees that these
1935: * jobs do not overlap with other unrelated jobs.
1936: */
1.410 rillig 1937: GNodeList lst = LST_INIT;
1938: Lst_Append(&lst, targ);
1939: (void)Make_Run(&lst);
1940: Lst_Done(&lst);
1941: JobStart(targ, TRUE);
1.341 rillig 1942: while (jobTokensRunning != 0) {
1943: Job_CatchOutput();
1944: }
1.91 christos 1945: #else
1.341 rillig 1946: Compat_Make(targ, targ);
1947: /* XXX: Replace with GNode_IsError(gn) */
1948: if (targ->made == ERROR) {
1949: PrintOnError(targ, "\n\nStop.");
1950: exit(1);
1951: }
1.91 christos 1952: #endif
1953: }
1954:
1.391 rillig 1955: /*
1956: * Handle the exit of a child. Called from Make_Make.
1.1 cgd 1957: *
1.243 rillig 1958: * The job descriptor is removed from the list of children.
1.1 cgd 1959: *
1960: * Notes:
1961: * We do waits, blocking or not, according to the wisdom of our
1962: * caller, until there are no more children to report. For each
1.118 dsl 1963: * job, call JobFinish to finish things off.
1.1 cgd 1964: */
1965: void
1.120 dsl 1966: Job_CatchChildren(void)
1.1 cgd 1967: {
1.341 rillig 1968: int pid; /* pid of dead child */
1969: int status; /* Exit/termination status */
1.1 cgd 1970:
1.341 rillig 1971: /* Don't even bother if we know there's no one around. */
1972: if (jobTokensRunning == 0)
1973: return;
1.16 christos 1974:
1.405 sjg 1975: /* Have we received SIGCHLD since last call? */
1976: if (caught_sigchld == 0)
1977: return;
1978: caught_sigchld = 0;
1979:
1.341 rillig 1980: while ((pid = waitpid((pid_t)-1, &status, WNOHANG | WUNTRACED)) > 0) {
1981: DEBUG2(JOB, "Process %d exited/stopped status %x.\n",
1982: pid, status);
1983: JobReapChild(pid, status, TRUE);
1984: }
1.153 sjg 1985: }
1986:
1987: /*
1988: * It is possible that wait[pid]() was called from elsewhere,
1989: * this lets us reap jobs regardless.
1990: */
1991: void
1992: JobReapChild(pid_t pid, int status, Boolean isJobs)
1993: {
1.341 rillig 1994: Job *job; /* job descriptor for dead child */
1.153 sjg 1995:
1.341 rillig 1996: /* Don't even bother if we know there's no one around. */
1997: if (jobTokensRunning == 0)
1998: return;
1.16 christos 1999:
1.341 rillig 2000: job = JobFindPid(pid, JOB_ST_RUNNING, isJobs);
2001: if (job == NULL) {
2002: if (isJobs) {
2003: if (!lurking_children)
2004: Error("Child (%d) status %x not in table?",
2005: pid, status);
2006: }
2007: return; /* not ours */
1.116 dsl 2008: }
1.341 rillig 2009: if (WIFSTOPPED(status)) {
2010: DEBUG2(JOB, "Process %d (%s) stopped.\n",
2011: job->pid, job->node->name);
2012: if (!make_suspended) {
2013: switch (WSTOPSIG(status)) {
2014: case SIGTSTP:
2015: (void)printf("*** [%s] Suspended\n",
2016: job->node->name);
2017: break;
2018: case SIGSTOP:
2019: (void)printf("*** [%s] Stopped\n",
2020: job->node->name);
2021: break;
2022: default:
2023: (void)printf("*** [%s] Stopped -- signal %d\n",
2024: job->node->name, WSTOPSIG(status));
2025: }
2026: job->suspended = TRUE;
2027: }
2028: (void)fflush(stdout);
2029: return;
1.1 cgd 2030: }
2031:
1.341 rillig 2032: job->status = JOB_ST_FINISHED;
2033: job->exit_status = status;
1.116 dsl 2034:
1.341 rillig 2035: JobFinish(job, status);
1.1 cgd 2036: }
2037:
1.391 rillig 2038: /*
2039: * Catch the output from our children, if we're using pipes do so. Otherwise
1.243 rillig 2040: * just block time until we get a signal(most likely a SIGCHLD) since there's
2041: * no point in just spinning when there's nothing to do and the reaping of a
1.391 rillig 2042: * child can wait for a while.
2043: */
1.1 cgd 2044: void
1.72 wiz 2045: Job_CatchOutput(void)
1.1 cgd 2046: {
1.341 rillig 2047: int nready;
2048: Job *job;
2049: unsigned int i;
1.169 christos 2050:
1.341 rillig 2051: (void)fflush(stdout);
1.120 dsl 2052:
1.341 rillig 2053: /* The first fd in the list is the job token pipe */
2054: do {
1.408 rillig 2055: nready = poll(fds + 1 - wantToken, fdsLen - 1 + wantToken,
1.341 rillig 2056: POLL_MSEC);
2057: } while (nready < 0 && errno == EINTR);
2058:
2059: if (nready < 0)
2060: Punt("poll: %s", strerror(errno));
2061:
2062: if (nready > 0 && readyfd(&childExitJob)) {
2063: char token = 0;
2064: ssize_t count;
2065: count = read(childExitJob.inPipe, &token, 1);
1.409 rillig 2066: if (count == 1) {
1.341 rillig 2067: if (token == DO_JOB_RESUME[0])
2068: /*
2069: * Complete relay requested from our SIGCONT
2070: * handler
2071: */
2072: JobRestartJobs();
1.409 rillig 2073: } else if (count == 0)
2074: Punt("unexpected eof on token pipe");
2075: else
2076: Punt("token pipe read: %s", strerror(errno));
1.341 rillig 2077: nready--;
1.169 christos 2078: }
1.120 dsl 2079:
1.341 rillig 2080: Job_CatchChildren();
2081: if (nready == 0)
2082: return;
2083:
1.408 rillig 2084: for (i = npseudojobs * nfds_per_job(); i < fdsLen; i++) {
1.396 rillig 2085: if (fds[i].revents == 0)
1.341 rillig 2086: continue;
1.408 rillig 2087: job = jobByFdIndex[i];
1.341 rillig 2088: if (job->status == JOB_ST_RUNNING)
2089: JobDoOutput(job, FALSE);
1.197 sjg 2090: #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
1.341 rillig 2091: /*
2092: * With meta mode, we may have activity on the job's filemon
2093: * descriptor too, which at the moment is any pollfd other
2094: * than job->inPollfd.
2095: */
2096: if (useMeta && job->inPollfd != &fds[i]) {
2097: if (meta_job_event(job) <= 0) {
2098: fds[i].events = 0; /* never mind */
2099: }
2100: }
2101: #endif
2102: if (--nready == 0)
2103: return;
1.196 riastrad 2104: }
1.1 cgd 2105: }
2106:
1.391 rillig 2107: /*
2108: * Start the creation of a target. Basically a front-end for JobStart used by
2109: * the Make module.
2110: */
1.1 cgd 2111: void
1.72 wiz 2112: Job_Make(GNode *gn)
1.1 cgd 2113: {
1.354 rillig 2114: (void)JobStart(gn, FALSE);
1.1 cgd 2115: }
2116:
1.344 rillig 2117: static void
2118: InitShellNameAndPath(void)
2119: {
1.355 rillig 2120: shellName = shell->name;
1.344 rillig 2121:
2122: #ifdef DEFSHELL_CUSTOM
2123: if (shellName[0] == '/') {
2124: shellPath = shellName;
1.387 rillig 2125: shellName = str_basename(shellPath);
1.344 rillig 2126: return;
2127: }
2128: #endif
2129:
2130: shellPath = str_concat3(_PATH_DEFSHELLDIR, "/", shellName);
2131: }
2132:
1.81 sjg 2133: void
1.120 dsl 2134: Shell_Init(void)
1.81 sjg 2135: {
1.344 rillig 2136: if (shellPath == NULL)
2137: InitShellNameAndPath();
2138:
1.341 rillig 2139: Var_SetWithFlags(".SHELL", shellPath, VAR_CMDLINE, VAR_SET_READONLY);
1.375 rillig 2140: if (shell->errFlag == NULL)
2141: shell->errFlag = "";
1.366 rillig 2142: if (shell->echoFlag == NULL)
2143: shell->echoFlag = "";
1.375 rillig 2144: if (shell->hasErrCtl && shell->errFlag[0] != '\0') {
1.396 rillig 2145: if (shellErrFlag != NULL &&
1.375 rillig 2146: strcmp(shell->errFlag, &shellErrFlag[1]) != 0) {
1.341 rillig 2147: free(shellErrFlag);
2148: shellErrFlag = NULL;
2149: }
2150: if (shellErrFlag == NULL) {
1.375 rillig 2151: size_t n = strlen(shell->errFlag) + 2;
1.341 rillig 2152:
2153: shellErrFlag = bmake_malloc(n);
1.355 rillig 2154: if (shellErrFlag != NULL)
1.366 rillig 2155: snprintf(shellErrFlag, n, "-%s",
1.375 rillig 2156: shell->errFlag);
1.341 rillig 2157: }
2158: } else if (shellErrFlag != NULL) {
2159: free(shellErrFlag);
2160: shellErrFlag = NULL;
2161: }
1.81 sjg 2162: }
2163:
1.341 rillig 2164: /*
2165: * Return the string literal that is used in the current command shell
2166: * to produce a newline character.
2167: */
1.112 rillig 2168: const char *
2169: Shell_GetNewline(void)
2170: {
1.355 rillig 2171: return shell->newline;
1.112 rillig 2172: }
2173:
1.125 sjg 2174: void
2175: Job_SetPrefix(void)
2176: {
1.341 rillig 2177: if (targPrefix != NULL) {
2178: free(targPrefix);
2179: } else if (!Var_Exists(MAKE_JOB_PREFIX, VAR_GLOBAL)) {
2180: Var_Set(MAKE_JOB_PREFIX, "---", VAR_GLOBAL);
2181: }
1.128 dsl 2182:
1.341 rillig 2183: (void)Var_Subst("${" MAKE_JOB_PREFIX "}",
2184: VAR_GLOBAL, VARE_WANTRES, &targPrefix);
2185: /* TODO: handle errors */
1.125 sjg 2186: }
2187:
1.342 rillig 2188: static void
2189: AddSig(int sig, SignalProc handler)
2190: {
2191: if (bmake_signal(sig, SIG_IGN) != SIG_IGN) {
2192: sigaddset(&caught_signals, sig);
2193: (void)bmake_signal(sig, handler);
2194: }
2195: }
2196:
1.222 rillig 2197: /* Initialize the process module. */
1.1 cgd 2198: void
1.111 dsl 2199: Job_Init(void)
1.1 cgd 2200: {
1.341 rillig 2201: Job_SetPrefix();
2202: /* Allocate space for all the job info */
2203: job_table = bmake_malloc((size_t)opts.maxJobs * sizeof *job_table);
2204: memset(job_table, 0, (size_t)opts.maxJobs * sizeof *job_table);
2205: job_table_end = job_table + opts.maxJobs;
2206: wantToken = 0;
1.405 sjg 2207: caught_sigchld = 0;
1.341 rillig 2208:
2209: aborting = ABORT_NONE;
2210: job_errors = 0;
2211:
2212: /*
2213: * There is a non-zero chance that we already have children.
2214: * eg after 'make -f- <<EOF'
2215: * Since their termination causes a 'Child (pid) not in table'
2216: * message, Collect the status of any that are already dead, and
2217: * suppress the error message if there are any undead ones.
2218: */
2219: for (;;) {
2220: int rval, status;
2221: rval = waitpid((pid_t)-1, &status, WNOHANG);
2222: if (rval > 0)
2223: continue;
2224: if (rval == 0)
2225: lurking_children = TRUE;
2226: break;
2227: }
1.1 cgd 2228:
1.341 rillig 2229: Shell_Init();
1.1 cgd 2230:
1.341 rillig 2231: JobCreatePipe(&childExitJob, 3);
1.117 dsl 2232:
1.408 rillig 2233: {
2234: /* Preallocate enough for the maximum number of jobs. */
2235: size_t nfds = (npseudojobs + (size_t)opts.maxJobs) *
2236: nfds_per_job();
2237: fds = bmake_malloc(sizeof *fds * nfds);
2238: jobByFdIndex = bmake_malloc(sizeof *jobByFdIndex * nfds);
2239: }
1.1 cgd 2240:
1.341 rillig 2241: /* These are permanent entries and take slots 0 and 1 */
2242: watchfd(&tokenWaitJob);
2243: watchfd(&childExitJob);
1.73 gson 2244:
1.341 rillig 2245: sigemptyset(&caught_signals);
2246: /*
2247: * Install a SIGCHLD handler.
2248: */
2249: (void)bmake_signal(SIGCHLD, JobChildSig);
2250: sigaddset(&caught_signals, SIGCHLD);
1.122 dsl 2251:
1.341 rillig 2252: /*
2253: * Catch the four signals that POSIX specifies if they aren't ignored.
2254: * JobPassSig will take care of calling JobInterrupt if appropriate.
2255: */
1.342 rillig 2256: AddSig(SIGINT, JobPassSig_int);
2257: AddSig(SIGHUP, JobPassSig_term);
2258: AddSig(SIGTERM, JobPassSig_term);
2259: AddSig(SIGQUIT, JobPassSig_term);
1.69 pk 2260:
1.341 rillig 2261: /*
2262: * There are additional signals that need to be caught and passed if
2263: * either the export system wants to be told directly of signals or if
2264: * we're giving each job its own process group (since then it won't get
2265: * signals from the terminal driver as we own the terminal)
2266: */
1.342 rillig 2267: AddSig(SIGTSTP, JobPassSig_suspend);
2268: AddSig(SIGTTOU, JobPassSig_suspend);
2269: AddSig(SIGTTIN, JobPassSig_suspend);
2270: AddSig(SIGWINCH, JobCondPassSig);
2271: AddSig(SIGCONT, JobContinueSig);
1.16 christos 2272:
1.341 rillig 2273: (void)Job_RunTarget(".BEGIN", NULL);
2274: /* Create the .END node now, even though no code in the unit tests
2275: * depends on it. See also Targ_GetEndNode in Compat_Run. */
2276: (void)Targ_GetEndNode();
1.1 cgd 2277: }
2278:
1.342 rillig 2279: static void
2280: DelSig(int sig)
2281: {
1.397 rillig 2282: if (sigismember(&caught_signals, sig) != 0)
1.342 rillig 2283: (void)bmake_signal(sig, SIG_DFL);
2284: }
2285:
1.388 rillig 2286: static void
2287: JobSigReset(void)
1.69 pk 2288: {
1.342 rillig 2289: DelSig(SIGINT);
2290: DelSig(SIGHUP);
2291: DelSig(SIGQUIT);
2292: DelSig(SIGTERM);
2293: DelSig(SIGTSTP);
2294: DelSig(SIGTTOU);
2295: DelSig(SIGTTIN);
2296: DelSig(SIGWINCH);
2297: DelSig(SIGCONT);
1.341 rillig 2298: (void)bmake_signal(SIGCHLD, SIG_DFL);
1.69 pk 2299: }
2300:
1.222 rillig 2301: /* Find a shell in 'shells' given its name, or return NULL. */
1.1 cgd 2302: static Shell *
1.301 rillig 2303: FindShellByName(const char *name)
1.1 cgd 2304: {
1.341 rillig 2305: Shell *sh = shells;
2306: const Shell *shellsEnd = sh + sizeof shells / sizeof shells[0];
1.1 cgd 2307:
1.341 rillig 2308: for (sh = shells; sh < shellsEnd; sh++) {
2309: if (strcmp(name, sh->name) == 0)
2310: return sh;
2311: }
2312: return NULL;
1.1 cgd 2313: }
2314:
1.338 rillig 2315: /*
1.355 rillig 2316: * Parse a shell specification and set up 'shell', shellPath and
1.338 rillig 2317: * shellName appropriately.
1.1 cgd 2318: *
1.72 wiz 2319: * Input:
2320: * line The shell spec
2321: *
1.1 cgd 2322: * Results:
1.224 rillig 2323: * FALSE if the specification was incorrect.
1.1 cgd 2324: *
2325: * Side Effects:
1.355 rillig 2326: * 'shell' points to a Shell structure (either predefined or
1.1 cgd 2327: * created from the shell spec), shellPath is the full path of the
1.355 rillig 2328: * shell described by 'shell', while shellName is just the
1.1 cgd 2329: * final component of shellPath.
2330: *
2331: * Notes:
2332: * A shell specification consists of a .SHELL target, with dependency
2333: * operator, followed by a series of blank-separated words. Double
2334: * quotes can be used to use blanks in words. A backslash escapes
2335: * anything (most notably a double-quote and a space) and
2336: * provides the functionality it does in C. Each word consists of
2337: * keyword and value separated by an equal sign. There should be no
2338: * unnecessary spaces in the word. The keywords are as follows:
1.246 rillig 2339: * name Name of shell.
2340: * path Location of shell.
2341: * quiet Command to turn off echoing.
2342: * echo Command to turn echoing on
2343: * filter Result of turning off echoing that shouldn't be
2344: * printed.
2345: * echoFlag Flag to turn echoing on at the start
2346: * errFlag Flag to turn error checking on at the start
2347: * hasErrCtl True if shell has error checking control
2348: * newline String literal to represent a newline char
2349: * check Command to turn on error checking if hasErrCtl
2350: * is TRUE or template of command to echo a command
2351: * for which error checking is off if hasErrCtl is
2352: * FALSE.
2353: * ignore Command to turn off error checking if hasErrCtl
2354: * is TRUE or template of command to execute a
2355: * command so as to ignore any errors it returns if
2356: * hasErrCtl is FALSE.
1.1 cgd 2357: */
1.224 rillig 2358: Boolean
1.72 wiz 2359: Job_ParseShell(char *line)
1.1 cgd 2360: {
1.341 rillig 2361: Words wordsList;
2362: char **words;
2363: char **argv;
2364: size_t argc;
2365: char *path;
2366: Shell newShell;
2367: Boolean fullSpec = FALSE;
2368: Shell *sh;
2369:
1.386 rillig 2370: /* XXX: don't use line as an iterator variable */
1.341 rillig 2371: pp_skip_whitespace(&line);
2372:
1.407 rillig 2373: free(shell_freeIt);
1.341 rillig 2374:
2375: memset(&newShell, 0, sizeof newShell);
2376:
2377: /*
2378: * Parse the specification by keyword
2379: */
2380: wordsList = Str_Words(line, TRUE);
2381: words = wordsList.words;
2382: argc = wordsList.len;
2383: path = wordsList.freeIt;
2384: if (words == NULL) {
2385: Error("Unterminated quoted string [%s]", line);
1.244 rillig 2386: return FALSE;
2387: }
1.407 rillig 2388: shell_freeIt = path;
1.1 cgd 2389:
1.341 rillig 2390: for (path = NULL, argv = words; argc != 0; argc--, argv++) {
2391: char *arg = *argv;
2392: if (strncmp(arg, "path=", 5) == 0) {
2393: path = arg + 5;
2394: } else if (strncmp(arg, "name=", 5) == 0) {
2395: newShell.name = arg + 5;
2396: } else {
2397: if (strncmp(arg, "quiet=", 6) == 0) {
2398: newShell.echoOff = arg + 6;
2399: } else if (strncmp(arg, "echo=", 5) == 0) {
2400: newShell.echoOn = arg + 5;
2401: } else if (strncmp(arg, "filter=", 7) == 0) {
2402: newShell.noPrint = arg + 7;
2403: newShell.noPrintLen = strlen(newShell.noPrint);
2404: } else if (strncmp(arg, "echoFlag=", 9) == 0) {
1.366 rillig 2405: newShell.echoFlag = arg + 9;
1.341 rillig 2406: } else if (strncmp(arg, "errFlag=", 8) == 0) {
1.375 rillig 2407: newShell.errFlag = arg + 8;
1.341 rillig 2408: } else if (strncmp(arg, "hasErrCtl=", 10) == 0) {
2409: char c = arg[10];
2410: newShell.hasErrCtl = c == 'Y' || c == 'y' ||
2411: c == 'T' || c == 't';
2412: } else if (strncmp(arg, "newline=", 8) == 0) {
2413: newShell.newline = arg + 8;
2414: } else if (strncmp(arg, "check=", 6) == 0) {
1.359 rillig 2415: /* Before 2020-12-10, these two variables
2416: * had been a single variable. */
1.358 rillig 2417: newShell.errOn = arg + 6;
1.364 rillig 2418: newShell.echoTmpl = arg + 6;
1.341 rillig 2419: } else if (strncmp(arg, "ignore=", 7) == 0) {
1.359 rillig 2420: /* Before 2020-12-10, these two variables
2421: * had been a single variable. */
2422: newShell.errOff = arg + 7;
1.364 rillig 2423: newShell.runIgnTmpl = arg + 7;
1.341 rillig 2424: } else if (strncmp(arg, "errout=", 7) == 0) {
1.364 rillig 2425: newShell.runChkTmpl = arg + 7;
1.341 rillig 2426: } else if (strncmp(arg, "comment=", 8) == 0) {
2427: newShell.commentChar = arg[8];
2428: } else {
2429: Parse_Error(PARSE_FATAL,
2430: "Unknown keyword \"%s\"", arg);
2431: free(words);
2432: return FALSE;
2433: }
2434: fullSpec = TRUE;
2435: }
1.1 cgd 2436: }
1.341 rillig 2437:
1.12 christos 2438: if (path == NULL) {
1.341 rillig 2439: /*
2440: * If no path was given, the user wants one of the
2441: * pre-defined shells, yes? So we find the one s/he wants
2442: * with the help of FindShellByName and set things up the
2443: * right way. shellPath will be set up by Shell_Init.
2444: */
2445: if (newShell.name == NULL) {
2446: Parse_Error(PARSE_FATAL,
2447: "Neither path nor name specified");
2448: free(words);
2449: return FALSE;
2450: } else {
2451: if ((sh = FindShellByName(newShell.name)) == NULL) {
2452: Parse_Error(PARSE_WARNING,
2453: "%s: No matching shell", newShell.name);
2454: free(words);
2455: return FALSE;
2456: }
1.355 rillig 2457: shell = sh;
1.341 rillig 2458: shellName = newShell.name;
2459: if (shellPath != NULL) {
2460: /*
2461: * Shell_Init has already been called!
2462: * Do it again.
2463: */
2464: free(UNCONST(shellPath));
2465: shellPath = NULL;
2466: Shell_Init();
2467: }
2468: }
1.1 cgd 2469: } else {
1.341 rillig 2470: /*
2471: * The user provided a path. If s/he gave nothing else
2472: * (fullSpec is FALSE), try and find a matching shell in the
2473: * ones we know of. Else we just take the specification at
2474: * its word and copy it to a new location. In either case,
2475: * we need to record the path the user gave for the shell.
2476: */
2477: shellPath = path;
2478: path = strrchr(path, '/');
2479: if (path == NULL) {
2480: path = UNCONST(shellPath);
2481: } else {
2482: path++;
2483: }
2484: if (newShell.name != NULL) {
2485: shellName = newShell.name;
2486: } else {
2487: shellName = path;
2488: }
2489: if (!fullSpec) {
2490: if ((sh = FindShellByName(shellName)) == NULL) {
2491: Parse_Error(PARSE_WARNING,
2492: "%s: No matching shell", shellName);
2493: free(words);
2494: return FALSE;
2495: }
1.355 rillig 2496: shell = sh;
1.341 rillig 2497: } else {
1.355 rillig 2498: shell = bmake_malloc(sizeof *shell);
2499: *shell = newShell;
1.341 rillig 2500: }
2501: /* this will take care of shellErrFlag */
2502: Shell_Init();
1.1 cgd 2503: }
1.341 rillig 2504:
1.396 rillig 2505: if (shell->echoOn != NULL && shell->echoOff != NULL)
1.355 rillig 2506: shell->hasEchoCtl = TRUE;
1.1 cgd 2507:
1.355 rillig 2508: if (!shell->hasErrCtl) {
1.364 rillig 2509: if (shell->echoTmpl == NULL)
2510: shell->echoTmpl = "";
2511: if (shell->runIgnTmpl == NULL)
2512: shell->runIgnTmpl = "%s\n";
1.1 cgd 2513: }
1.16 christos 2514:
1.341 rillig 2515: /*
2516: * Do not free up the words themselves, since they might be in use
2517: * by the shell specification.
2518: */
2519: free(words);
2520: return TRUE;
1.1 cgd 2521: }
2522:
1.341 rillig 2523: /*
2524: * Handle the receipt of an interrupt.
1.243 rillig 2525: *
2526: * All children are killed. Another job will be started if the .INTERRUPT
2527: * target is defined.
1.1 cgd 2528: *
1.72 wiz 2529: * Input:
2530: * runINTERRUPT Non-zero if commands for the .INTERRUPT target
2531: * should be executed
2532: * signo signal received
1.1 cgd 2533: */
2534: static void
1.396 rillig 2535: JobInterrupt(Boolean runINTERRUPT, int signo)
1.69 pk 2536: {
1.341 rillig 2537: Job *job; /* job descriptor in that element */
2538: GNode *interrupt; /* the node describing the .INTERRUPT target */
2539: sigset_t mask;
2540: GNode *gn;
2541:
2542: aborting = ABORT_INTERRUPT;
2543:
2544: JobSigLock(&mask);
2545:
2546: for (job = job_table; job < job_table_end; job++) {
2547: if (job->status != JOB_ST_RUNNING)
2548: continue;
2549:
2550: gn = job->node;
2551:
2552: JobDeleteTarget(gn);
1.397 rillig 2553: if (job->pid != 0) {
1.341 rillig 2554: DEBUG2(JOB,
2555: "JobInterrupt passing signal %d to child %d.\n",
2556: signo, job->pid);
2557: KILLPG(job->pid, signo);
2558: }
1.12 christos 2559: }
2560:
1.341 rillig 2561: JobSigUnlock(&mask);
1.69 pk 2562:
1.341 rillig 2563: if (runINTERRUPT && !opts.touchFlag) {
2564: interrupt = Targ_FindNode(".INTERRUPT");
2565: if (interrupt != NULL) {
2566: opts.ignoreErrors = FALSE;
2567: JobRun(interrupt);
2568: }
1.1 cgd 2569: }
1.341 rillig 2570: Trace_Log(MAKEINTR, NULL);
1.368 rillig 2571: exit(signo); /* XXX: why signo? */
1.1 cgd 2572: }
2573:
1.341 rillig 2574: /*
2575: * Do the final processing, i.e. run the commands attached to the .END target.
1.1 cgd 2576: *
1.341 rillig 2577: * Return the number of errors reported.
2578: */
1.1 cgd 2579: int
1.72 wiz 2580: Job_Finish(void)
1.1 cgd 2581: {
1.341 rillig 2582: GNode *endNode = Targ_GetEndNode();
2583: if (!Lst_IsEmpty(&endNode->commands) ||
2584: !Lst_IsEmpty(&endNode->children)) {
2585: if (job_errors != 0) {
2586: Error("Errors reported so .END ignored");
2587: } else {
2588: JobRun(endNode);
2589: }
1.1 cgd 2590: }
1.341 rillig 2591: return job_errors;
1.22 christos 2592: }
2593:
1.243 rillig 2594: /* Clean up any memory used by the jobs module. */
1.22 christos 2595: void
1.72 wiz 2596: Job_End(void)
1.22 christos 2597: {
1.30 mycroft 2598: #ifdef CLEANUP
1.407 rillig 2599: free(shell_freeIt);
1.30 mycroft 2600: #endif
1.1 cgd 2601: }
2602:
1.341 rillig 2603: /*
2604: * Waits for all running jobs to finish and returns.
2605: * Sets 'aborting' to ABORT_WAIT to prevent other jobs from starting.
2606: */
1.1 cgd 2607: void
1.72 wiz 2608: Job_Wait(void)
1.1 cgd 2609: {
1.341 rillig 2610: aborting = ABORT_WAIT;
2611: while (jobTokensRunning != 0) {
2612: Job_CatchOutput();
2613: }
2614: aborting = ABORT_NONE;
1.1 cgd 2615: }
2616:
1.341 rillig 2617: /*
2618: * Abort all currently running jobs without handling output or anything.
1.243 rillig 2619: * This function is to be called only in the event of a major error.
2620: * Most definitely NOT to be called from JobInterrupt.
1.1 cgd 2621: *
1.341 rillig 2622: * All children are killed, not just the firstborn.
2623: */
1.1 cgd 2624: void
1.72 wiz 2625: Job_AbortAll(void)
1.1 cgd 2626: {
1.341 rillig 2627: Job *job; /* the job descriptor in that element */
2628: int foo;
1.16 christos 2629:
1.341 rillig 2630: aborting = ABORT_ERROR;
1.16 christos 2631:
1.341 rillig 2632: if (jobTokensRunning != 0) {
2633: for (job = job_table; job < job_table_end; job++) {
2634: if (job->status != JOB_ST_RUNNING)
2635: continue;
2636: /*
2637: * kill the child process with increasingly drastic
2638: * signals to make darn sure it's dead.
2639: */
2640: KILLPG(job->pid, SIGINT);
2641: KILLPG(job->pid, SIGKILL);
2642: }
1.1 cgd 2643: }
1.16 christos 2644:
1.341 rillig 2645: /*
2646: * Catch as many children as want to report in at first, then give up
2647: */
2648: while (waitpid((pid_t)-1, &foo, WNOHANG) > 0)
2649: continue;
1.12 christos 2650: }
2651:
1.341 rillig 2652: /*
2653: * Tries to restart stopped jobs if there are slots available.
2654: * Called in process context in response to a SIGCONT.
2655: */
1.12 christos 2656: static void
1.72 wiz 2657: JobRestartJobs(void)
1.12 christos 2658: {
1.341 rillig 2659: Job *job;
1.69 pk 2660:
1.341 rillig 2661: for (job = job_table; job < job_table_end; job++) {
2662: if (job->status == JOB_ST_RUNNING &&
2663: (make_suspended || job->suspended)) {
2664: DEBUG1(JOB, "Restarting stopped job pid %d.\n",
2665: job->pid);
2666: if (job->suspended) {
2667: (void)printf("*** [%s] Continued\n",
2668: job->node->name);
2669: (void)fflush(stdout);
2670: }
2671: job->suspended = FALSE;
2672: if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) {
2673: debug_printf("Failed to send SIGCONT to %d\n",
2674: job->pid);
2675: }
2676: }
2677: if (job->status == JOB_ST_FINISHED) {
2678: /*
2679: * Job exit deferred after calling waitpid() in a
2680: * signal handler
2681: */
2682: JobFinish(job, job->exit_status);
2683: }
2684: }
2685: make_suspended = FALSE;
1.1 cgd 2686: }
1.35 christos 2687:
2688: static void
1.72 wiz 2689: watchfd(Job *job)
1.35 christos 2690: {
1.341 rillig 2691: if (job->inPollfd != NULL)
2692: Punt("Watching watched job");
1.35 christos 2693:
1.408 rillig 2694: fds[fdsLen].fd = job->inPipe;
2695: fds[fdsLen].events = POLLIN;
2696: jobByFdIndex[fdsLen] = job;
2697: job->inPollfd = &fds[fdsLen];
2698: fdsLen++;
1.341 rillig 2699: #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
2700: if (useMeta) {
1.408 rillig 2701: fds[fdsLen].fd = meta_job_fd(job);
2702: fds[fdsLen].events = fds[fdsLen].fd == -1 ? 0 : POLLIN;
2703: jobByFdIndex[fdsLen] = job;
2704: fdsLen++;
1.341 rillig 2705: }
1.196 riastrad 2706: #endif
1.35 christos 2707: }
2708:
2709: static void
1.72 wiz 2710: clearfd(Job *job)
1.35 christos 2711: {
1.341 rillig 2712: size_t i;
2713: if (job->inPollfd == NULL)
2714: Punt("Unwatching unwatched job");
2715: i = (size_t)(job->inPollfd - fds);
1.408 rillig 2716: fdsLen--;
1.197 sjg 2717: #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
1.341 rillig 2718: if (useMeta) {
2719: /*
2720: * Sanity check: there should be two fds per job, so the job's
2721: * pollfd number should be even.
2722: */
2723: assert(nfds_per_job() == 2);
1.397 rillig 2724: if (i % 2 != 0)
1.341 rillig 2725: Punt("odd-numbered fd with meta");
1.408 rillig 2726: fdsLen--;
1.341 rillig 2727: }
2728: #endif
1.196 riastrad 2729: /*
1.341 rillig 2730: * Move last job in table into hole made by dead job.
1.196 riastrad 2731: */
1.408 rillig 2732: if (fdsLen != i) {
2733: fds[i] = fds[fdsLen];
2734: jobByFdIndex[i] = jobByFdIndex[fdsLen];
2735: jobByFdIndex[i]->inPollfd = &fds[i];
1.341 rillig 2736: #if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
2737: if (useMeta) {
1.408 rillig 2738: fds[i + 1] = fds[fdsLen + 1];
2739: jobByFdIndex[i + 1] = jobByFdIndex[fdsLen + 1];
1.341 rillig 2740: }
1.196 riastrad 2741: #endif
2742: }
1.341 rillig 2743: job->inPollfd = NULL;
1.35 christos 2744: }
2745:
1.396 rillig 2746: static Boolean
1.72 wiz 2747: readyfd(Job *job)
1.35 christos 2748: {
1.341 rillig 2749: if (job->inPollfd == NULL)
2750: Punt("Polling unwatched job");
2751: return (job->inPollfd->revents & POLLIN) != 0;
1.35 christos 2752: }
1.40 sommerfe 2753:
1.391 rillig 2754: /*
2755: * Put a token (back) into the job pipe.
2756: * This allows a make process to start a build job.
2757: */
1.40 sommerfe 2758: static void
1.72 wiz 2759: JobTokenAdd(void)
1.40 sommerfe 2760: {
1.341 rillig 2761: char tok = JOB_TOKENS[aborting], tok1;
1.101 dsl 2762:
1.341 rillig 2763: /* If we are depositing an error token flush everything else */
2764: while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1)
2765: continue;
2766:
2767: DEBUG3(JOB, "(%d) aborting %d, deposit token %c\n",
2768: getpid(), aborting, JOB_TOKENS[aborting]);
2769: while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
2770: continue;
1.40 sommerfe 2771: }
2772:
1.243 rillig 2773: /* Prep the job token pipe in the root make process. */
1.72 wiz 2774: void
1.122 dsl 2775: Job_ServerStart(int max_tokens, int jp_0, int jp_1)
1.40 sommerfe 2776: {
1.341 rillig 2777: int i;
2778: char jobarg[64];
1.201 rillig 2779:
1.341 rillig 2780: if (jp_0 >= 0 && jp_1 >= 0) {
2781: /* Pipe passed in from parent */
2782: tokenWaitJob.inPipe = jp_0;
2783: tokenWaitJob.outPipe = jp_1;
2784: (void)fcntl(jp_0, F_SETFD, FD_CLOEXEC);
2785: (void)fcntl(jp_1, F_SETFD, FD_CLOEXEC);
2786: return;
2787: }
1.100 dsl 2788:
1.341 rillig 2789: JobCreatePipe(&tokenWaitJob, 15);
1.40 sommerfe 2790:
1.341 rillig 2791: snprintf(jobarg, sizeof jobarg, "%d,%d",
1.122 dsl 2792: tokenWaitJob.inPipe, tokenWaitJob.outPipe);
1.40 sommerfe 2793:
1.341 rillig 2794: Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
2795: Var_Append(MAKEFLAGS, jobarg, VAR_GLOBAL);
1.101 dsl 2796:
1.341 rillig 2797: /*
2798: * Preload the job pipe with one token per job, save the one
2799: * "extra" token for the primary job.
2800: *
2801: * XXX should clip maxJobs against PIPE_BUF -- if max_tokens is
2802: * larger than the write buffer size of the pipe, we will
2803: * deadlock here.
2804: */
2805: for (i = 1; i < max_tokens; i++)
2806: JobTokenAdd();
1.40 sommerfe 2807: }
2808:
1.243 rillig 2809: /* Return a withdrawn token to the pool. */
1.40 sommerfe 2810: void
1.72 wiz 2811: Job_TokenReturn(void)
1.40 sommerfe 2812: {
1.341 rillig 2813: jobTokensRunning--;
2814: if (jobTokensRunning < 0)
2815: Punt("token botch");
1.396 rillig 2816: if (jobTokensRunning != 0 || JOB_TOKENS[aborting] != '+')
1.341 rillig 2817: JobTokenAdd();
1.40 sommerfe 2818: }
2819:
1.341 rillig 2820: /*
2821: * Attempt to withdraw a token from the pool.
1.40 sommerfe 2822: *
1.243 rillig 2823: * If pool is empty, set wantToken so that we wake up when a token is
2824: * released.
1.40 sommerfe 2825: *
1.243 rillig 2826: * Returns TRUE if a token was withdrawn, and FALSE if the pool is currently
1.341 rillig 2827: * empty.
2828: */
1.40 sommerfe 2829: Boolean
1.72 wiz 2830: Job_TokenWithdraw(void)
1.40 sommerfe 2831: {
1.341 rillig 2832: char tok, tok1;
2833: ssize_t count;
1.40 sommerfe 2834:
1.341 rillig 2835: wantToken = 0;
2836: DEBUG3(JOB, "Job_TokenWithdraw(%d): aborting %d, running %d\n",
2837: getpid(), aborting, jobTokensRunning);
1.60 enami 2838:
1.341 rillig 2839: if (aborting != ABORT_NONE || (jobTokensRunning >= opts.maxJobs))
2840: return FALSE;
1.40 sommerfe 2841:
1.341 rillig 2842: count = read(tokenWaitJob.inPipe, &tok, 1);
2843: if (count == 0)
2844: Fatal("eof on job pipe!");
2845: if (count < 0 && jobTokensRunning != 0) {
2846: if (errno != EAGAIN) {
2847: Fatal("job pipe read: %s", strerror(errno));
2848: }
2849: DEBUG1(JOB, "(%d) blocked for token\n", getpid());
1.393 sjg 2850: wantToken = 1;
1.341 rillig 2851: return FALSE;
1.40 sommerfe 2852: }
1.102 dsl 2853:
1.341 rillig 2854: if (count == 1 && tok != '+') {
2855: /* make being aborted - remove any other job tokens */
2856: DEBUG2(JOB, "(%d) aborted by token %c\n", getpid(), tok);
2857: while (read(tokenWaitJob.inPipe, &tok1, 1) == 1)
2858: continue;
2859: /* And put the stopper back */
2860: while (write(tokenWaitJob.outPipe, &tok, 1) == -1 &&
2861: errno == EAGAIN)
2862: continue;
2863: if (shouldDieQuietly(NULL, 1))
1.394 sjg 2864: exit(6); /* we aborted */
1.341 rillig 2865: Fatal("A failure has been detected "
2866: "in another branch of the parallel make");
2867: }
2868:
2869: if (count == 1 && jobTokensRunning == 0)
2870: /* We didn't want the token really */
2871: while (write(tokenWaitJob.outPipe, &tok, 1) == -1 &&
2872: errno == EAGAIN)
2873: continue;
1.102 dsl 2874:
1.341 rillig 2875: jobTokensRunning++;
2876: DEBUG1(JOB, "(%d) withdrew token\n", getpid());
2877: return TRUE;
1.41 sommerfe 2878: }
2879:
1.341 rillig 2880: /*
2881: * Run the named target if found. If a filename is specified, then set that
1.243 rillig 2882: * to the sources.
1.172 christos 2883: *
1.341 rillig 2884: * Exits if the target fails.
2885: */
1.172 christos 2886: Boolean
1.341 rillig 2887: Job_RunTarget(const char *target, const char *fname)
2888: {
2889: GNode *gn = Targ_FindNode(target);
2890: if (gn == NULL)
2891: return FALSE;
1.172 christos 2892:
1.341 rillig 2893: if (fname != NULL)
2894: Var_Set(ALLSRC, fname, gn);
1.172 christos 2895:
1.341 rillig 2896: JobRun(gn);
2897: /* XXX: Replace with GNode_IsError(gn) */
2898: if (gn->made == ERROR) {
2899: PrintOnError(gn, "\n\nStop.");
2900: exit(1);
2901: }
2902: return TRUE;
1.172 christos 2903: }
2904:
1.73 gson 2905: #ifdef USE_SELECT
2906: int
2907: emul_poll(struct pollfd *fd, int nfd, int timeout)
2908: {
1.341 rillig 2909: fd_set rfds, wfds;
2910: int i, maxfd, nselect, npoll;
2911: struct timeval tv, *tvp;
2912: long usecs;
1.73 gson 2913:
1.341 rillig 2914: FD_ZERO(&rfds);
2915: FD_ZERO(&wfds);
1.73 gson 2916:
1.341 rillig 2917: maxfd = -1;
2918: for (i = 0; i < nfd; i++) {
2919: fd[i].revents = 0;
1.73 gson 2920:
1.341 rillig 2921: if (fd[i].events & POLLIN)
2922: FD_SET(fd[i].fd, &rfds);
2923:
2924: if (fd[i].events & POLLOUT)
2925: FD_SET(fd[i].fd, &wfds);
2926:
2927: if (fd[i].fd > maxfd)
2928: maxfd = fd[i].fd;
2929: }
1.201 rillig 2930:
1.341 rillig 2931: if (maxfd >= FD_SETSIZE) {
2932: Punt("Ran out of fd_set slots; "
2933: "recompile with a larger FD_SETSIZE.");
2934: }
1.73 gson 2935:
1.341 rillig 2936: if (timeout < 0) {
2937: tvp = NULL;
2938: } else {
2939: usecs = timeout * 1000;
2940: tv.tv_sec = usecs / 1000000;
2941: tv.tv_usec = usecs % 1000000;
2942: tvp = &tv;
2943: }
1.73 gson 2944:
1.341 rillig 2945: nselect = select(maxfd + 1, &rfds, &wfds, NULL, tvp);
1.73 gson 2946:
1.341 rillig 2947: if (nselect <= 0)
2948: return nselect;
1.73 gson 2949:
1.341 rillig 2950: npoll = 0;
2951: for (i = 0; i < nfd; i++) {
2952: if (FD_ISSET(fd[i].fd, &rfds))
2953: fd[i].revents |= POLLIN;
1.73 gson 2954:
1.341 rillig 2955: if (FD_ISSET(fd[i].fd, &wfds))
2956: fd[i].revents |= POLLOUT;
1.73 gson 2957:
1.341 rillig 2958: if (fd[i].revents)
2959: npoll++;
2960: }
1.73 gson 2961:
1.341 rillig 2962: return npoll;
1.73 gson 2963: }
2964: #endif /* USE_SELECT */
CVSweb <webmaster@jp.NetBSD.org>