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