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