job.c revision 144665
1254721Semaste/*- 2254721Semaste * Copyright (c) 1988, 1989, 1990, 1993 3254721Semaste * The Regents of the University of California. All rights reserved. 4254721Semaste * Copyright (c) 1988, 1989 by Adam de Boor 5254721Semaste * Copyright (c) 1989 by Berkeley Softworks 6254721Semaste * All rights reserved. 7254721Semaste * 8254721Semaste * This code is derived from software contributed to Berkeley by 9254721Semaste * Adam de Boor. 10254721Semaste * 11254721Semaste * Redistribution and use in source and binary forms, with or without 12254721Semaste * modification, are permitted provided that the following conditions 13254721Semaste * are met: 14254721Semaste * 1. Redistributions of source code must retain the above copyright 15254721Semaste * notice, this list of conditions and the following disclaimer. 16254721Semaste * 2. Redistributions in binary form must reproduce the above copyright 17254721Semaste * notice, this list of conditions and the following disclaimer in the 18254721Semaste * documentation and/or other materials provided with the distribution. 19254721Semaste * 3. All advertising materials mentioning features or use of this software 20254721Semaste * must display the following acknowledgement: 21269024Semaste * This product includes software developed by the University of 22254721Semaste * California, Berkeley and its contributors. 23254721Semaste * 4. Neither the name of the University nor the names of its contributors 24254721Semaste * may be used to endorse or promote products derived from this software 25254721Semaste * without specific prior written permission. 26254721Semaste * 27254721Semaste * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28254721Semaste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29254721Semaste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30254721Semaste * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31254721Semaste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32254721Semaste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33254721Semaste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34254721Semaste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35254721Semaste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36254721Semaste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37254721Semaste * SUCH DAMAGE. 38254721Semaste * 39254721Semaste * @(#)job.c 8.2 (Berkeley) 3/19/94 40254721Semaste */ 41254721Semaste 42254721Semaste#include <sys/cdefs.h> 43254721Semaste__FBSDID("$FreeBSD: head/usr.bin/make/job.c 144665 2005-04-05 12:33:54Z harti $"); 44254721Semaste 45254721Semaste#ifndef OLD_JOKE 46254721Semaste#define OLD_JOKE 0 47254721Semaste#endif /* OLD_JOKE */ 48254721Semaste 49254721Semaste/*- 50254721Semaste * job.c -- 51254721Semaste * handle the creation etc. of our child processes. 52254721Semaste * 53254721Semaste * Interface: 54254721Semaste * Job_Make Start the creation of the given target. 55254721Semaste * 56254721Semaste * Job_CatchChildren 57254721Semaste * Check for and handle the termination of any children. 58254721Semaste * This must be called reasonably frequently to keep the 59254721Semaste * whole make going at a decent clip, since job table 60254721Semaste * entries aren't removed until their process is caught 61254721Semaste * this way. Its single argument is TRUE if the function 62254721Semaste * should block waiting for a child to terminate. 63254721Semaste * 64254721Semaste * Job_CatchOutput Print any output our children have produced. Should 65269024Semaste * also be called fairly frequently to keep the user 66254721Semaste * informed of what's going on. If no output is waiting, 67254721Semaste * it will block for a time given by the SEL_* constants, 68254721Semaste * below, or until output is ready. 69254721Semaste * 70254721Semaste * Job_Init Called to intialize this module. in addition, any 71254721Semaste * commands attached to the .BEGIN target are executed 72269024Semaste * before this function returns. Hence, the makefile must 73254721Semaste * have been parsed before this function is called. 74254721Semaste * 75254721Semaste * Job_Full Return TRUE if the job table is filled. 76254721Semaste * 77254721Semaste * Job_Empty Return TRUE if the job table is completely empty. 78254721Semaste * 79254721Semaste * Job_ParseShell Given the line following a .SHELL target, parse the 80254721Semaste * line as a shell specification. Returns FAILURE if the 81254721Semaste * spec was incorrect. 82254721Semaste * 83254721Semaste * Job_Finish Perform any final processing which needs doing. This 84254721Semaste * includes the execution of any commands which have 85254721Semaste * been/were attached to the .END target. It should only 86254721Semaste * be called when the job table is empty. 87254721Semaste * 88254721Semaste * Job_AbortAll Abort all currently running jobs. It doesn't handle 89254721Semaste * output or do anything for the jobs, just kills them. 90254721Semaste * It should only be called in an emergency, as it were. 91254721Semaste * 92254721Semaste * Job_CheckCommands 93254721Semaste * Verify that the commands for a target are ok. Provide 94254721Semaste * them if necessary and possible. 95254721Semaste * 96254721Semaste * Job_Touch Update a target without really updating it. 97254721Semaste * 98254721Semaste * Job_Wait Wait for all currently-running jobs to finish. 99254721Semaste */ 100254721Semaste 101254721Semaste#include <sys/queue.h> 102254721Semaste#include <sys/types.h> 103254721Semaste#include <sys/select.h> 104254721Semaste#include <sys/stat.h> 105254721Semaste#ifdef USE_KQUEUE 106254721Semaste#include <sys/event.h> 107254721Semaste#endif 108254721Semaste#include <sys/wait.h> 109254721Semaste#include <ctype.h> 110254721Semaste#include <errno.h> 111254721Semaste#include <fcntl.h> 112254721Semaste#include <inttypes.h> 113254721Semaste#include <string.h> 114254721Semaste#include <signal.h> 115254721Semaste#include <stdlib.h> 116254721Semaste#include <unistd.h> 117254721Semaste#include <utime.h> 118254721Semaste 119254721Semaste#include "arch.h" 120254721Semaste#include "buf.h" 121254721Semaste#include "compat.h" 122254721Semaste#include "dir.h" 123254721Semaste#include "globals.h" 124254721Semaste#include "GNode.h" 125254721Semaste#include "job.h" 126254721Semaste#include "make.h" 127254721Semaste#include "parse.h" 128254721Semaste#include "pathnames.h" 129254721Semaste#include "str.h" 130254721Semaste#include "targ.h" 131254721Semaste#include "util.h" 132254721Semaste#include "var.h" 133254721Semaste 134254721Semaste/* 135254721Semaste * Job Table definitions. 136254721Semaste * 137254721Semaste * The job "table" is kept as a linked Lst in 'jobs', with the number of 138269024Semaste * active jobs maintained in the 'nJobs' variable. At no time will this 139269024Semaste * exceed the value of 'maxJobs', initialized by the Job_Init function. 140269024Semaste * 141269024Semaste * When a job is finished, the Make_Update function is called on each of the 142269024Semaste * parents of the node which was just remade. This takes care of the upward 143269024Semaste * traversal of the dependency graph. 144269024Semaste */ 145269024Semaste#define JOB_BUFSIZE 1024 146269024Semastetypedef struct Job { 147254721Semaste pid_t pid; /* The child's process ID */ 148254721Semaste 149254721Semaste struct GNode *node; /* The target the child is making */ 150254721Semaste 151254721Semaste /* 152254721Semaste * A LstNode for the first command to be saved after the job completes. 153254721Semaste * This is NULL if there was no "..." in the job's commands. 154254721Semaste */ 155254721Semaste LstNode *tailCmds; 156254721Semaste 157254721Semaste /* 158254721Semaste * An FILE* for writing out the commands. This is only 159254721Semaste * used before the job is actually started. 160254721Semaste */ 161254721Semaste FILE *cmdFILE; 162254721Semaste 163254721Semaste /* 164254721Semaste * A word of flags which determine how the module handles errors, 165254721Semaste * echoing, etc. for the job 166254721Semaste */ 167254721Semaste short flags; /* Flags to control treatment of job */ 168254721Semaste#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ 169254721Semaste#define JOB_SILENT 0x002 /* no output */ 170254721Semaste#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally 171254721Semaste * if we can't export it and maxLocal is 0 */ 172254721Semaste#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing 173254721Semaste * commands */ 174254721Semaste#define JOB_FIRST 0x020 /* Job is first job for the node */ 175254721Semaste#define JOB_RESTART 0x080 /* Job needs to be completely restarted */ 176254721Semaste#define JOB_RESUME 0x100 /* Job needs to be resumed b/c it stopped, 177254721Semaste * for some reason */ 178254721Semaste#define JOB_CONTINUING 0x200 /* We are in the process of resuming this job. 179254721Semaste * Used to avoid infinite recursion between 180254721Semaste * JobFinish and JobRestart */ 181254721Semaste 182254721Semaste /* union for handling shell's output */ 183254721Semaste union { 184254721Semaste /* 185254721Semaste * This part is used when usePipes is true. 186254721Semaste * The output is being caught via a pipe and the descriptors 187254721Semaste * of our pipe, an array in which output is line buffered and 188254721Semaste * the current position in that buffer are all maintained for 189254721Semaste * each job. 190254721Semaste */ 191254721Semaste struct { 192254721Semaste /* 193254721Semaste * Input side of pipe associated with 194254721Semaste * job's output channel 195254721Semaste */ 196254721Semaste int op_inPipe; 197254721Semaste 198254721Semaste /* 199254721Semaste * Output side of pipe associated with job's 200254721Semaste * output channel 201254721Semaste */ 202254721Semaste int op_outPipe; 203254721Semaste 204254721Semaste /* 205254721Semaste * Buffer for storing the output of the 206254721Semaste * job, line by line 207254721Semaste */ 208254721Semaste char op_outBuf[JOB_BUFSIZE + 1]; 209254721Semaste 210254721Semaste /* Current position in op_outBuf */ 211254721Semaste int op_curPos; 212254721Semaste } o_pipe; 213254721Semaste 214254721Semaste /* 215254721Semaste * If usePipes is false the output is routed to a temporary 216254721Semaste * file and all that is kept is the name of the file and the 217254721Semaste * descriptor open to the file. 218254721Semaste */ 219254721Semaste struct { 220254721Semaste /* Name of file to which shell output was rerouted */ 221254721Semaste char of_outFile[sizeof(TMPPAT)]; 222254721Semaste 223254721Semaste /* 224254721Semaste * Stream open to the output file. Used to funnel all 225254721Semaste * from a single job to one file while still allowing 226254721Semaste * multiple shell invocations 227254721Semaste */ 228254721Semaste int of_outFd; 229254721Semaste } o_file; 230254721Semaste 231254721Semaste } output; /* Data for tracking a shell's output */ 232254721Semaste 233254721Semaste TAILQ_ENTRY(Job) link; /* list link */ 234254721Semaste} Job; 235254721Semaste 236254721Semaste#define outPipe output.o_pipe.op_outPipe 237254721Semaste#define inPipe output.o_pipe.op_inPipe 238254721Semaste#define outBuf output.o_pipe.op_outBuf 239254721Semaste#define curPos output.o_pipe.op_curPos 240254721Semaste#define outFile output.o_file.of_outFile 241254721Semaste#define outFd output.o_file.of_outFd 242254721Semaste 243254721SemasteTAILQ_HEAD(JobList, Job); 244254721Semaste 245254721Semaste/* 246254721Semaste * Shell Specifications: 247254721Semaste * 248254721Semaste * Some special stuff goes on if a shell doesn't have error control. In such 249254721Semaste * a case, errCheck becomes a printf template for echoing the command, 250254721Semaste * should echoing be on and ignErr becomes another printf template for 251254721Semaste * executing the command while ignoring the return status. If either of these 252254721Semaste * strings is empty when hasErrCtl is FALSE, the command will be executed 253254721Semaste * anyway as is and if it causes an error, so be it. 254254721Semaste */ 255254721Semaste#define DEF_SHELL_STRUCT(TAG, CONST) \ 256254721Semastestruct TAG { \ 257254721Semaste /* \ 258254721Semaste * the name of the shell. For Bourne and C shells, this is used \ 259254721Semaste * only to find the shell description when used as the single \ 260254721Semaste * source of a .SHELL target. For user-defined shells, this is \ 261254721Semaste * the full path of the shell. \ 262254721Semaste */ \ 263254721Semaste CONST char *name; \ 264254721Semaste \ 265254721Semaste /* True if both echoOff and echoOn defined */ \ 266254721Semaste Boolean hasEchoCtl; \ 267254721Semaste \ 268254721Semaste CONST char *echoOff; /* command to turn off echo */ \ 269254721Semaste CONST char *echoOn; /* command to turn it back on */\ 270254721Semaste \ 271254721Semaste /* \ 272254721Semaste * What the shell prints, and its length, when given the \ 273254721Semaste * echo-off command. This line will not be printed when \ 274254721Semaste * received from the shell. This is usually the command which \ 275254721Semaste * was executed to turn off echoing \ 276254721Semaste */ \ 277254721Semaste CONST char *noPrint; \ 278254721Semaste int noPLen; /* length of noPrint command */ \ 279254721Semaste \ 280254721Semaste /* set if can control error checking for individual commands */ \ 281254721Semaste Boolean hasErrCtl; \ 282254721Semaste \ 283254721Semaste /* string to turn error checking on */ \ 284254721Semaste CONST char *errCheck; \ 285254721Semaste \ 286254721Semaste /* string to turn off error checking */ \ 287254721Semaste CONST char *ignErr; \ 288254721Semaste \ 289254721Semaste CONST char *echo; /* command line flag: echo commands */ \ 290254721Semaste CONST char *exit; /* command line flag: exit on error */ \ 291254721Semaste} 292254721Semaste 293254721SemasteDEF_SHELL_STRUCT(Shell,); 294254721SemasteDEF_SHELL_STRUCT(CShell, const); 295254721Semaste 296254721Semaste/* 297263363Semaste * error handling variables 298263363Semaste */ 299263363Semastestatic int errors = 0; /* number of errors reported */ 300254721Semastestatic int aborting = 0; /* why is the make aborting? */ 301254721Semaste#define ABORT_ERROR 1 /* Because of an error */ 302254721Semaste#define ABORT_INTERRUPT 2 /* Because it was interrupted */ 303263363Semaste#define ABORT_WAIT 3 /* Waiting for jobs to finish */ 304263363Semaste 305263363Semaste/* 306263363Semaste * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file 307263363Semaste * is a char! So when we go above 127 we turn negative! 308263363Semaste */ 309254721Semaste#define FILENO(a) ((unsigned)fileno(a)) 310254721Semaste 311254721Semaste/* 312254721Semaste * post-make command processing. The node postCommands is really just the 313254721Semaste * .END target but we keep it around to avoid having to search for it 314254721Semaste * all the time. 315254721Semaste */ 316254721Semastestatic GNode *postCommands; 317254721Semaste 318254721Semaste/* 319254721Semaste * The number of commands actually printed for a target. Should this 320254721Semaste * number be 0, no shell will be executed. 321254721Semaste */ 322254721Semastestatic int numCommands; 323254721Semaste 324254721Semaste/* 325254721Semaste * Return values from JobStart. 326254721Semaste */ 327254721Semaste#define JOB_RUNNING 0 /* Job is running */ 328254721Semaste#define JOB_ERROR 1 /* Error in starting the job */ 329254721Semaste#define JOB_FINISHED 2 /* The job is already finished */ 330254721Semaste#define JOB_STOPPED 3 /* The job is stopped */ 331254721Semaste 332254721Semaste/* 333254721Semaste * Descriptions for various shells. 334254721Semaste */ 335254721Semastestatic const struct CShell shells[] = { 336254721Semaste /* 337254721Semaste * CSH description. The csh can do echo control by playing 338254721Semaste * with the setting of the 'echo' shell variable. Sadly, 339254721Semaste * however, it is unable to do error control nicely. 340254721Semaste */ 341254721Semaste { 342254721Semaste "csh", 343254721Semaste TRUE, "unset verbose", "set verbose", "unset verbose", 13, 344254721Semaste FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"", 345254721Semaste "v", "e", 346254721Semaste }, 347254721Semaste /* 348254721Semaste * SH description. Echo control is also possible and, under 349254721Semaste * sun UNIX anyway, one can even control error checking. 350254721Semaste */ 351254721Semaste { 352254721Semaste "sh", 353254721Semaste TRUE, "set -", "set -v", "set -", 5, 354254721Semaste TRUE, "set -e", "set +e", 355254721Semaste#ifdef OLDBOURNESHELL 356254721Semaste FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n", 357254721Semaste#endif 358254721Semaste "v", "e", 359254721Semaste }, 360254721Semaste /* 361254721Semaste * KSH description. The Korn shell has a superset of 362254721Semaste * the Bourne shell's functionality. 363254721Semaste */ 364254721Semaste { 365254721Semaste "ksh", 366254721Semaste TRUE, "set -", "set -v", "set -", 5, 367254721Semaste TRUE, "set -e", "set +e", 368254721Semaste "v", "e", 369254721Semaste }, 370254721Semaste}; 371254721Semaste 372254721Semaste/* 373254721Semaste * This is the shell to which we pass all commands in the Makefile. 374254721Semaste * It is set by the Job_ParseShell function. 375254721Semaste */ 376254721Semastestatic struct Shell *commandShell = NULL; 377254721Semastechar *shellPath = NULL; /* full pathname of executable image */ 378254721Semastechar *shellName = NULL; /* last component of shell */ 379254721Semaste 380254721Semasteint maxJobs; /* The most children we can run at once */ 381254721Semastestatic int nJobs; /* The number of children currently running */ 382254721Semaste 383254721Semaste/* The structures that describe them */ 384254721Semastestatic struct JobList jobs = TAILQ_HEAD_INITIALIZER(jobs); 385254721Semaste 386254721Semastestatic Boolean jobFull; /* Flag to tell when the job table is full. It 387254721Semaste * is set TRUE when (1) the total number of 388254721Semaste * running jobs equals the maximum allowed */ 389254721Semaste#ifdef USE_KQUEUE 390254721Semastestatic int kqfd; /* File descriptor obtained by kqueue() */ 391254721Semaste#else 392254721Semastestatic fd_set outputs; /* Set of descriptors of pipes connected to 393254721Semaste * the output channels of children */ 394254721Semaste#endif 395254721Semaste 396254721Semastestatic GNode *lastNode; /* The node for which output was most recently 397254721Semaste * produced. */ 398254721Semastestatic const char *targFmt; /* Format string to use to head output from a 399254721Semaste * job when it's not the most-recent job heard 400254721Semaste * from */ 401254721Semaste 402254721Semaste#define TARG_FMT "--- %s ---\n" /* Default format */ 403254721Semaste#define MESSAGE(fp, gn) \ 404254721Semaste fprintf(fp, targFmt, gn->name); 405254721Semaste 406254721Semaste/* 407254721Semaste * When JobStart attempts to run a job but isn't allowed to 408254721Semaste * or when Job_CatchChildren detects a job that has 409254721Semaste * been stopped somehow, the job is placed on the stoppedJobs queue to be run 410254721Semaste * when the next job finishes. 411254721Semaste * 412254721Semaste * Lst of Job structures describing jobs that were stopped due to 413254721Semaste * concurrency limits or externally 414254721Semaste */ 415254721Semastestatic struct JobList stoppedJobs = TAILQ_HEAD_INITIALIZER(stoppedJobs); 416254721Semaste 417254721Semastestatic int fifoFd; /* Fd of our job fifo */ 418254721Semastestatic char fifoName[] = "/tmp/make_fifo_XXXXXXXXX"; 419254721Semastestatic int fifoMaster; 420254721Semaste 421254721Semastestatic sig_atomic_t interrupted; 422254721Semaste 423254721Semaste 424254721Semaste#if defined(USE_PGRP) && defined(SYSV) 425254721Semaste# define KILL(pid, sig) killpg(-(pid), (sig)) 426254721Semaste#else 427254721Semaste# if defined(USE_PGRP) 428254721Semaste# define KILL(pid, sig) killpg((pid), (sig)) 429254721Semaste# else 430254721Semaste# define KILL(pid, sig) kill((pid), (sig)) 431254721Semaste# endif 432254721Semaste#endif 433254721Semaste 434254721Semaste/* 435254721Semaste * Grmpf... There is no way to set bits of the wait structure 436254721Semaste * anymore with the stupid W*() macros. I liked the union wait 437254721Semaste * stuff much more. So, we devise our own macros... This is 438254721Semaste * really ugly, use dramamine sparingly. You have been warned. 439254721Semaste */ 440254721Semaste#define W_SETMASKED(st, val, fun) \ 441254721Semaste { \ 442254721Semaste int sh = (int)~0; \ 443254721Semaste int mask = fun(sh); \ 444254721Semaste \ 445254721Semaste for (sh = 0; ((mask >> sh) & 1) == 0; sh++) \ 446254721Semaste continue; \ 447254721Semaste *(st) = (*(st) & ~mask) | ((val) << sh); \ 448254721Semaste } 449254721Semaste 450254721Semaste#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG) 451254721Semaste#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) 452254721Semaste 453254721Semastestatic void JobRestart(Job *); 454254721Semastestatic int JobStart(GNode *, int, Job *); 455254721Semastestatic void JobDoOutput(Job *, Boolean); 456254721Semastestatic struct Shell *JobMatchShell(const char *); 457254721Semastestatic void JobInterrupt(int, int); 458254721Semastestatic void JobRestartJobs(void); 459254721Semaste 460254721Semaste/** 461254721Semaste * JobCatchSignal 462254721Semaste * Got a signal. Set global variables and hope that someone will 463254721Semaste * handle it. 464254721Semaste */ 465254721Semastestatic void 466254721SemasteJobCatchSig(int signo) 467254721Semaste{ 468254721Semaste 469254721Semaste interrupted = signo; 470254721Semaste} 471254721Semaste 472254721Semaste/** 473254721Semaste * JobCondPassSig -- 474254721Semaste * Pass a signal to all jobs 475254721Semaste * 476254721Semaste * Side Effects: 477254721Semaste * None, except the job may bite it. 478254721Semaste */ 479254721Semastestatic void 480254721SemasteJobCondPassSig(int signo) 481254721Semaste{ 482254721Semaste Job *job; 483254721Semaste 484254721Semaste TAILQ_FOREACH(job, &jobs, link) { 485254721Semaste DEBUGF(JOB, ("JobCondPassSig passing signal %d to child %jd.\n", 486254721Semaste signo, (intmax_t)job->pid)); 487254721Semaste KILL(job->pid, signo); 488254721Semaste } 489254721Semaste} 490254721Semaste 491254721Semaste/** 492254721Semaste * JobPassSig -- 493254721Semaste * Pass a signal on to all local jobs if 494254721Semaste * USE_PGRP is defined, then die ourselves. 495254721Semaste * 496254721Semaste * Side Effects: 497254721Semaste * We die by the same signal. 498254721Semaste */ 499254721Semastestatic void 500254721SemasteJobPassSig(int signo) 501254721Semaste{ 502254721Semaste sigset_t nmask, omask; 503254721Semaste struct sigaction act; 504254721Semaste 505254721Semaste sigemptyset(&nmask); 506254721Semaste sigaddset(&nmask, signo); 507254721Semaste sigprocmask(SIG_SETMASK, &nmask, &omask); 508254721Semaste 509254721Semaste DEBUGF(JOB, ("JobPassSig(%d) called.\n", signo)); 510254721Semaste JobCondPassSig(signo); 511263367Semaste 512263367Semaste /* 513263367Semaste * Deal with proper cleanup based on the signal received. We only run 514263367Semaste * the .INTERRUPT target if the signal was in fact an interrupt. 515263367Semaste * The other three termination signals are more of a "get out *now*" 516263367Semaste * command. 517263367Semaste */ 518263367Semaste if (signo == SIGINT) { 519263367Semaste JobInterrupt(TRUE, signo); 520263367Semaste } else if (signo == SIGHUP || signo == SIGTERM || signo == SIGQUIT) { 521263367Semaste JobInterrupt(FALSE, signo); 522263367Semaste } 523263367Semaste 524254721Semaste /* 525254721Semaste * Leave gracefully if SIGQUIT, rather than core dumping. 526254721Semaste */ 527254721Semaste if (signo == SIGQUIT) { 528254721Semaste signo = SIGINT; 529254721Semaste } 530254721Semaste 531254721Semaste /* 532254721Semaste * Send ourselves the signal now we've given the message to everyone 533254721Semaste * else. Note we block everything else possible while we're getting 534254721Semaste * the signal. This ensures that all our jobs get continued when we 535254721Semaste * wake up before we take any other signal. 536254721Semaste * XXX this comment seems wrong. 537254721Semaste */ 538263367Semaste act.sa_handler = SIG_DFL; 539263367Semaste sigemptyset(&act.sa_mask); 540263367Semaste act.sa_flags = 0; 541263367Semaste sigaction(signo, &act, NULL); 542263367Semaste 543263367Semaste DEBUGF(JOB, ("JobPassSig passing signal to self, mask = %x.\n", 544263367Semaste ~0 & ~(1 << (signo - 1)))); 545263367Semaste signal(signo, SIG_DFL); 546263367Semaste 547263367Semaste KILL(getpid(), signo); 548263367Semaste 549263367Semaste signo = SIGCONT; 550263367Semaste JobCondPassSig(signo); 551263367Semaste 552263367Semaste sigprocmask(SIG_SETMASK, &omask, NULL); 553263367Semaste sigprocmask(SIG_SETMASK, &omask, NULL); 554263367Semaste act.sa_handler = JobPassSig; 555263367Semaste sigaction(signo, &act, NULL); 556263367Semaste} 557263367Semaste 558254721Semaste/** 559254721Semaste * JobPrintCommand -- 560254721Semaste * Put out another command for the given job. If the command starts 561254721Semaste * with an @ or a - we process it specially. In the former case, 562254721Semaste * so long as the -s and -n flags weren't given to make, we stick 563254721Semaste * a shell-specific echoOff command in the script. In the latter, 564254721Semaste * we ignore errors for the entire job, unless the shell has error 565254721Semaste * control. 566254721Semaste * If the command is just "..." we take all future commands for this 567254721Semaste * job to be commands to be executed once the entire graph has been 568254721Semaste * made and return non-zero to signal that the end of the commands 569254721Semaste * was reached. These commands are later attached to the postCommands 570254721Semaste * node and executed by Job_Finish when all things are done. 571254721Semaste * This function is called from JobStart via LST_FOREACH. 572254721Semaste * 573254721Semaste * Results: 574254721Semaste * Always 0, unless the command was "..." 575254721Semaste * 576254721Semaste * Side Effects: 577254721Semaste * If the command begins with a '-' and the shell has no error control, 578254721Semaste * the JOB_IGNERR flag is set in the job descriptor. 579254721Semaste * If the command is "..." and we're not ignoring such things, 580254721Semaste * tailCmds is set to the successor node of the cmd. 581254721Semaste * numCommands is incremented if the command is actually printed. 582254721Semaste */ 583254721Semastestatic int 584254721SemasteJobPrintCommand(void *cmdp, void *jobp) 585254721Semaste{ 586254721Semaste Boolean noSpecials; /* true if we shouldn't worry about 587254721Semaste * inserting special commands into 588254721Semaste * the input stream. */ 589254721Semaste Boolean shutUp = FALSE; /* true if we put a no echo command 590254721Semaste * into the command file */ 591254721Semaste Boolean errOff = FALSE; /* true if we turned error checking 592254721Semaste * off before printing the command 593254721Semaste * and need to turn it back on */ 594254721Semaste const char *cmdTemplate;/* Template to use when printing the command */ 595254721Semaste char *cmdStart; /* Start of expanded command */ 596254721Semaste LstNode *cmdNode; /* Node for replacing the command */ 597254721Semaste char *cmd = cmdp; 598254721Semaste Job *job = jobp; 599254721Semaste 600254721Semaste noSpecials = (noExecute && !(job->node->type & OP_MAKE)); 601254721Semaste 602254721Semaste if (strcmp(cmd, "...") == 0) { 603254721Semaste job->node->type |= OP_SAVE_CMDS; 604254721Semaste if ((job->flags & JOB_IGNDOTS) == 0) { 605254721Semaste job->tailCmds = 606254721Semaste Lst_Succ(Lst_Member(&job->node->commands, cmd)); 607254721Semaste return (1); 608254721Semaste } 609254721Semaste return (0); 610254721Semaste } 611254721Semaste 612254721Semaste#define DBPRINTF(fmt, arg) \ 613254721Semaste DEBUGF(JOB, (fmt, arg)); \ 614254721Semaste fprintf(job->cmdFILE, fmt, arg); \ 615254721Semaste fflush(job->cmdFILE); 616254721Semaste 617254721Semaste numCommands += 1; 618254721Semaste 619254721Semaste /* 620254721Semaste * For debugging, we replace each command with the result of expanding 621254721Semaste * the variables in the command. 622254721Semaste */ 623254721Semaste cmdNode = Lst_Member(&job->node->commands, cmd); 624254721Semaste 625254721Semaste cmd = Buf_Peel(Var_Subst(NULL, cmd, job->node, FALSE)); 626254721Semaste cmdStart = cmd; 627254721Semaste 628254721Semaste Lst_Replace(cmdNode, cmdStart); 629254721Semaste 630254721Semaste cmdTemplate = "%s\n"; 631254721Semaste 632254721Semaste /* 633254721Semaste * Check for leading @', -' or +'s to control echoing, error checking, 634254721Semaste * and execution on -n. 635254721Semaste */ 636254721Semaste while (*cmd == '@' || *cmd == '-' || *cmd == '+') { 637254721Semaste switch (*cmd) { 638254721Semaste 639254721Semaste case '@': 640254721Semaste shutUp = DEBUG(LOUD) ? FALSE : TRUE; 641254721Semaste break; 642254721Semaste 643254721Semaste case '-': 644254721Semaste errOff = TRUE; 645254721Semaste break; 646254721Semaste 647254721Semaste case '+': 648254721Semaste if (noSpecials) { 649254721Semaste /* 650254721Semaste * We're not actually exececuting anything... 651254721Semaste * but this one needs to be - use compat mode 652254721Semaste * just for it. 653254721Semaste */ 654254721Semaste Compat_RunCommand(cmdp, job->node); 655254721Semaste return (0); 656254721Semaste } 657254721Semaste break; 658254721Semaste } 659254721Semaste cmd++; 660254721Semaste } 661254721Semaste 662254721Semaste while (isspace((unsigned char)*cmd)) 663254721Semaste cmd++; 664254721Semaste 665254721Semaste if (shutUp) { 666254721Semaste if (!(job->flags & JOB_SILENT) && !noSpecials && 667254721Semaste commandShell->hasEchoCtl) { 668254721Semaste DBPRINTF("%s\n", commandShell->echoOff); 669254721Semaste } else { 670254721Semaste shutUp = FALSE; 671254721Semaste } 672254721Semaste } 673254721Semaste 674254721Semaste if (errOff) { 675254721Semaste if (!(job->flags & JOB_IGNERR) && !noSpecials) { 676254721Semaste if (commandShell->hasErrCtl) { 677254721Semaste /* 678254721Semaste * We don't want the error-control commands 679254721Semaste * showing up either, so we turn off echoing 680254721Semaste * while executing them. We could put another 681254721Semaste * field in the shell structure to tell 682254721Semaste * JobDoOutput to look for this string too, 683254721Semaste * but why make it any more complex than 684254721Semaste * it already is? 685254721Semaste */ 686254721Semaste if (!(job->flags & JOB_SILENT) && !shutUp && 687254721Semaste commandShell->hasEchoCtl) { 688254721Semaste DBPRINTF("%s\n", commandShell->echoOff); 689254721Semaste DBPRINTF("%s\n", commandShell->ignErr); 690254721Semaste DBPRINTF("%s\n", commandShell->echoOn); 691254721Semaste } else { 692254721Semaste DBPRINTF("%s\n", commandShell->ignErr); 693254721Semaste } 694254721Semaste } else if (commandShell->ignErr && 695254721Semaste *commandShell->ignErr != '\0') { 696254721Semaste /* 697254721Semaste * The shell has no error control, so we need to 698254721Semaste * be weird to get it to ignore any errors from 699254721Semaste * the command. If echoing is turned on, we turn 700254721Semaste * it off and use the errCheck template to echo 701254721Semaste * the command. Leave echoing off so the user 702254721Semaste * doesn't see the weirdness we go through to 703254721Semaste * ignore errors. Set cmdTemplate to use the 704254721Semaste * weirdness instead of the simple "%s\n" 705254721Semaste * template. 706254721Semaste */ 707254721Semaste if (!(job->flags & JOB_SILENT) && !shutUp && 708254721Semaste commandShell->hasEchoCtl) { 709254721Semaste DBPRINTF("%s\n", commandShell->echoOff); 710254721Semaste DBPRINTF(commandShell->errCheck, cmd); 711254721Semaste shutUp = TRUE; 712254721Semaste } 713254721Semaste cmdTemplate = commandShell->ignErr; 714254721Semaste /* 715254721Semaste * The error ignoration (hee hee) is already 716254721Semaste * taken care of by the ignErr template, so 717254721Semaste * pretend error checking is still on. 718254721Semaste */ 719254721Semaste errOff = FALSE; 720254721Semaste } else { 721254721Semaste errOff = FALSE; 722254721Semaste } 723254721Semaste } else { 724254721Semaste errOff = FALSE; 725254721Semaste } 726254721Semaste } 727254721Semaste 728254721Semaste DBPRINTF(cmdTemplate, cmd); 729254721Semaste 730254721Semaste if (errOff) { 731254721Semaste /* 732254721Semaste * If echoing is already off, there's no point in issuing the 733254721Semaste * echoOff command. Otherwise we issue it and pretend it was on 734254721Semaste * for the whole command... 735254721Semaste */ 736254721Semaste if (!shutUp && !(job->flags & JOB_SILENT) && 737254721Semaste commandShell->hasEchoCtl) { 738254721Semaste DBPRINTF("%s\n", commandShell->echoOff); 739254721Semaste shutUp = TRUE; 740254721Semaste } 741254721Semaste DBPRINTF("%s\n", commandShell->errCheck); 742254721Semaste } 743254721Semaste if (shutUp) { 744254721Semaste DBPRINTF("%s\n", commandShell->echoOn); 745254721Semaste } 746254721Semaste return (0); 747254721Semaste} 748254721Semaste 749254721Semaste/** 750254721Semaste * JobClose -- 751254721Semaste * Called to close both input and output pipes when a job is finished. 752254721Semaste * 753254721Semaste * Side Effects: 754254721Semaste * The file descriptors associated with the job are closed. 755254721Semaste */ 756254721Semastestatic void 757254721SemasteJobClose(Job *job) 758254721Semaste{ 759254721Semaste 760254721Semaste if (usePipes) { 761254721Semaste#if !defined(USE_KQUEUE) 762254721Semaste FD_CLR(job->inPipe, &outputs); 763254721Semaste#endif 764254721Semaste if (job->outPipe != job->inPipe) { 765254721Semaste close(job->outPipe); 766254721Semaste } 767254721Semaste JobDoOutput(job, TRUE); 768254721Semaste close(job->inPipe); 769254721Semaste } else { 770254721Semaste close(job->outFd); 771254721Semaste JobDoOutput(job, TRUE); 772254721Semaste } 773254721Semaste} 774254721Semaste 775254721Semaste/** 776254721Semaste * JobFinish -- 777254721Semaste * Do final processing for the given job including updating 778254721Semaste * parents and starting new jobs as available/necessary. Note 779254721Semaste * that we pay no attention to the JOB_IGNERR flag here. 780254721Semaste * This is because when we're called because of a noexecute flag 781254721Semaste * or something, jstat.w_status is 0 and when called from 782254721Semaste * Job_CatchChildren, the status is zeroed if it s/b ignored. 783254721Semaste * 784254721Semaste * Side Effects: 785254721Semaste * Some nodes may be put on the toBeMade queue. 786254721Semaste * Final commands for the job are placed on postCommands. 787254721Semaste * 788254721Semaste * If we got an error and are aborting (aborting == ABORT_ERROR) and 789254721Semaste * the job list is now empty, we are done for the day. 790254721Semaste * If we recognized an error (errors !=0), we set the aborting flag 791254721Semaste * to ABORT_ERROR so no more jobs will be started. 792254721Semaste */ 793254721Semastestatic void 794254721SemasteJobFinish(Job *job, int *status) 795254721Semaste{ 796254721Semaste Boolean done; 797254721Semaste LstNode *ln; 798254721Semaste 799254721Semaste if ((WIFEXITED(*status) && WEXITSTATUS(*status) != 0 && 800254721Semaste !(job->flags & JOB_IGNERR)) || 801254721Semaste (WIFSIGNALED(*status) && WTERMSIG(*status) != SIGCONT)) { 802254721Semaste /* 803254721Semaste * If it exited non-zero and either we're doing things our 804254721Semaste * way or we're not ignoring errors, the job is finished. 805254721Semaste * Similarly, if the shell died because of a signal 806254721Semaste * the job is also finished. In these cases, finish out the 807254721Semaste * job's output before printing the exit status... 808254721Semaste */ 809254721Semaste JobClose(job); 810254721Semaste if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 811254721Semaste fclose(job->cmdFILE); 812254721Semaste } 813254721Semaste done = TRUE; 814254721Semaste 815254721Semaste } else if (WIFEXITED(*status)) { 816254721Semaste /* 817254721Semaste * Deal with ignored errors in -B mode. We need to print a 818254721Semaste * message telling of the ignored error as well as setting 819254721Semaste * status.w_status to 0 so the next command gets run. To do 820254721Semaste * this, we set done to be TRUE if in -B mode and the job 821254721Semaste * exited non-zero. 822254721Semaste */ 823254721Semaste done = WEXITSTATUS(*status) != 0; 824254721Semaste 825254721Semaste /* 826254721Semaste * Old comment said: "Note we don't want to close down any of 827254721Semaste * the streams until we know we're at the end." But we do. 828254721Semaste * Otherwise when are we going to print the rest of the stuff? 829254721Semaste */ 830254721Semaste JobClose(job); 831254721Semaste } else { 832254721Semaste /* 833254721Semaste * No need to close things down or anything. 834254721Semaste */ 835254721Semaste done = FALSE; 836254721Semaste } 837254721Semaste 838254721Semaste if (done || WIFSTOPPED(*status) || 839254721Semaste (WIFSIGNALED(*status) && WTERMSIG(*status) == SIGCONT) || 840254721Semaste DEBUG(JOB)) { 841254721Semaste FILE *out; 842254721Semaste 843254721Semaste if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) { 844254721Semaste /* 845254721Semaste * If output is going to a file and this job is ignoring 846254721Semaste * errors, arrange to have the exit status sent to the 847254721Semaste * output file as well. 848254721Semaste */ 849254721Semaste out = fdopen(job->outFd, "w"); 850254721Semaste if (out == NULL) 851254721Semaste Punt("Cannot fdopen"); 852254721Semaste } else { 853254721Semaste out = stdout; 854254721Semaste } 855254721Semaste 856254721Semaste if (WIFEXITED(*status)) { 857254721Semaste DEBUGF(JOB, ("Process %jd exited.\n", 858254721Semaste (intmax_t)job->pid)); 859254721Semaste if (WEXITSTATUS(*status) != 0) { 860254721Semaste if (usePipes && job->node != lastNode) { 861254721Semaste MESSAGE(out, job->node); 862254721Semaste lastNode = job->node; 863254721Semaste } 864254721Semaste fprintf(out, "*** Error code %d%s\n", 865254721Semaste WEXITSTATUS(*status), 866254721Semaste (job->flags & JOB_IGNERR) ? 867254721Semaste "(ignored)" : ""); 868254721Semaste 869254721Semaste if (job->flags & JOB_IGNERR) { 870254721Semaste *status = 0; 871254721Semaste } 872254721Semaste } else if (DEBUG(JOB)) { 873254721Semaste if (usePipes && job->node != lastNode) { 874254721Semaste MESSAGE(out, job->node); 875254721Semaste lastNode = job->node; 876254721Semaste } 877254721Semaste fprintf(out, "*** Completed successfully\n"); 878254721Semaste } 879254721Semaste 880254721Semaste } else if (WIFSTOPPED(*status)) { 881254721Semaste DEBUGF(JOB, ("Process %jd stopped.\n", 882254721Semaste (intmax_t)job->pid)); 883254721Semaste if (usePipes && job->node != lastNode) { 884254721Semaste MESSAGE(out, job->node); 885254721Semaste lastNode = job->node; 886254721Semaste } 887254721Semaste fprintf(out, "*** Stopped -- signal %d\n", 888254721Semaste WSTOPSIG(*status)); 889254721Semaste job->flags |= JOB_RESUME; 890254721Semaste TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 891254721Semaste fflush(out); 892254721Semaste return; 893254721Semaste 894254721Semaste } else if (WTERMSIG(*status) == SIGCONT) { 895254721Semaste /* 896254721Semaste * If the beastie has continued, shift the Job from 897254721Semaste * the stopped list to the running one (or re-stop it 898254721Semaste * if concurrency is exceeded) and go and get another 899254721Semaste * child. 900254721Semaste */ 901254721Semaste if (job->flags & (JOB_RESUME | JOB_RESTART)) { 902254721Semaste if (usePipes && job->node != lastNode) { 903254721Semaste MESSAGE(out, job->node); 904254721Semaste lastNode = job->node; 905254721Semaste } 906254721Semaste fprintf(out, "*** Continued\n"); 907254721Semaste } 908254721Semaste if (!(job->flags & JOB_CONTINUING)) { 909254721Semaste DEBUGF(JOB, ("Warning: process %jd was not " 910254721Semaste "continuing.\n", (intmax_t)job->pid)); 911254721Semaste#ifdef notdef 912254721Semaste /* 913254721Semaste * We don't really want to restart a job from 914254721Semaste * scratch just because it continued, especially 915254721Semaste * not without killing the continuing process! 916254721Semaste * That's why this is ifdef'ed out. 917254721Semaste * FD - 9/17/90 918254721Semaste */ 919254721Semaste JobRestart(job); 920254721Semaste#endif 921254721Semaste } 922254721Semaste job->flags &= ~JOB_CONTINUING; 923254721Semaste TAILQ_INSERT_TAIL(&jobs, job, link); 924254721Semaste nJobs += 1; 925254721Semaste DEBUGF(JOB, ("Process %jd is continuing locally.\n", 926254721Semaste (intmax_t)job->pid)); 927254721Semaste if (nJobs == maxJobs) { 928254721Semaste jobFull = TRUE; 929254721Semaste DEBUGF(JOB, ("Job queue is full.\n")); 930254721Semaste } 931254721Semaste fflush(out); 932254721Semaste return; 933254721Semaste 934254721Semaste } else { 935254721Semaste if (usePipes && job->node != lastNode) { 936254721Semaste MESSAGE(out, job->node); 937254721Semaste lastNode = job->node; 938254721Semaste } 939254721Semaste fprintf(out, "*** Signal %d\n", WTERMSIG(*status)); 940254721Semaste } 941254721Semaste 942254721Semaste fflush(out); 943254721Semaste } 944254721Semaste 945254721Semaste /* 946254721Semaste * Now handle the -B-mode stuff. If the beast still isn't finished, 947254721Semaste * try and restart the job on the next command. If JobStart says it's 948254721Semaste * ok, it's ok. If there's an error, this puppy is done. 949254721Semaste */ 950254721Semaste if (compatMake && WIFEXITED(*status) && 951254721Semaste Lst_Succ(job->node->compat_command) != NULL) { 952254721Semaste switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) { 953254721Semaste case JOB_RUNNING: 954254721Semaste done = FALSE; 955254721Semaste break; 956254721Semaste case JOB_ERROR: 957254721Semaste done = TRUE; 958254721Semaste W_SETEXITSTATUS(status, 1); 959254721Semaste break; 960254721Semaste case JOB_FINISHED: 961254721Semaste /* 962254721Semaste * If we got back a JOB_FINISHED code, JobStart has 963254721Semaste * already called Make_Update and freed the job 964254721Semaste * descriptor. We set done to false here to avoid fake 965254721Semaste * cycles and double frees. JobStart needs to do the 966254721Semaste * update so we can proceed up the graph when given 967254721Semaste * the -n flag.. 968254721Semaste */ 969254721Semaste done = FALSE; 970254721Semaste break; 971254721Semaste default: 972254721Semaste break; 973254721Semaste } 974254721Semaste } else { 975254721Semaste done = TRUE; 976254721Semaste } 977254721Semaste 978254721Semaste if (done && aborting != ABORT_ERROR && 979254721Semaste aborting != ABORT_INTERRUPT && *status == 0) { 980254721Semaste /* 981254721Semaste * As long as we aren't aborting and the job didn't return a 982254721Semaste * non-zero status that we shouldn't ignore, we call 983254721Semaste * Make_Update to update the parents. In addition, any saved 984254721Semaste * commands for the node are placed on the .END target. 985254721Semaste */ 986254721Semaste for (ln = job->tailCmds; ln != NULL; ln = LST_NEXT(ln)) { 987254721Semaste Lst_AtEnd(&postCommands->commands, 988254721Semaste Buf_Peel(Var_Subst(NULL, Lst_Datum(ln), 989254721Semaste job->node, FALSE))); 990254721Semaste } 991254721Semaste 992254721Semaste job->node->made = MADE; 993254721Semaste Make_Update(job->node); 994254721Semaste free(job); 995254721Semaste 996254721Semaste } else if (*status != 0) { 997254721Semaste errors += 1; 998254721Semaste free(job); 999254721Semaste } 1000254721Semaste 1001254721Semaste JobRestartJobs(); 1002254721Semaste 1003254721Semaste /* 1004254721Semaste * Set aborting if any error. 1005254721Semaste */ 1006254721Semaste if (errors && !keepgoing && aborting != ABORT_INTERRUPT) { 1007254721Semaste /* 1008254721Semaste * If we found any errors in this batch of children and the -k 1009254721Semaste * flag wasn't given, we set the aborting flag so no more jobs 1010254721Semaste * get started. 1011254721Semaste */ 1012254721Semaste aborting = ABORT_ERROR; 1013254721Semaste } 1014254721Semaste 1015254721Semaste if (aborting == ABORT_ERROR && Job_Empty()) { 1016254721Semaste /* 1017254721Semaste * If we are aborting and the job table is now empty, we finish. 1018254721Semaste */ 1019254721Semaste Finish(errors); 1020254721Semaste } 1021254721Semaste} 1022254721Semaste 1023254721Semaste/** 1024254721Semaste * Job_Touch 1025254721Semaste * Touch the given target. Called by JobStart when the -t flag was 1026254721Semaste * given. Prints messages unless told to be silent. 1027254721Semaste * 1028254721Semaste * Side Effects: 1029254721Semaste * The data modification of the file is changed. In addition, if the 1030254721Semaste * file did not exist, it is created. 1031254721Semaste */ 1032254721Semastevoid 1033254721SemasteJob_Touch(GNode *gn, Boolean silent) 1034254721Semaste{ 1035254721Semaste int streamID; /* ID of stream opened to do the touch */ 1036254721Semaste struct utimbuf times; /* Times for utime() call */ 1037254721Semaste 1038254721Semaste if (gn->type & (OP_JOIN | OP_USE | OP_EXEC | OP_OPTIONAL)) { 1039254721Semaste /* 1040254721Semaste * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" 1041254721Semaste * targets and, as such, shouldn't really be created. 1042254721Semaste */ 1043254721Semaste return; 1044254721Semaste } 1045254721Semaste 1046254721Semaste if (!silent) { 1047254721Semaste fprintf(stdout, "touch %s\n", gn->name); 1048254721Semaste fflush(stdout); 1049254721Semaste } 1050254721Semaste 1051254721Semaste if (noExecute) { 1052254721Semaste return; 1053254721Semaste } 1054254721Semaste 1055254721Semaste if (gn->type & OP_ARCHV) { 1056254721Semaste Arch_Touch(gn); 1057254721Semaste } else if (gn->type & OP_LIB) { 1058254721Semaste Arch_TouchLib(gn); 1059254721Semaste } else { 1060254721Semaste char *file = gn->path ? gn->path : gn->name; 1061254721Semaste 1062254721Semaste times.actime = times.modtime = now; 1063254721Semaste if (utime(file, ×) < 0) { 1064254721Semaste streamID = open(file, O_RDWR | O_CREAT, 0666); 1065254721Semaste 1066254721Semaste if (streamID >= 0) { 1067254721Semaste char c; 1068254721Semaste 1069254721Semaste /* 1070254721Semaste * Read and write a byte to the file to change 1071254721Semaste * the modification time, then close the file. 1072254721Semaste */ 1073254721Semaste if (read(streamID, &c, 1) == 1) { 1074254721Semaste lseek(streamID, (off_t)0, SEEK_SET); 1075254721Semaste write(streamID, &c, 1); 1076254721Semaste } 1077254721Semaste 1078254721Semaste close(streamID); 1079254721Semaste } else { 1080254721Semaste fprintf(stdout, "*** couldn't touch %s: %s", 1081254721Semaste file, strerror(errno)); 1082254721Semaste fflush(stdout); 1083254721Semaste } 1084254721Semaste } 1085254721Semaste } 1086254721Semaste} 1087254721Semaste 1088254721Semaste/** 1089254721Semaste * Job_CheckCommands 1090254721Semaste * Make sure the given node has all the commands it needs. 1091254721Semaste * 1092254721Semaste * Results: 1093254721Semaste * TRUE if the commands list is/was ok. 1094254721Semaste * 1095254721Semaste * Side Effects: 1096254721Semaste * The node will have commands from the .DEFAULT rule added to it 1097254721Semaste * if it needs them. 1098254721Semaste */ 1099254721SemasteBoolean 1100254721SemasteJob_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) 1101254721Semaste{ 1102254721Semaste 1103254721Semaste if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) && 1104254721Semaste (gn->type & OP_LIB) == 0) { 1105254721Semaste /* 1106254721Semaste * No commands. Look for .DEFAULT rule from which we might infer 1107254721Semaste * commands. 1108254721Semaste */ 1109254721Semaste if (DEFAULT != NULL && !Lst_IsEmpty(&DEFAULT->commands)) { 1110254721Semaste char *p1; 1111254721Semaste /* 1112254721Semaste * Make only looks for a .DEFAULT if the node was 1113254721Semaste * never the target of an operator, so that's what we 1114254721Semaste * do too. If a .DEFAULT was given, we substitute its 1115254721Semaste * commands for gn's commands and set the IMPSRC 1116254721Semaste * variable to be the target's name The DEFAULT node 1117254721Semaste * acts like a transformation rule, in that gn also 1118254721Semaste * inherits any attributes or sources attached to 1119254721Semaste * .DEFAULT itself. 1120254721Semaste */ 1121254721Semaste Make_HandleUse(DEFAULT, gn); 1122254721Semaste Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn); 1123254721Semaste free(p1); 1124254721Semaste 1125254721Semaste } else if (Dir_MTime(gn) == 0) { 1126254721Semaste /* 1127254721Semaste * The node wasn't the target of an operator we have 1128254721Semaste * no .DEFAULT rule to go on and the target doesn't 1129254721Semaste * already exist. There's nothing more we can do for 1130254721Semaste * this branch. If the -k flag wasn't given, we stop 1131254721Semaste * in our tracks, otherwise we just don't update 1132254721Semaste * this node's parents so they never get examined. 1133254721Semaste */ 1134254721Semaste static const char msg[] = 1135254721Semaste "make: don't know how to make"; 1136254721Semaste 1137254721Semaste if (gn->type & OP_OPTIONAL) { 1138254721Semaste fprintf(stdout, "%s %s(ignored)\n", 1139254721Semaste msg, gn->name); 1140254721Semaste fflush(stdout); 1141254721Semaste } else if (keepgoing) { 1142254721Semaste fprintf(stdout, "%s %s(continuing)\n", 1143254721Semaste msg, gn->name); 1144254721Semaste fflush(stdout); 1145254721Semaste return (FALSE); 1146254721Semaste } else { 1147254721Semaste#if OLD_JOKE 1148254721Semaste if (strcmp(gn->name,"love") == 0) 1149254721Semaste (*abortProc)("Not war."); 1150254721Semaste else 1151254721Semaste#endif 1152254721Semaste (*abortProc)("%s %s. Stop", 1153254721Semaste msg, gn->name); 1154254721Semaste return (FALSE); 1155254721Semaste } 1156254721Semaste } 1157254721Semaste } 1158254721Semaste return (TRUE); 1159254721Semaste} 1160254721Semaste 1161254721Semaste/** 1162254721Semaste * JobExec 1163254721Semaste * Execute the shell for the given job. Called from JobStart and 1164254721Semaste * JobRestart. 1165254721Semaste * 1166254721Semaste * Side Effects: 1167254721Semaste * A shell is executed, outputs is altered and the Job structure added 1168254721Semaste * to the job table. 1169254721Semaste */ 1170254721Semastestatic void 1171254721SemasteJobExec(Job *job, char **argv) 1172254721Semaste{ 1173254721Semaste pid_t cpid; /* ID of new child */ 1174254721Semaste 1175254721Semaste if (DEBUG(JOB)) { 1176254721Semaste int i; 1177254721Semaste 1178254721Semaste DEBUGF(JOB, ("Running %s\n", job->node->name)); 1179254721Semaste DEBUGF(JOB, ("\tCommand: ")); 1180254721Semaste for (i = 0; argv[i] != NULL; i++) { 1181254721Semaste DEBUGF(JOB, ("%s ", argv[i])); 1182254721Semaste } 1183254721Semaste DEBUGF(JOB, ("\n")); 1184254721Semaste } 1185254721Semaste 1186254721Semaste /* 1187254721Semaste * Some jobs produce no output and it's disconcerting to have 1188254721Semaste * no feedback of their running (since they produce no output, the 1189254721Semaste * banner with their name in it never appears). This is an attempt to 1190254721Semaste * provide that feedback, even if nothing follows it. 1191254721Semaste */ 1192254721Semaste if (lastNode != job->node && (job->flags & JOB_FIRST) && 1193254721Semaste !(job->flags & JOB_SILENT)) { 1194254721Semaste MESSAGE(stdout, job->node); 1195254721Semaste lastNode = job->node; 1196254721Semaste } 1197254721Semaste 1198254721Semaste if ((cpid = vfork()) == -1) 1199254721Semaste Punt("Cannot fork"); 1200254721Semaste 1201254721Semaste if (cpid == 0) { 1202254721Semaste /* 1203254721Semaste * Child 1204254721Semaste */ 1205254721Semaste if (fifoFd >= 0) 1206254721Semaste close(fifoFd); 1207254721Semaste 1208254721Semaste /* 1209254721Semaste * Must duplicate the input stream down to the child's input and 1210254721Semaste * reset it to the beginning (again). Since the stream was 1211254721Semaste * marked close-on-exec, we must clear that bit in the new 1212254721Semaste * input. 1213254721Semaste */ 1214254721Semaste if (dup2(FILENO(job->cmdFILE), 0) == -1) 1215254721Semaste Punt("Cannot dup2: %s", strerror(errno)); 1216254721Semaste fcntl(0, F_SETFD, 0); 1217254721Semaste lseek(0, (off_t)0, SEEK_SET); 1218254721Semaste 1219254721Semaste if (usePipes) { 1220254721Semaste /* 1221254721Semaste * Set up the child's output to be routed through the 1222254721Semaste * pipe we've created for it. 1223254721Semaste */ 1224254721Semaste if (dup2(job->outPipe, 1) == -1) 1225254721Semaste Punt("Cannot dup2: %s", strerror(errno)); 1226254721Semaste } else { 1227254721Semaste /* 1228254721Semaste * We're capturing output in a file, so we duplicate the 1229254721Semaste * descriptor to the temporary file into the standard 1230254721Semaste * output. 1231254721Semaste */ 1232254721Semaste if (dup2(job->outFd, 1) == -1) 1233254721Semaste Punt("Cannot dup2: %s", strerror(errno)); 1234254721Semaste } 1235254721Semaste /* 1236254721Semaste * The output channels are marked close on exec. This bit was 1237254721Semaste * duplicated by the dup2 (on some systems), so we have to clear 1238254721Semaste * it before routing the shell's error output to the same place 1239254721Semaste * as its standard output. 1240254721Semaste */ 1241254721Semaste fcntl(1, F_SETFD, 0); 1242254721Semaste if (dup2(1, 2) == -1) 1243254721Semaste Punt("Cannot dup2: %s", strerror(errno)); 1244254721Semaste 1245254721Semaste#ifdef USE_PGRP 1246254721Semaste /* 1247254721Semaste * We want to switch the child into a different process family 1248254721Semaste * so we can kill it and all its descendants in one fell swoop, 1249254721Semaste * by killing its process family, but not commit suicide. 1250254721Semaste */ 1251254721Semaste# if defined(SYSV) 1252254721Semaste setsid(); 1253254721Semaste# else 1254254721Semaste setpgid(0, getpid()); 1255254721Semaste# endif 1256254721Semaste#endif /* USE_PGRP */ 1257254721Semaste 1258254721Semaste execv(shellPath, argv); 1259254721Semaste 1260254721Semaste write(STDERR_FILENO, "Could not execute shell\n", 1261254721Semaste sizeof("Could not execute shell")); 1262254721Semaste _exit(1); 1263254721Semaste } 1264254721Semaste 1265254721Semaste /* 1266254721Semaste * Parent 1267254721Semaste */ 1268254721Semaste job->pid = cpid; 1269254721Semaste 1270254721Semaste if (usePipes && (job->flags & JOB_FIRST)) { 1271254721Semaste /* 1272254721Semaste * The first time a job is run for a node, we set the 1273254721Semaste * current position in the buffer to the beginning and 1274254721Semaste * mark another stream to watch in the outputs mask. 1275254721Semaste */ 1276254721Semaste#ifdef USE_KQUEUE 1277254721Semaste struct kevent kev[2]; 1278254721Semaste#endif 1279254721Semaste job->curPos = 0; 1280254721Semaste 1281254721Semaste#if defined(USE_KQUEUE) 1282254721Semaste EV_SET(&kev[0], job->inPipe, EVFILT_READ, EV_ADD, 0, 0, job); 1283254721Semaste EV_SET(&kev[1], job->pid, EVFILT_PROC, 1284254721Semaste EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, NULL); 1285254721Semaste if (kevent(kqfd, kev, 2, NULL, 0, NULL) != 0) { 1286254721Semaste /* 1287254721Semaste * kevent() will fail if the job is already 1288254721Semaste * finished 1289254721Semaste */ 1290254721Semaste if (errno != EINTR && errno != EBADF && errno != ESRCH) 1291254721Semaste Punt("kevent: %s", strerror(errno)); 1292254721Semaste } 1293254721Semaste#else 1294254721Semaste FD_SET(job->inPipe, &outputs); 1295254721Semaste#endif /* USE_KQUEUE */ 1296254721Semaste } 1297254721Semaste 1298254721Semaste if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1299254721Semaste fclose(job->cmdFILE); 1300254721Semaste job->cmdFILE = NULL; 1301254721Semaste } 1302254721Semaste 1303254721Semaste /* 1304254721Semaste * Now the job is actually running, add it to the table. 1305254721Semaste */ 1306254721Semaste nJobs += 1; 1307254721Semaste TAILQ_INSERT_TAIL(&jobs, job, link); 1308254721Semaste if (nJobs == maxJobs) { 1309254721Semaste jobFull = TRUE; 1310254721Semaste } 1311254721Semaste} 1312254721Semaste 1313254721Semaste/** 1314254721Semaste * JobMakeArgv 1315254721Semaste * Create the argv needed to execute the shell for a given job. 1316254721Semaste */ 1317254721Semastestatic void 1318254721SemasteJobMakeArgv(Job *job, char **argv) 1319254721Semaste{ 1320254721Semaste int argc; 1321254721Semaste static char args[10]; /* For merged arguments */ 1322254721Semaste 1323254721Semaste argv[0] = shellName; 1324254721Semaste argc = 1; 1325254721Semaste 1326254721Semaste if ((commandShell->exit && *commandShell->exit != '-') || 1327254721Semaste (commandShell->echo && *commandShell->echo != '-')) { 1328254721Semaste /* 1329254721Semaste * At least one of the flags doesn't have a minus before it, so 1330254721Semaste * merge them together. Have to do this because the *(&(@*#*&#$# 1331254721Semaste * Bourne shell thinks its second argument is a file to source. 1332254721Semaste * Grrrr. Note the ten-character limitation on the combined 1333254721Semaste * arguments. 1334254721Semaste */ 1335254721Semaste sprintf(args, "-%s%s", (job->flags & JOB_IGNERR) ? "" : 1336254721Semaste commandShell->exit ? commandShell->exit : "", 1337254721Semaste (job->flags & JOB_SILENT) ? "" : 1338254721Semaste commandShell->echo ? commandShell->echo : ""); 1339254721Semaste 1340254721Semaste if (args[1]) { 1341254721Semaste argv[argc] = args; 1342254721Semaste argc++; 1343254721Semaste } 1344254721Semaste } else { 1345254721Semaste if (!(job->flags & JOB_IGNERR) && commandShell->exit) { 1346254721Semaste argv[argc] = commandShell->exit; 1347254721Semaste argc++; 1348254721Semaste } 1349254721Semaste if (!(job->flags & JOB_SILENT) && commandShell->echo) { 1350254721Semaste argv[argc] = commandShell->echo; 1351254721Semaste argc++; 1352254721Semaste } 1353254721Semaste } 1354254721Semaste argv[argc] = NULL; 1355254721Semaste} 1356254721Semaste 1357254721Semaste/** 1358254721Semaste * JobRestart 1359254721Semaste * Restart a job that stopped for some reason. The job must be neither 1360254721Semaste * on the jobs nor on the stoppedJobs list. 1361254721Semaste * 1362254721Semaste * Side Effects: 1363254721Semaste * jobFull will be set if the job couldn't be run. 1364254721Semaste */ 1365254721Semastestatic void 1366254721SemasteJobRestart(Job *job) 1367254721Semaste{ 1368254721Semaste 1369254721Semaste if (job->flags & JOB_RESTART) { 1370254721Semaste /* 1371254721Semaste * Set up the control arguments to the shell. This is based on 1372254721Semaste * the flags set earlier for this job. If the JOB_IGNERR flag 1373254721Semaste * is clear, the 'exit' flag of the commandShell is used to 1374254721Semaste * cause it to exit upon receiving an error. If the JOB_SILENT 1375254721Semaste * flag is clear, the 'echo' flag of the commandShell is used 1376254721Semaste * to get it to start echoing as soon as it starts 1377254721Semaste * processing commands. 1378254721Semaste */ 1379254721Semaste char *argv[4]; 1380254721Semaste 1381254721Semaste JobMakeArgv(job, argv); 1382254721Semaste 1383254721Semaste DEBUGF(JOB, ("Restarting %s...", job->node->name)); 1384254721Semaste if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) { 1385254721Semaste /* 1386254721Semaste * Not allowed to run -- put it back on the hold 1387254721Semaste * queue and mark the table full 1388254721Semaste */ 1389254721Semaste DEBUGF(JOB, ("holding\n")); 1390254721Semaste TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1391254721Semaste jobFull = TRUE; 1392254721Semaste DEBUGF(JOB, ("Job queue is full.\n")); 1393254721Semaste return; 1394254721Semaste } else { 1395254721Semaste /* 1396254721Semaste * Job may be run locally. 1397254721Semaste */ 1398254721Semaste DEBUGF(JOB, ("running locally\n")); 1399254721Semaste } 1400254721Semaste JobExec(job, argv); 1401254721Semaste 1402254721Semaste } else { 1403254721Semaste /* 1404254721Semaste * The job has stopped and needs to be restarted. 1405254721Semaste * Why it stopped, we don't know... 1406254721Semaste */ 1407254721Semaste DEBUGF(JOB, ("Resuming %s...", job->node->name)); 1408254721Semaste if ((nJobs < maxJobs || ((job->flags & JOB_SPECIAL) && 1409254721Semaste maxJobs == 0)) && nJobs != maxJobs) { 1410254721Semaste /* 1411254721Semaste * If we haven't reached the concurrency limit already 1412254721Semaste * (or the job must be run and maxJobs is 0), it's ok 1413254721Semaste * to resume it. 1414254721Semaste */ 1415254721Semaste Boolean error; 1416254721Semaste int status; 1417254721Semaste 1418254721Semaste error = (KILL(job->pid, SIGCONT) != 0); 1419254721Semaste 1420254721Semaste if (!error) { 1421254721Semaste /* 1422254721Semaste * Make sure the user knows we've continued 1423254721Semaste * the beast and actually put the thing in the 1424254721Semaste * job table. 1425254721Semaste */ 1426254721Semaste job->flags |= JOB_CONTINUING; 1427254721Semaste status = 0; 1428254721Semaste W_SETTERMSIG(&status, SIGCONT); 1429254721Semaste JobFinish(job, &status); 1430254721Semaste 1431254721Semaste job->flags &= ~(JOB_RESUME|JOB_CONTINUING); 1432254721Semaste DEBUGF(JOB, ("done\n")); 1433254721Semaste } else { 1434254721Semaste Error("couldn't resume %s: %s", 1435254721Semaste job->node->name, strerror(errno)); 1436254721Semaste status = 0; 1437254721Semaste W_SETEXITSTATUS(&status, 1); 1438254721Semaste JobFinish(job, &status); 1439254721Semaste } 1440254721Semaste } else { 1441254721Semaste /* 1442254721Semaste * Job cannot be restarted. Mark the table as full and 1443254721Semaste * place the job back on the list of stopped jobs. 1444254721Semaste */ 1445254721Semaste DEBUGF(JOB, ("table full\n")); 1446254721Semaste TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1447254721Semaste jobFull = TRUE; 1448254721Semaste DEBUGF(JOB, ("Job queue is full.\n")); 1449254721Semaste } 1450254721Semaste } 1451254721Semaste} 1452254721Semaste 1453254721Semaste/** 1454254721Semaste * JobStart 1455254721Semaste * Start a target-creation process going for the target described 1456254721Semaste * by the graph node gn. 1457254721Semaste * 1458254721Semaste * Results: 1459254721Semaste * JOB_ERROR if there was an error in the commands, JOB_FINISHED 1460254721Semaste * if there isn't actually anything left to do for the job and 1461254721Semaste * JOB_RUNNING if the job has been started. 1462254721Semaste * 1463254721Semaste * Side Effects: 1464254721Semaste * A new Job node is created and added to the list of running 1465254721Semaste * jobs. PMake is forked and a child shell created. 1466254721Semaste */ 1467254721Semastestatic int 1468254721SemasteJobStart(GNode *gn, int flags, Job *previous) 1469254721Semaste{ 1470254721Semaste Job *job; /* new job descriptor */ 1471254721Semaste char *argv[4]; /* Argument vector to shell */ 1472254721Semaste Boolean cmdsOK; /* true if the nodes commands were all right */ 1473254721Semaste Boolean noExec; /* Set true if we decide not to run the job */ 1474254721Semaste int tfd; /* File descriptor for temp file */ 1475254721Semaste LstNode *ln; 1476254721Semaste char tfile[sizeof(TMPPAT)]; 1477254721Semaste 1478254721Semaste if (interrupted) { 1479254721Semaste JobPassSig(interrupted); 1480254721Semaste return (JOB_ERROR); 1481254721Semaste } 1482254721Semaste if (previous != NULL) { 1483254721Semaste previous->flags &= ~(JOB_FIRST | JOB_IGNERR | JOB_SILENT); 1484254721Semaste job = previous; 1485254721Semaste } else { 1486254721Semaste job = emalloc(sizeof(Job)); 1487254721Semaste flags |= JOB_FIRST; 1488254721Semaste } 1489254721Semaste 1490254721Semaste job->node = gn; 1491254721Semaste job->tailCmds = NULL; 1492254721Semaste 1493254721Semaste /* 1494254721Semaste * Set the initial value of the flags for this job based on the global 1495254721Semaste * ones and the node's attributes... Any flags supplied by the caller 1496254721Semaste * are also added to the field. 1497254721Semaste */ 1498254721Semaste job->flags = 0; 1499254721Semaste if (Targ_Ignore(gn)) { 1500254721Semaste job->flags |= JOB_IGNERR; 1501254721Semaste } 1502254721Semaste if (Targ_Silent(gn)) { 1503254721Semaste job->flags |= JOB_SILENT; 1504254721Semaste } 1505254721Semaste job->flags |= flags; 1506254721Semaste 1507254721Semaste /* 1508254721Semaste * Check the commands now so any attributes from .DEFAULT have a chance 1509254721Semaste * to migrate to the node. 1510254721Semaste */ 1511254721Semaste if (!compatMake && (job->flags & JOB_FIRST)) { 1512254721Semaste cmdsOK = Job_CheckCommands(gn, Error); 1513254721Semaste } else { 1514254721Semaste cmdsOK = TRUE; 1515254721Semaste } 1516254721Semaste 1517254721Semaste /* 1518254721Semaste * If the -n flag wasn't given, we open up OUR (not the child's) 1519254721Semaste * temporary file to stuff commands in it. The thing is rd/wr so we 1520254721Semaste * don't need to reopen it to feed it to the shell. If the -n flag 1521254721Semaste * *was* given, we just set the file to be stdout. Cute, huh? 1522254721Semaste */ 1523254721Semaste if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) { 1524254721Semaste /* 1525254721Semaste * We're serious here, but if the commands were bogus, we're 1526254721Semaste * also dead... 1527254721Semaste */ 1528254721Semaste if (!cmdsOK) { 1529254721Semaste DieHorribly(); 1530254721Semaste } 1531254721Semaste 1532254721Semaste strcpy(tfile, TMPPAT); 1533254721Semaste if ((tfd = mkstemp(tfile)) == -1) 1534254721Semaste Punt("Cannot create temp file: %s", strerror(errno)); 1535254721Semaste job->cmdFILE = fdopen(tfd, "w+"); 1536254721Semaste eunlink(tfile); 1537254721Semaste if (job->cmdFILE == NULL) { 1538254721Semaste close(tfd); 1539254721Semaste Punt("Could not open %s", tfile); 1540254721Semaste } 1541254721Semaste fcntl(FILENO(job->cmdFILE), F_SETFD, 1); 1542254721Semaste /* 1543254721Semaste * Send the commands to the command file, flush all its 1544254721Semaste * buffers then rewind and remove the thing. 1545254721Semaste */ 1546254721Semaste noExec = FALSE; 1547254721Semaste 1548254721Semaste /* 1549254721Semaste * Used to be backwards; replace when start doing multiple 1550254721Semaste * commands per shell. 1551254721Semaste */ 1552254721Semaste if (compatMake) { 1553254721Semaste /* 1554254721Semaste * Be compatible: If this is the first time for this 1555254721Semaste * node, verify its commands are ok and open the 1556254721Semaste * commands list for sequential access by later 1557254721Semaste * invocations of JobStart. Once that is done, we take 1558254721Semaste * the next command off the list and print it to the 1559254721Semaste * command file. If the command was an ellipsis, note 1560254721Semaste * that there's nothing more to execute. 1561254721Semaste */ 1562254721Semaste if (job->flags & JOB_FIRST) 1563254721Semaste gn->compat_command = Lst_First(&gn->commands); 1564254721Semaste else 1565254721Semaste gn->compat_command = 1566254721Semaste Lst_Succ(gn->compat_command); 1567254721Semaste 1568254721Semaste if (gn->compat_command == NULL || 1569254721Semaste JobPrintCommand(Lst_Datum(gn->compat_command), job)) 1570254721Semaste noExec = TRUE; 1571254721Semaste 1572254721Semaste if (noExec && !(job->flags & JOB_FIRST)) { 1573254721Semaste /* 1574254721Semaste * If we're not going to execute anything, the 1575254721Semaste * job is done and we need to close down the 1576254721Semaste * various file descriptors we've opened for 1577254721Semaste * output, then call JobDoOutput to catch the 1578254721Semaste * final characters or send the file to the 1579254721Semaste * screen... Note that the i/o streams are only 1580254721Semaste * open if this isn't the first job. Note also 1581254721Semaste * that this could not be done in 1582254721Semaste * Job_CatchChildren b/c it wasn't clear if 1583254721Semaste * there were more commands to execute or not... 1584254721Semaste */ 1585254721Semaste JobClose(job); 1586254721Semaste } 1587254721Semaste } else { 1588254721Semaste /* 1589254721Semaste * We can do all the commands at once. hooray for sanity 1590254721Semaste */ 1591254721Semaste numCommands = 0; 1592254721Semaste LST_FOREACH(ln, &gn->commands) { 1593254721Semaste if (JobPrintCommand(Lst_Datum(ln), job)) 1594254721Semaste break; 1595254721Semaste } 1596254721Semaste 1597254721Semaste /* 1598254721Semaste * If we didn't print out any commands to the shell 1599254721Semaste * script, there's not much point in executing the 1600254721Semaste * shell, is there? 1601254721Semaste */ 1602254721Semaste if (numCommands == 0) { 1603254721Semaste noExec = TRUE; 1604254721Semaste } 1605254721Semaste } 1606254721Semaste 1607254721Semaste } else if (noExecute) { 1608254721Semaste /* 1609254721Semaste * Not executing anything -- just print all the commands to 1610254721Semaste * stdout in one fell swoop. This will still set up 1611254721Semaste * job->tailCmds correctly. 1612254721Semaste */ 1613254721Semaste if (lastNode != gn) { 1614254721Semaste MESSAGE(stdout, gn); 1615254721Semaste lastNode = gn; 1616254721Semaste } 1617254721Semaste job->cmdFILE = stdout; 1618254721Semaste 1619254721Semaste /* 1620254721Semaste * Only print the commands if they're ok, but don't die if 1621254721Semaste * they're not -- just let the user know they're bad and keep 1622254721Semaste * going. It doesn't do any harm in this case and may do 1623254721Semaste * some good. 1624254721Semaste */ 1625254721Semaste if (cmdsOK) { 1626254721Semaste LST_FOREACH(ln, &gn->commands) { 1627254721Semaste if (JobPrintCommand(Lst_Datum(ln), job)) 1628254721Semaste break; 1629254721Semaste } 1630254721Semaste } 1631254721Semaste /* 1632254721Semaste * Don't execute the shell, thank you. 1633254721Semaste */ 1634254721Semaste noExec = TRUE; 1635254721Semaste 1636254721Semaste } else { 1637254721Semaste /* 1638254721Semaste * Just touch the target and note that no shell should be 1639254721Semaste * executed. Set cmdFILE to stdout to make life easier. Check 1640254721Semaste * the commands, too, but don't die if they're no good -- it 1641254721Semaste * does no harm to keep working up the graph. 1642254721Semaste */ 1643254721Semaste job->cmdFILE = stdout; 1644254721Semaste Job_Touch(gn, job->flags & JOB_SILENT); 1645254721Semaste noExec = TRUE; 1646254721Semaste } 1647254721Semaste 1648254721Semaste /* 1649254721Semaste * If we're not supposed to execute a shell, don't. 1650254721Semaste */ 1651254721Semaste if (noExec) { 1652254721Semaste /* 1653254721Semaste * Unlink and close the command file if we opened one 1654254721Semaste */ 1655254721Semaste if (job->cmdFILE != stdout) { 1656254721Semaste if (job->cmdFILE != NULL) 1657254721Semaste fclose(job->cmdFILE); 1658254721Semaste } else { 1659254721Semaste fflush(stdout); 1660254721Semaste } 1661254721Semaste 1662254721Semaste /* 1663254721Semaste * We only want to work our way up the graph if we aren't here 1664254721Semaste * because the commands for the job were no good. 1665254721Semaste */ 1666254721Semaste if (cmdsOK) { 1667254721Semaste if (aborting == 0) { 1668254721Semaste for (ln = job->tailCmds; ln != NULL; 1669254721Semaste ln = LST_NEXT(ln)) { 1670254721Semaste Lst_AtEnd(&postCommands->commands, 1671254721Semaste Buf_Peel(Var_Subst(NULL, 1672254721Semaste Lst_Datum(ln), job->node, FALSE))); 1673254721Semaste } 1674254721Semaste job->node->made = MADE; 1675254721Semaste Make_Update(job->node); 1676254721Semaste } 1677254721Semaste free(job); 1678254721Semaste return(JOB_FINISHED); 1679254721Semaste } else { 1680254721Semaste free(job); 1681254721Semaste return(JOB_ERROR); 1682254721Semaste } 1683254721Semaste } else { 1684254721Semaste fflush(job->cmdFILE); 1685254721Semaste } 1686254721Semaste 1687254721Semaste /* 1688254721Semaste * Set up the control arguments to the shell. This is based on the flags 1689254721Semaste * set earlier for this job. 1690254721Semaste */ 1691254721Semaste JobMakeArgv(job, argv); 1692254721Semaste 1693254721Semaste /* 1694254721Semaste * If we're using pipes to catch output, create the pipe by which we'll 1695254721Semaste * get the shell's output. If we're using files, print out that we're 1696254721Semaste * starting a job and then set up its temporary-file name. 1697254721Semaste */ 1698254721Semaste if (!compatMake || (job->flags & JOB_FIRST)) { 1699254721Semaste if (usePipes) { 1700254721Semaste int fd[2]; 1701254721Semaste 1702254721Semaste if (pipe(fd) == -1) 1703254721Semaste Punt("Cannot create pipe: %s", strerror(errno)); 1704254721Semaste job->inPipe = fd[0]; 1705254721Semaste job->outPipe = fd[1]; 1706254721Semaste fcntl(job->inPipe, F_SETFD, 1); 1707254721Semaste fcntl(job->outPipe, F_SETFD, 1); 1708254721Semaste } else { 1709254721Semaste fprintf(stdout, "Remaking `%s'\n", gn->name); 1710254721Semaste fflush(stdout); 1711254721Semaste strcpy(job->outFile, TMPPAT); 1712254721Semaste if ((job->outFd = mkstemp(job->outFile)) == -1) 1713254721Semaste Punt("cannot create temp file: %s", 1714254721Semaste strerror(errno)); 1715254721Semaste fcntl(job->outFd, F_SETFD, 1); 1716254721Semaste } 1717254721Semaste } 1718254721Semaste 1719254721Semaste if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) && maxJobs != 0) { 1720254721Semaste /* 1721254721Semaste * We've hit the limit of concurrency, so put the job on hold 1722254721Semaste * until some other job finishes. Note that the special jobs 1723254721Semaste * (.BEGIN, .INTERRUPT and .END) may be run even when the 1724254721Semaste * limit has been reached (e.g. when maxJobs == 0). 1725254721Semaste */ 1726254721Semaste jobFull = TRUE; 1727254721Semaste 1728254721Semaste DEBUGF(JOB, ("Can only run job locally.\n")); 1729254721Semaste job->flags |= JOB_RESTART; 1730254721Semaste TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 1731254721Semaste } else { 1732254721Semaste if (nJobs >= maxJobs) { 1733254721Semaste /* 1734254721Semaste * If we're running this job as a special case 1735254721Semaste * (see above), at least say the table is full. 1736254721Semaste */ 1737254721Semaste jobFull = TRUE; 1738254721Semaste DEBUGF(JOB, ("Local job queue is full.\n")); 1739254721Semaste } 1740254721Semaste JobExec(job, argv); 1741254721Semaste } 1742254721Semaste return (JOB_RUNNING); 1743254721Semaste} 1744254721Semaste 1745254721Semastestatic char * 1746254721SemasteJobOutput(Job *job, char *cp, char *endp, int msg) 1747254721Semaste{ 1748254721Semaste char *ecp; 1749254721Semaste 1750254721Semaste if (commandShell->noPrint) { 1751254721Semaste ecp = strstr(cp, commandShell->noPrint); 1752254721Semaste while (ecp != NULL) { 1753254721Semaste if (cp != ecp) { 1754254721Semaste *ecp = '\0'; 1755254721Semaste if (msg && job->node != lastNode) { 1756254721Semaste MESSAGE(stdout, job->node); 1757254721Semaste lastNode = job->node; 1758254721Semaste } 1759254721Semaste /* 1760254721Semaste * The only way there wouldn't be a newline 1761254721Semaste * after this line is if it were the last in 1762254721Semaste * the buffer. However, since the non-printable 1763254721Semaste * comes after it, there must be a newline, so 1764254721Semaste * we don't print one. 1765254721Semaste */ 1766254721Semaste fprintf(stdout, "%s", cp); 1767254721Semaste fflush(stdout); 1768254721Semaste } 1769263363Semaste cp = ecp + commandShell->noPLen; 1770263363Semaste if (cp != endp) { 1771263363Semaste /* 1772263363Semaste * Still more to print, look again after 1773263363Semaste * skipping the whitespace following the 1774263363Semaste * non-printable command.... 1775263363Semaste */ 1776263363Semaste cp++; 1777263363Semaste while (*cp == ' ' || *cp == '\t' || 1778263363Semaste *cp == '\n') { 1779263363Semaste cp++; 1780263363Semaste } 1781263363Semaste ecp = strstr(cp, commandShell->noPrint); 1782263363Semaste } else { 1783263363Semaste return (cp); 1784263363Semaste } 1785263363Semaste } 1786263363Semaste } 1787263363Semaste return (cp); 1788263363Semaste} 1789263363Semaste 1790263363Semaste/** 1791263363Semaste * JobDoOutput 1792263363Semaste * This function is called at different times depending on 1793263363Semaste * whether the user has specified that output is to be collected 1794263363Semaste * via pipes or temporary files. In the former case, we are called 1795263363Semaste * whenever there is something to read on the pipe. We collect more 1796263363Semaste * output from the given job and store it in the job's outBuf. If 1797263363Semaste * this makes up a line, we print it tagged by the job's identifier, 1798263363Semaste * as necessary. 1799263363Semaste * If output has been collected in a temporary file, we open the 1800263363Semaste * file and read it line by line, transfering it to our own 1801263363Semaste * output channel until the file is empty. At which point we 1802263363Semaste * remove the temporary file. 1803263363Semaste * In both cases, however, we keep our figurative eye out for the 1804263363Semaste * 'noPrint' line for the shell from which the output came. If 1805263363Semaste * we recognize a line, we don't print it. If the command is not 1806263363Semaste * alone on the line (the character after it is not \0 or \n), we 1807263363Semaste * do print whatever follows it. 1808263363Semaste * 1809263363Semaste * Side Effects: 1810263363Semaste * curPos may be shifted as may the contents of outBuf. 1811263363Semaste */ 1812263363Semastestatic void 1813263363SemasteJobDoOutput(Job *job, Boolean finish) 1814263363Semaste{ 1815263363Semaste Boolean gotNL = FALSE; /* true if got a newline */ 1816263363Semaste Boolean fbuf; /* true if our buffer filled up */ 1817263363Semaste int nr; /* number of bytes read */ 1818263363Semaste int i; /* auxiliary index into outBuf */ 1819263363Semaste int max; /* limit for i (end of current data) */ 1820263363Semaste int nRead; /* (Temporary) number of bytes read */ 1821263363Semaste FILE *oFILE; /* Stream pointer to shell's output file */ 1822263363Semaste char inLine[132]; 1823263363Semaste 1824263363Semaste if (usePipes) { 1825263363Semaste /* 1826263363Semaste * Read as many bytes as will fit in the buffer. 1827263363Semaste */ 1828263363Semaste end_loop: 1829263363Semaste gotNL = FALSE; 1830263363Semaste fbuf = FALSE; 1831263363Semaste 1832263363Semaste nRead = read(job->inPipe, &job->outBuf[job->curPos], 1833263363Semaste JOB_BUFSIZE - job->curPos); 1834263363Semaste /* 1835263363Semaste * Check for interrupt here too, because the above read may 1836263363Semaste * block when the child process is stopped. In this case the 1837263363Semaste * interrupt will unblock it (we don't use SA_RESTART). 1838263363Semaste */ 1839263363Semaste if (interrupted) 1840263363Semaste JobPassSig(interrupted); 1841263363Semaste 1842254721Semaste if (nRead < 0) { 1843254721Semaste DEBUGF(JOB, ("JobDoOutput(piperead)")); 1844254721Semaste nr = 0; 1845254721Semaste } else { 1846254721Semaste nr = nRead; 1847254721Semaste } 1848254721Semaste 1849254721Semaste /* 1850254721Semaste * If we hit the end-of-file (the job is dead), we must flush 1851254721Semaste * its remaining output, so pretend we read a newline if 1852254721Semaste * there's any output remaining in the buffer. 1853254721Semaste * Also clear the 'finish' flag so we stop looping. 1854254721Semaste */ 1855254721Semaste if (nr == 0 && job->curPos != 0) { 1856254721Semaste job->outBuf[job->curPos] = '\n'; 1857254721Semaste nr = 1; 1858254721Semaste finish = FALSE; 1859254721Semaste } else if (nr == 0) { 1860254721Semaste finish = FALSE; 1861254721Semaste } 1862254721Semaste 1863254721Semaste /* 1864254721Semaste * Look for the last newline in the bytes we just got. If there 1865254721Semaste * is one, break out of the loop with 'i' as its index and 1866254721Semaste * gotNL set TRUE. 1867254721Semaste */ 1868254721Semaste max = job->curPos + nr; 1869254721Semaste for (i = job->curPos + nr - 1; i >= job->curPos; i--) { 1870254721Semaste if (job->outBuf[i] == '\n') { 1871254721Semaste gotNL = TRUE; 1872254721Semaste break; 1873254721Semaste } else if (job->outBuf[i] == '\0') { 1874254721Semaste /* 1875254721Semaste * Why? 1876254721Semaste */ 1877254721Semaste job->outBuf[i] = ' '; 1878254721Semaste } 1879254721Semaste } 1880254721Semaste 1881263363Semaste if (!gotNL) { 1882263363Semaste job->curPos += nr; 1883263363Semaste if (job->curPos == JOB_BUFSIZE) { 1884263363Semaste /* 1885263363Semaste * If we've run out of buffer space, we have 1886263363Semaste * no choice but to print the stuff. sigh. 1887263363Semaste */ 1888263363Semaste fbuf = TRUE; 1889263363Semaste i = job->curPos; 1890263363Semaste } 1891263363Semaste } 1892263363Semaste if (gotNL || fbuf) { 1893263363Semaste /* 1894263363Semaste * Need to send the output to the screen. Null terminate 1895263363Semaste * it first, overwriting the newline character if there 1896263363Semaste * was one. So long as the line isn't one we should 1897263363Semaste * filter (according to the shell description), we print 1898263363Semaste * the line, preceded by a target banner if this target 1899254721Semaste * isn't the same as the one for which we last printed 1900254721Semaste * something. The rest of the data in the buffer are 1901254721Semaste * then shifted down to the start of the buffer and 1902254721Semaste * curPos is set accordingly. 1903254721Semaste */ 1904254721Semaste job->outBuf[i] = '\0'; 1905254721Semaste if (i >= job->curPos) { 1906254721Semaste char *cp; 1907254721Semaste 1908254721Semaste cp = JobOutput(job, job->outBuf, 1909254721Semaste &job->outBuf[i], FALSE); 1910254721Semaste 1911254721Semaste /* 1912254721Semaste * There's still more in that buffer. This time, 1913254721Semaste * though, we know there's no newline at the 1914254721Semaste * end, so we add one of our own free will. 1915254721Semaste */ 1916254721Semaste if (*cp != '\0') { 1917254721Semaste if (job->node != lastNode) { 1918254721Semaste MESSAGE(stdout, job->node); 1919254721Semaste lastNode = job->node; 1920254721Semaste } 1921254721Semaste fprintf(stdout, "%s%s", cp, 1922254721Semaste gotNL ? "\n" : ""); 1923254721Semaste fflush(stdout); 1924254721Semaste } 1925254721Semaste } 1926254721Semaste if (i < max - 1) { 1927254721Semaste /* shift the remaining characters down */ 1928254721Semaste memcpy(job->outBuf, &job->outBuf[i + 1], 1929254721Semaste max - (i + 1)); 1930254721Semaste job->curPos = max - (i + 1); 1931254721Semaste 1932254721Semaste } else { 1933254721Semaste /* 1934254721Semaste * We have written everything out, so we just 1935254721Semaste * start over from the start of the buffer. 1936254721Semaste * No copying. No nothing. 1937254721Semaste */ 1938254721Semaste job->curPos = 0; 1939254721Semaste } 1940254721Semaste } 1941254721Semaste if (finish) { 1942254721Semaste /* 1943254721Semaste * If the finish flag is true, we must loop until we hit 1944254721Semaste * end-of-file on the pipe. This is guaranteed to happen 1945254721Semaste * eventually since the other end of the pipe is now 1946254721Semaste * closed (we closed it explicitly and the child has 1947254721Semaste * exited). When we do get an EOF, finish will be set 1948254721Semaste * FALSE and we'll fall through and out. 1949254721Semaste */ 1950254721Semaste goto end_loop; 1951254721Semaste } 1952254721Semaste 1953254721Semaste } else { 1954254721Semaste /* 1955254721Semaste * We've been called to retrieve the output of the job from the 1956254721Semaste * temporary file where it's been squirreled away. This consists 1957254721Semaste * of opening the file, reading the output line by line, being 1958254721Semaste * sure not to print the noPrint line for the shell we used, 1959254721Semaste * then close and remove the temporary file. Very simple. 1960254721Semaste * 1961254721Semaste * Change to read in blocks and do FindSubString type things 1962254721Semaste * as for pipes? That would allow for "@echo -n..." 1963254721Semaste */ 1964254721Semaste oFILE = fopen(job->outFile, "r"); 1965254721Semaste if (oFILE != NULL) { 1966254721Semaste fprintf(stdout, "Results of making %s:\n", 1967254721Semaste job->node->name); 1968254721Semaste fflush(stdout); 1969254721Semaste 1970254721Semaste while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { 1971254721Semaste char *cp, *endp, *oendp; 1972254721Semaste 1973254721Semaste cp = inLine; 1974254721Semaste oendp = endp = inLine + strlen(inLine); 1975254721Semaste if (endp[-1] == '\n') { 1976254721Semaste *--endp = '\0'; 1977254721Semaste } 1978263363Semaste cp = JobOutput(job, inLine, endp, FALSE); 1979263363Semaste 1980263363Semaste /* 1981263363Semaste * There's still more in that buffer. This time, 1982263363Semaste * though, we know there's no newline at the 1983263363Semaste * end, so we add one of our own free will. 1984263363Semaste */ 1985254721Semaste fprintf(stdout, "%s", cp); 1986254721Semaste fflush(stdout); 1987254721Semaste if (endp != oendp) { 1988254721Semaste fprintf(stdout, "\n"); 1989263363Semaste fflush(stdout); 1990263363Semaste } 1991263363Semaste } 1992263363Semaste fclose(oFILE); 1993254721Semaste eunlink(job->outFile); 1994254721Semaste } 1995254721Semaste } 1996254721Semaste} 1997254721Semaste 1998254721Semaste/** 1999254721Semaste * Job_CatchChildren 2000254721Semaste * Handle the exit of a child. Called from Make_Make. 2001254721Semaste * 2002254721Semaste * Side Effects: 2003254721Semaste * The job descriptor is removed from the list of children. 2004254721Semaste * 2005254721Semaste * Notes: 2006254721Semaste * We do waits, blocking or not, according to the wisdom of our 2007254721Semaste * caller, until there are no more children to report. For each 2008254721Semaste * job, call JobFinish to finish things off. This will take care of 2009254721Semaste * putting jobs on the stoppedJobs queue. 2010254721Semaste */ 2011254721Semastevoid 2012254721SemasteJob_CatchChildren(Boolean block) 2013254721Semaste{ 2014254721Semaste pid_t pid; /* pid of dead child */ 2015254721Semaste Job *job; /* job descriptor for dead child */ 2016254721Semaste int status; /* Exit/termination status */ 2017254721Semaste 2018254721Semaste /* 2019254721Semaste * Don't even bother if we know there's no one around. 2020254721Semaste */ 2021254721Semaste if (nJobs == 0) { 2022254721Semaste return; 2023254721Semaste } 2024254721Semaste 2025263363Semaste for (;;) { 2026269024Semaste pid = waitpid((pid_t)-1, &status, 2027254721Semaste (block ? 0 : WNOHANG) | WUNTRACED); 2028254721Semaste if (pid <= 0) 2029254721Semaste break; 2030254721Semaste 2031254721Semaste DEBUGF(JOB, ("Process %jd exited or stopped.\n", 2032254721Semaste (intmax_t)pid)); 2033254721Semaste 2034254721Semaste TAILQ_FOREACH(job, &jobs, link) { 2035254721Semaste if (job->pid == pid) 2036254721Semaste break; 2037254721Semaste } 2038254721Semaste 2039254721Semaste if (job == NULL) { 2040254721Semaste if (WIFSIGNALED(status) && 2041254721Semaste (WTERMSIG(status) == SIGCONT)) { 2042254721Semaste TAILQ_FOREACH(job, &jobs, link) { 2043254721Semaste if (job->pid == pid) 2044254721Semaste break; 2045254721Semaste } 2046254721Semaste if (job == NULL) { 2047254721Semaste Error("Resumed child (%jd) " 2048254721Semaste "not in table", (intmax_t)pid); 2049254721Semaste continue; 2050254721Semaste } 2051254721Semaste TAILQ_REMOVE(&stoppedJobs, job, link); 2052254721Semaste } else { 2053254721Semaste Error("Child (%jd) not in table?", 2054254721Semaste (intmax_t)pid); 2055254721Semaste continue; 2056254721Semaste } 2057254721Semaste } else { 2058254721Semaste TAILQ_REMOVE(&jobs, job, link); 2059254721Semaste nJobs -= 1; 2060254721Semaste if (fifoFd >= 0 && maxJobs > 1) { 2061254721Semaste write(fifoFd, "+", 1); 2062254721Semaste maxJobs--; 2063254721Semaste if (nJobs >= maxJobs) 2064254721Semaste jobFull = TRUE; 2065254721Semaste else 2066254721Semaste jobFull = FALSE; 2067254721Semaste } else { 2068254721Semaste DEBUGF(JOB, ("Job queue is no longer full.\n")); 2069269024Semaste jobFull = FALSE; 2070269024Semaste } 2071269024Semaste } 2072269024Semaste 2073269024Semaste JobFinish(job, &status); 2074269024Semaste } 2075269024Semaste if (interrupted) 2076269024Semaste JobPassSig(interrupted); 2077269024Semaste} 2078269024Semaste 2079269024Semaste/** 2080269024Semaste * Job_CatchOutput 2081269024Semaste * Catch the output from our children, if we're using 2082269024Semaste * pipes do so. Otherwise just block time until we get a 2083269024Semaste * signal(most likely a SIGCHLD) since there's no point in 2084269024Semaste * just spinning when there's nothing to do and the reaping 2085269024Semaste * of a child can wait for a while. 2086269024Semaste * 2087269024Semaste * Side Effects: 2088269024Semaste * Output is read from pipes if we're piping. 2089269024Semaste * ----------------------------------------------------------------------- 2090269024Semaste */ 2091269024Semastevoid 2092269024Semaste#ifdef USE_KQUEUE 2093269024SemasteJob_CatchOutput(int flag __unused) 2094269024Semaste#else 2095269024SemasteJob_CatchOutput(int flag) 2096269024Semaste#endif 2097269024Semaste{ 2098269024Semaste int nfds; 2099269024Semaste#ifdef USE_KQUEUE 2100269024Semaste#define KEV_SIZE 4 2101269024Semaste struct kevent kev[KEV_SIZE]; 2102269024Semaste int i; 2103269024Semaste#else 2104269024Semaste struct timeval timeout; 2105269024Semaste fd_set readfds; 2106269024Semaste Job *job; 2107269024Semaste#endif 2108269024Semaste 2109269024Semaste fflush(stdout); 2110269024Semaste 2111269024Semaste if (usePipes) { 2112269024Semaste#ifdef USE_KQUEUE 2113269024Semaste if ((nfds = kevent(kqfd, NULL, 0, kev, KEV_SIZE, NULL)) == -1) { 2114269024Semaste if (errno != EINTR) 2115269024Semaste Punt("kevent: %s", strerror(errno)); 2116269024Semaste if (interrupted) 2117269024Semaste JobPassSig(interrupted); 2118269024Semaste } else { 2119269024Semaste for (i = 0; i < nfds; i++) { 2120269024Semaste if (kev[i].flags & EV_ERROR) { 2121269024Semaste warnc(kev[i].data, "kevent"); 2122269024Semaste continue; 2123269024Semaste } 2124269024Semaste switch (kev[i].filter) { 2125269024Semaste case EVFILT_READ: 2126269024Semaste JobDoOutput(kev[i].udata, FALSE); 2127269024Semaste break; 2128269024Semaste case EVFILT_PROC: 2129269024Semaste /* 2130269024Semaste * Just wake up and let 2131269024Semaste * Job_CatchChildren() collect the 2132269024Semaste * terminated job. 2133269024Semaste */ 2134269024Semaste break; 2135269024Semaste } 2136269024Semaste } 2137269024Semaste } 2138269024Semaste#else 2139269024Semaste readfds = outputs; 2140269024Semaste timeout.tv_sec = SEL_SEC; 2141269024Semaste timeout.tv_usec = SEL_USEC; 2142269024Semaste if (flag && jobFull && fifoFd >= 0) 2143269024Semaste FD_SET(fifoFd, &readfds); 2144269024Semaste 2145269024Semaste nfds = select(FD_SETSIZE, &readfds, (fd_set *)NULL, 2146269024Semaste (fd_set *)NULL, &timeout); 2147269024Semaste if (nfds <= 0) { 2148269024Semaste if (interrupted) 2149269024Semaste JobPassSig(interrupted); 2150269024Semaste return; 2151269024Semaste } 2152269024Semaste if (fifoFd >= 0 && FD_ISSET(fifoFd, &readfds)) { 2153269024Semaste if (--nfds <= 0) 2154269024Semaste return; 2155269024Semaste } 2156269024Semaste job = TAILQ_FIRST(&jobs); 2157269024Semaste while (nfds != 0 && job != NULL) { 2158269024Semaste if (FD_ISSET(job->inPipe, &readfds)) { 2159269024Semaste JobDoOutput(job, FALSE); 2160269024Semaste nfds--; 2161269024Semaste } 2162269024Semaste job = TAILQ_NEXT(job, link); 2163269024Semaste } 2164269024Semaste#endif /* !USE_KQUEUE */ 2165269024Semaste } 2166269024Semaste} 2167269024Semaste 2168269024Semaste/** 2169269024Semaste * Job_Make 2170269024Semaste * Start the creation of a target. Basically a front-end for 2171269024Semaste * JobStart used by the Make module. 2172269024Semaste * 2173269024Semaste * Side Effects: 2174269024Semaste * Another job is started. 2175269024Semaste */ 2176269024Semastevoid 2177269024SemasteJob_Make(GNode *gn) 2178269024Semaste{ 2179269024Semaste 2180269024Semaste JobStart(gn, 0, NULL); 2181269024Semaste} 2182269024Semaste 2183269024Semaste/** 2184269024Semaste * JobCopyShell 2185269024Semaste * Make a new copy of the shell structure including a copy of the strings 2186269024Semaste * in it. This also defaults some fields in case they are NULL. 2187269024Semaste * 2188269024Semaste * Returns: 2189269024Semaste * The function returns a pointer to the new shell structure. 2190269024Semaste */ 2191static struct Shell * 2192JobCopyShell(const struct Shell *osh) 2193{ 2194 struct Shell *nsh; 2195 2196 nsh = emalloc(sizeof(*nsh)); 2197 nsh->name = estrdup(osh->name); 2198 2199 if (osh->echoOff != NULL) 2200 nsh->echoOff = estrdup(osh->echoOff); 2201 else 2202 nsh->echoOff = NULL; 2203 if (osh->echoOn != NULL) 2204 nsh->echoOn = estrdup(osh->echoOn); 2205 else 2206 nsh->echoOn = NULL; 2207 nsh->hasEchoCtl = osh->hasEchoCtl; 2208 2209 if (osh->noPrint != NULL) 2210 nsh->noPrint = estrdup(osh->noPrint); 2211 else 2212 nsh->noPrint = NULL; 2213 nsh->noPLen = osh->noPLen; 2214 2215 nsh->hasErrCtl = osh->hasErrCtl; 2216 if (osh->errCheck == NULL) 2217 nsh->errCheck = estrdup(""); 2218 else 2219 nsh->errCheck = estrdup(osh->errCheck); 2220 if (osh->ignErr == NULL) 2221 nsh->ignErr = estrdup("%s"); 2222 else 2223 nsh->ignErr = estrdup(osh->ignErr); 2224 2225 if (osh->echo == NULL) 2226 nsh->echo = estrdup(""); 2227 else 2228 nsh->echo = estrdup(osh->echo); 2229 2230 if (osh->exit == NULL) 2231 nsh->exit = estrdup(""); 2232 else 2233 nsh->exit = estrdup(osh->exit); 2234 2235 return (nsh); 2236} 2237 2238/** 2239 * JobFreeShell 2240 * Free a shell structure and all associated strings. 2241 */ 2242static void 2243JobFreeShell(struct Shell *sh) 2244{ 2245 2246 if (sh != NULL) { 2247 free(sh->name); 2248 free(sh->echoOff); 2249 free(sh->echoOn); 2250 free(sh->noPrint); 2251 free(sh->errCheck); 2252 free(sh->ignErr); 2253 free(sh->echo); 2254 free(sh->exit); 2255 free(sh); 2256 } 2257} 2258 2259void 2260Shell_Init(void) 2261{ 2262 2263 if (commandShell == NULL) 2264 commandShell = JobMatchShell(shells[DEFSHELL].name); 2265 2266 if (shellPath == NULL) { 2267 /* 2268 * The user didn't specify a shell to use, so we are using the 2269 * default one... Both the absolute path and the last component 2270 * must be set. The last component is taken from the 'name' 2271 * field of the default shell description pointed-to by 2272 * commandShell. All default shells are located in 2273 * PATH_DEFSHELLDIR. 2274 */ 2275 shellName = commandShell->name; 2276 shellPath = str_concat(PATH_DEFSHELLDIR, shellName, 2277 STR_ADDSLASH); 2278 } 2279} 2280 2281/** 2282 * Job_Init 2283 * Initialize the process module, given a maximum number of jobs. 2284 * 2285 * Side Effects: 2286 * lists and counters are initialized 2287 */ 2288void 2289Job_Init(int maxproc) 2290{ 2291 GNode *begin; /* node for commands to do at the very start */ 2292 const char *env; 2293 struct sigaction sa; 2294 2295 fifoFd = -1; 2296 env = getenv("MAKE_JOBS_FIFO"); 2297 2298 if (env == NULL && maxproc > 1) { 2299 /* 2300 * We did not find the environment variable so we are the 2301 * leader. Create the fifo, open it, write one char per 2302 * allowed job into the pipe. 2303 */ 2304 mktemp(fifoName); 2305 if (!mkfifo(fifoName, 0600)) { 2306 fifoFd = open(fifoName, O_RDWR | O_NONBLOCK, 0); 2307 if (fifoFd >= 0) { 2308 fifoMaster = 1; 2309 fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2310 env = fifoName; 2311 setenv("MAKE_JOBS_FIFO", env, 1); 2312 while (maxproc-- > 0) { 2313 write(fifoFd, "+", 1); 2314 } 2315 /* The master make does not get a magic token */ 2316 jobFull = TRUE; 2317 maxJobs = 0; 2318 } else { 2319 unlink(fifoName); 2320 env = NULL; 2321 } 2322 } 2323 2324 } else if (env != NULL) { 2325 /* 2326 * We had the environment variable so we are a slave. 2327 * Open fifo and give ourselves a magic token which represents 2328 * the token our parent make has grabbed to start his make 2329 * process. Otherwise the sub-makes would gobble up tokens and 2330 * the proper number of tokens to specify to -j would depend 2331 * on the depth of the tree and the order of execution. 2332 */ 2333 fifoFd = open(env, O_RDWR, 0); 2334 if (fifoFd >= 0) { 2335 fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2336 maxJobs = 1; 2337 jobFull = FALSE; 2338 } 2339 } 2340 if (fifoFd <= 0) { 2341 maxJobs = maxproc; 2342 jobFull = FALSE; 2343 } else { 2344 } 2345 nJobs = 0; 2346 2347 aborting = 0; 2348 errors = 0; 2349 2350 lastNode = NULL; 2351 2352 if ((maxJobs == 1 && fifoFd < 0) || beVerbose == 0) { 2353 /* 2354 * If only one job can run at a time, there's no need for a 2355 * banner, no is there? 2356 */ 2357 targFmt = ""; 2358 } else { 2359 targFmt = TARG_FMT; 2360 } 2361 2362 Shell_Init(); 2363 2364 /* 2365 * Catch the four signals that POSIX specifies if they aren't ignored. 2366 * JobCatchSignal will just set global variables and hope someone 2367 * else is going to handle the interrupt. 2368 */ 2369 sa.sa_handler = JobCatchSig; 2370 sigemptyset(&sa.sa_mask); 2371 sa.sa_flags = 0; 2372 2373 if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 2374 sigaction(SIGINT, &sa, NULL); 2375 } 2376 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { 2377 sigaction(SIGHUP, &sa, NULL); 2378 } 2379 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { 2380 sigaction(SIGQUIT, &sa, NULL); 2381 } 2382 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { 2383 sigaction(SIGTERM, &sa, NULL); 2384 } 2385 /* 2386 * There are additional signals that need to be caught and passed if 2387 * either the export system wants to be told directly of signals or if 2388 * we're giving each job its own process group (since then it won't get 2389 * signals from the terminal driver as we own the terminal) 2390 */ 2391#if defined(USE_PGRP) 2392 if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { 2393 sigaction(SIGTSTP, &sa, NULL); 2394 } 2395 if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) { 2396 sigaction(SIGTTOU, &sa, NULL); 2397 } 2398 if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) { 2399 sigaction(SIGTTIN, &sa, NULL); 2400 } 2401 if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) { 2402 sigaction(SIGWINCH, &sa, NULL); 2403 } 2404#endif 2405 2406#ifdef USE_KQUEUE 2407 if ((kqfd = kqueue()) == -1) { 2408 Punt("kqueue: %s", strerror(errno)); 2409 } 2410#endif 2411 2412 begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); 2413 2414 if (begin != NULL) { 2415 JobStart(begin, JOB_SPECIAL, (Job *)NULL); 2416 while (nJobs) { 2417 Job_CatchOutput(0); 2418 Job_CatchChildren(!usePipes); 2419 } 2420 } 2421 postCommands = Targ_FindNode(".END", TARG_CREATE); 2422} 2423 2424/** 2425 * Job_Full 2426 * See if the job table is full. It is considered full if it is OR 2427 * if we are in the process of aborting OR if we have 2428 * reached/exceeded our local quota. This prevents any more jobs 2429 * from starting up. 2430 * 2431 * Results: 2432 * TRUE if the job table is full, FALSE otherwise 2433 */ 2434Boolean 2435Job_Full(void) 2436{ 2437 char c; 2438 int i; 2439 2440 if (aborting) 2441 return (aborting); 2442 if (fifoFd >= 0 && jobFull) { 2443 i = read(fifoFd, &c, 1); 2444 if (i > 0) { 2445 maxJobs++; 2446 jobFull = FALSE; 2447 } 2448 } 2449 return (jobFull); 2450} 2451 2452/** 2453 * Job_Empty 2454 * See if the job table is empty. Because the local concurrency may 2455 * be set to 0, it is possible for the job table to become empty, 2456 * while the list of stoppedJobs remains non-empty. In such a case, 2457 * we want to restart as many jobs as we can. 2458 * 2459 * Results: 2460 * TRUE if it is. FALSE if it ain't. 2461 */ 2462Boolean 2463Job_Empty(void) 2464{ 2465 if (nJobs == 0) { 2466 if (!TAILQ_EMPTY(&stoppedJobs) && !aborting) { 2467 /* 2468 * The job table is obviously not full if it has no 2469 * jobs in it...Try and restart the stopped jobs. 2470 */ 2471 jobFull = FALSE; 2472 JobRestartJobs(); 2473 return (FALSE); 2474 } else { 2475 return (TRUE); 2476 } 2477 } else { 2478 return (FALSE); 2479 } 2480} 2481 2482/** 2483 * JobMatchShell 2484 * Find a matching shell in 'shells' given its final component. 2485 * 2486 * Results: 2487 * A pointer to a freshly allocated Shell structure with a copy 2488 * of the static structure or NULL if no shell with the given name 2489 * is found. 2490 */ 2491static struct Shell * 2492JobMatchShell(const char *name) 2493{ 2494 const struct CShell *sh; /* Pointer into shells table */ 2495 struct Shell *nsh; 2496 2497 for (sh = shells; sh < shells + sizeof(shells)/sizeof(shells[0]); sh++) 2498 if (strcmp(sh->name, name) == 0) 2499 break; 2500 2501 if (sh == shells + sizeof(shells)/sizeof(shells[0])) 2502 return (NULL); 2503 2504 /* make a copy */ 2505 nsh = emalloc(sizeof(*nsh)); 2506 2507 nsh->name = estrdup(sh->name); 2508 nsh->echoOff = estrdup(sh->echoOff); 2509 nsh->echoOn = estrdup(sh->echoOn); 2510 nsh->hasEchoCtl = sh->hasEchoCtl; 2511 nsh->noPrint = estrdup(sh->noPrint); 2512 nsh->noPLen = sh->noPLen; 2513 nsh->hasErrCtl = sh->hasErrCtl; 2514 nsh->errCheck = estrdup(sh->errCheck); 2515 nsh->ignErr = estrdup(sh->ignErr); 2516 nsh->echo = estrdup(sh->echo); 2517 nsh->exit = estrdup(sh->exit); 2518 2519 return (nsh); 2520} 2521 2522/** 2523 * Job_ParseShell 2524 * Parse a shell specification and set up commandShell, shellPath 2525 * and shellName appropriately. 2526 * 2527 * Results: 2528 * FAILURE if the specification was incorrect. 2529 * 2530 * Side Effects: 2531 * commandShell points to a Shell structure (either predefined or 2532 * created from the shell spec), shellPath is the full path of the 2533 * shell described by commandShell, while shellName is just the 2534 * final component of shellPath. 2535 * 2536 * Notes: 2537 * A shell specification consists of a .SHELL target, with dependency 2538 * operator, followed by a series of blank-separated words. Double 2539 * quotes can be used to use blanks in words. A backslash escapes 2540 * anything (most notably a double-quote and a space) and 2541 * provides the functionality it does in C. Each word consists of 2542 * keyword and value separated by an equal sign. There should be no 2543 * unnecessary spaces in the word. The keywords are as follows: 2544 * name Name of shell. 2545 * path Location of shell. Overrides "name" if given 2546 * quiet Command to turn off echoing. 2547 * echo Command to turn echoing on 2548 * filter Result of turning off echoing that shouldn't be 2549 * printed. 2550 * echoFlag Flag to turn echoing on at the start 2551 * errFlag Flag to turn error checking on at the start 2552 * hasErrCtl True if shell has error checking control 2553 * check Command to turn on error checking if hasErrCtl 2554 * is TRUE or template of command to echo a command 2555 * for which error checking is off if hasErrCtl is 2556 * FALSE. 2557 * ignore Command to turn off error checking if hasErrCtl 2558 * is TRUE or template of command to execute a 2559 * command so as to ignore any errors it returns if 2560 * hasErrCtl is FALSE. 2561 */ 2562ReturnStatus 2563Job_ParseShell(char *line) 2564{ 2565 char **words; 2566 int wordCount; 2567 char **argv; 2568 int argc; 2569 char *path; 2570 Boolean fullSpec = FALSE; 2571 struct Shell newShell; 2572 struct Shell *sh; 2573 2574 while (isspace((unsigned char)*line)) { 2575 line++; 2576 } 2577 words = brk_string(line, &wordCount, TRUE); 2578 2579 memset(&newShell, 0, sizeof(newShell)); 2580 2581 /* 2582 * Parse the specification by keyword 2583 */ 2584 for (path = NULL, argc = wordCount - 1, argv = words + 1; argc != 0; 2585 argc--, argv++) { 2586 if (strncmp(*argv, "path=", 5) == 0) { 2587 path = &argv[0][5]; 2588 } else if (strncmp(*argv, "name=", 5) == 0) { 2589 newShell.name = &argv[0][5]; 2590 } else { 2591 if (strncmp(*argv, "quiet=", 6) == 0) { 2592 newShell.echoOff = &argv[0][6]; 2593 } else if (strncmp(*argv, "echo=", 5) == 0) { 2594 newShell.echoOn = &argv[0][5]; 2595 } else if (strncmp(*argv, "filter=", 7) == 0) { 2596 newShell.noPrint = &argv[0][7]; 2597 newShell.noPLen = strlen(newShell.noPrint); 2598 } else if (strncmp(*argv, "echoFlag=", 9) == 0) { 2599 newShell.echo = &argv[0][9]; 2600 } else if (strncmp(*argv, "errFlag=", 8) == 0) { 2601 newShell.exit = &argv[0][8]; 2602 } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) { 2603 char c = argv[0][10]; 2604 newShell.hasErrCtl = !((c != 'Y') && 2605 (c != 'y') && (c != 'T') && (c != 't')); 2606 } else if (strncmp(*argv, "check=", 6) == 0) { 2607 newShell.errCheck = &argv[0][6]; 2608 } else if (strncmp(*argv, "ignore=", 7) == 0) { 2609 newShell.ignErr = &argv[0][7]; 2610 } else { 2611 Parse_Error(PARSE_FATAL, 2612 "Unknown keyword \"%s\"", *argv); 2613 return (FAILURE); 2614 } 2615 fullSpec = TRUE; 2616 } 2617 } 2618 2619 /* 2620 * Some checks (could be more) 2621 */ 2622 if (fullSpec) { 2623 if ((newShell.echoOn != NULL) ^ (newShell.echoOff != NULL)) 2624 Parse_Error(PARSE_FATAL, "Shell must have either both " 2625 "echoOff and echoOn or none of them"); 2626 2627 if (newShell.echoOn != NULL && newShell.echoOff) 2628 newShell.hasEchoCtl = TRUE; 2629 } 2630 2631 if (path == NULL) { 2632 /* 2633 * If no path was given, the user wants one of the pre-defined 2634 * shells, yes? So we find the one s/he wants with the help of 2635 * JobMatchShell and set things up the right way. shellPath 2636 * will be set up by Job_Init. 2637 */ 2638 if (newShell.name == NULL) { 2639 Parse_Error(PARSE_FATAL, 2640 "Neither path nor name specified"); 2641 return (FAILURE); 2642 } 2643 if ((sh = JobMatchShell(newShell.name)) == NULL) { 2644 Parse_Error(PARSE_FATAL, "%s: no matching shell", 2645 newShell.name); 2646 return (FAILURE); 2647 } 2648 2649 } else { 2650 /* 2651 * The user provided a path. If s/he gave nothing else 2652 * (fullSpec is FALSE), try and find a matching shell in the 2653 * ones we know of. Else we just take the specification at its 2654 * word and copy it to a new location. In either case, we need 2655 * to record the path the user gave for the shell. 2656 */ 2657 free(shellPath); 2658 shellPath = estrdup(path); 2659 if (newShell.name == NULL) { 2660 /* get the base name as the name */ 2661 path = strrchr(path, '/'); 2662 if (path == NULL) { 2663 path = shellPath; 2664 } else { 2665 path += 1; 2666 } 2667 newShell.name = path; 2668 } 2669 2670 if (!fullSpec) { 2671 if ((sh = JobMatchShell(newShell.name)) == NULL) { 2672 Parse_Error(PARSE_FATAL, 2673 "%s: no matching shell", newShell.name); 2674 return (FAILURE); 2675 } 2676 } else { 2677 sh = JobCopyShell(&newShell); 2678 } 2679 } 2680 2681 /* set the new shell */ 2682 JobFreeShell(commandShell); 2683 commandShell = sh; 2684 2685 shellName = commandShell->name; 2686 2687 return (SUCCESS); 2688} 2689 2690/** 2691 * JobInterrupt 2692 * Handle the receipt of an interrupt. 2693 * 2694 * Side Effects: 2695 * All children are killed. Another job will be started if the 2696 * .INTERRUPT target was given. 2697 */ 2698static void 2699JobInterrupt(int runINTERRUPT, int signo) 2700{ 2701 Job *job; /* job descriptor in that element */ 2702 GNode *interrupt; /* the node describing the .INTERRUPT target */ 2703 2704 aborting = ABORT_INTERRUPT; 2705 2706 TAILQ_FOREACH(job, &jobs, link) { 2707 if (!Targ_Precious(job->node)) { 2708 char *file = (job->node->path == NULL ? 2709 job->node->name : job->node->path); 2710 2711 if (!noExecute && eunlink(file) != -1) { 2712 Error("*** %s removed", file); 2713 } 2714 } 2715 if (job->pid) { 2716 DEBUGF(JOB, ("JobInterrupt passing signal to child " 2717 "%jd.\n", (intmax_t)job->pid)); 2718 KILL(job->pid, signo); 2719 } 2720 } 2721 2722 if (runINTERRUPT && !touchFlag) { 2723 /* 2724 * clear the interrupted flag because we would get an 2725 * infinite loop otherwise. 2726 */ 2727 interrupted = 0; 2728 2729 interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 2730 if (interrupt != NULL) { 2731 ignoreErrors = FALSE; 2732 2733 JobStart(interrupt, JOB_IGNDOTS, (Job *)NULL); 2734 while (nJobs) { 2735 Job_CatchOutput(0); 2736 Job_CatchChildren(!usePipes); 2737 } 2738 } 2739 } 2740} 2741 2742/** 2743 * Job_Finish 2744 * Do final processing such as the running of the commands 2745 * attached to the .END target. 2746 * 2747 * Results: 2748 * Number of errors reported. 2749 */ 2750int 2751Job_Finish(void) 2752{ 2753 2754 if (postCommands != NULL && !Lst_IsEmpty(&postCommands->commands)) { 2755 if (errors) { 2756 Error("Errors reported so .END ignored"); 2757 } else { 2758 JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL); 2759 2760 while (nJobs) { 2761 Job_CatchOutput(0); 2762 Job_CatchChildren(!usePipes); 2763 } 2764 } 2765 } 2766 if (fifoFd >= 0) { 2767 close(fifoFd); 2768 fifoFd = -1; 2769 if (fifoMaster) 2770 unlink(fifoName); 2771 } 2772 return (errors); 2773} 2774 2775/** 2776 * Job_Wait 2777 * Waits for all running jobs to finish and returns. Sets 'aborting' 2778 * to ABORT_WAIT to prevent other jobs from starting. 2779 * 2780 * Side Effects: 2781 * Currently running jobs finish. 2782 */ 2783void 2784Job_Wait(void) 2785{ 2786 2787 aborting = ABORT_WAIT; 2788 while (nJobs != 0) { 2789 Job_CatchOutput(0); 2790 Job_CatchChildren(!usePipes); 2791 } 2792 aborting = 0; 2793} 2794 2795/** 2796 * Job_AbortAll 2797 * Abort all currently running jobs without handling output or anything. 2798 * This function is to be called only in the event of a major 2799 * error. Most definitely NOT to be called from JobInterrupt. 2800 * 2801 * Side Effects: 2802 * All children are killed, not just the firstborn 2803 */ 2804void 2805Job_AbortAll(void) 2806{ 2807 Job *job; /* the job descriptor in that element */ 2808 int foo; 2809 2810 aborting = ABORT_ERROR; 2811 2812 if (nJobs) { 2813 TAILQ_FOREACH(job, &jobs, link) { 2814 /* 2815 * kill the child process with increasingly drastic 2816 * signals to make darn sure it's dead. 2817 */ 2818 KILL(job->pid, SIGINT); 2819 KILL(job->pid, SIGKILL); 2820 } 2821 } 2822 2823 /* 2824 * Catch as many children as want to report in at first, then give up 2825 */ 2826 while (waitpid((pid_t)-1, &foo, WNOHANG) > 0) 2827 ; 2828} 2829 2830/** 2831 * JobRestartJobs 2832 * Tries to restart stopped jobs if there are slots available. 2833 * Note that this tries to restart them regardless of pending errors. 2834 * It's not good to leave stopped jobs lying around! 2835 * 2836 * Side Effects: 2837 * Resumes(and possibly migrates) jobs. 2838 */ 2839static void 2840JobRestartJobs(void) 2841{ 2842 Job *job; 2843 2844 while (!jobFull && (job = TAILQ_FIRST(&stoppedJobs)) != NULL) { 2845 DEBUGF(JOB, ("Job queue is not full. " 2846 "Restarting a stopped job.\n")); 2847 TAILQ_REMOVE(&stoppedJobs, job, link); 2848 JobRestart(job); 2849 } 2850} 2851