job.c revision 144741
1141104Sharti/*- 294589Sobrien * Copyright (c) 1988, 1989, 1990, 1993 394589Sobrien * The Regents of the University of California. All rights reserved. 45814Sjkh * Copyright (c) 1988, 1989 by Adam de Boor 51590Srgrimes * Copyright (c) 1989 by Berkeley Softworks 61590Srgrimes * All rights reserved. 71590Srgrimes * 81590Srgrimes * This code is derived from software contributed to Berkeley by 91590Srgrimes * Adam de Boor. 101590Srgrimes * 111590Srgrimes * Redistribution and use in source and binary forms, with or without 121590Srgrimes * modification, are permitted provided that the following conditions 131590Srgrimes * are met: 141590Srgrimes * 1. Redistributions of source code must retain the above copyright 151590Srgrimes * notice, this list of conditions and the following disclaimer. 161590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171590Srgrimes * notice, this list of conditions and the following disclaimer in the 181590Srgrimes * documentation and/or other materials provided with the distribution. 191590Srgrimes * 3. All advertising materials mentioning features or use of this software 201590Srgrimes * must display the following acknowledgement: 211590Srgrimes * This product includes software developed by the University of 221590Srgrimes * California, Berkeley and its contributors. 231590Srgrimes * 4. Neither the name of the University nor the names of its contributors 241590Srgrimes * may be used to endorse or promote products derived from this software 251590Srgrimes * without specific prior written permission. 261590Srgrimes * 271590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 281590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 291590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 301590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 311590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 321590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 331590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 341590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 351590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 361590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 371590Srgrimes * SUCH DAMAGE. 3862833Swsanchez * 3962833Swsanchez * @(#)job.c 8.2 (Berkeley) 3/19/94 401590Srgrimes */ 411590Srgrimes 4262833Swsanchez#include <sys/cdefs.h> 4394587Sobrien__FBSDID("$FreeBSD: head/usr.bin/make/job.c 144741 2005-04-07 11:26:15Z harti $"); 441590Srgrimes 4535483Simp#ifndef OLD_JOKE 46103503Sjmallett#define OLD_JOKE 0 4735483Simp#endif /* OLD_JOKE */ 4835483Simp 491590Srgrimes/*- 501590Srgrimes * job.c -- 511590Srgrimes * handle the creation etc. of our child processes. 521590Srgrimes * 531590Srgrimes * Interface: 54144467Sharti * Job_Make Start the creation of the given target. 551590Srgrimes * 56144467Sharti * Job_CatchChildren 57144467Sharti * Check for and handle the termination of any children. 58144467Sharti * This must be called reasonably frequently to keep the 59144467Sharti * whole make going at a decent clip, since job table 60144467Sharti * entries aren't removed until their process is caught 61144467Sharti * this way. Its single argument is TRUE if the function 62144467Sharti * should block waiting for a child to terminate. 631590Srgrimes * 64144467Sharti * Job_CatchOutput Print any output our children have produced. Should 65144467Sharti * also be called fairly frequently to keep the user 66144467Sharti * informed of what's going on. If no output is waiting, 67144467Sharti * it will block for a time given by the SEL_* constants, 68144467Sharti * below, or until output is ready. 691590Srgrimes * 70144467Sharti * Job_Init Called to intialize this module. in addition, any 71144467Sharti * commands attached to the .BEGIN target are executed 72144467Sharti * before this function returns. Hence, the makefile must 73144467Sharti * have been parsed before this function is called. 741590Srgrimes * 75144467Sharti * Job_Full Return TRUE if the job table is filled. 761590Srgrimes * 77144467Sharti * Job_Empty Return TRUE if the job table is completely empty. 781590Srgrimes * 79144467Sharti * Job_ParseShell Given the line following a .SHELL target, parse the 80144467Sharti * line as a shell specification. Returns FAILURE if the 81144467Sharti * spec was incorrect. 821590Srgrimes * 83144467Sharti * Job_Finish Perform any final processing which needs doing. This 84144467Sharti * includes the execution of any commands which have 85144467Sharti * been/were attached to the .END target. It should only 86144467Sharti * be called when the job table is empty. 871590Srgrimes * 88144467Sharti * Job_AbortAll Abort all currently running jobs. It doesn't handle 89144467Sharti * output or do anything for the jobs, just kills them. 90144467Sharti * It should only be called in an emergency, as it were. 911590Srgrimes * 92144467Sharti * Job_CheckCommands 93144467Sharti * Verify that the commands for a target are ok. Provide 94144467Sharti * them if necessary and possible. 951590Srgrimes * 96144467Sharti * Job_Touch Update a target without really updating it. 971590Srgrimes * 98144467Sharti * Job_Wait Wait for all currently-running jobs to finish. 991590Srgrimes */ 1001590Srgrimes 101144494Sharti#include <sys/queue.h> 1021590Srgrimes#include <sys/types.h> 103141104Sharti#include <sys/select.h> 1041590Srgrimes#include <sys/stat.h> 105107447Sru#ifdef USE_KQUEUE 106104475Sphk#include <sys/event.h> 107107447Sru#endif 1081590Srgrimes#include <sys/wait.h> 109141104Sharti#include <ctype.h> 11094506Scharnier#include <errno.h> 1115814Sjkh#include <fcntl.h> 112144665Sharti#include <inttypes.h> 1131590Srgrimes#include <string.h> 1145814Sjkh#include <signal.h> 115141104Sharti#include <stdlib.h> 11680381Ssheldonh#include <unistd.h> 11794506Scharnier#include <utime.h> 118141104Sharti 119141104Sharti#include "arch.h" 120142457Sharti#include "buf.h" 121141104Sharti#include "compat.h" 1221590Srgrimes#include "dir.h" 123141104Sharti#include "globals.h" 124141104Sharti#include "GNode.h" 1251590Srgrimes#include "job.h" 126141104Sharti#include "make.h" 127141104Sharti#include "parse.h" 1281590Srgrimes#include "pathnames.h" 129141104Sharti#include "str.h" 130141104Sharti#include "targ.h" 131141104Sharti#include "util.h" 132141104Sharti#include "var.h" 1331590Srgrimes 1341590Srgrimes/* 135144483Sharti * Job Table definitions. 136144483Sharti * 137144483Sharti * The job "table" is kept as a linked Lst in 'jobs', with the number of 138144483Sharti * active jobs maintained in the 'nJobs' variable. At no time will this 139144483Sharti * exceed the value of 'maxJobs', initialized by the Job_Init function. 140144483Sharti * 141144483Sharti * When a job is finished, the Make_Update function is called on each of the 142144483Sharti * parents of the node which was just remade. This takes care of the upward 143144483Sharti * traversal of the dependency graph. 144144483Sharti */ 145144483Sharti#define JOB_BUFSIZE 1024 146144483Shartitypedef struct Job { 147144665Sharti pid_t pid; /* The child's process ID */ 148144483Sharti 149144483Sharti struct GNode *node; /* The target the child is making */ 150144483Sharti 151144483Sharti /* 152144483Sharti * A LstNode for the first command to be saved after the job completes. 153144483Sharti * This is NULL if there was no "..." in the job's commands. 154144483Sharti */ 155144483Sharti LstNode *tailCmds; 156144483Sharti 157144483Sharti /* 158144483Sharti * An FILE* for writing out the commands. This is only 159144483Sharti * used before the job is actually started. 160144483Sharti */ 161144483Sharti FILE *cmdFILE; 162144483Sharti 163144483Sharti /* 164144483Sharti * A word of flags which determine how the module handles errors, 165144483Sharti * echoing, etc. for the job 166144483Sharti */ 167144483Sharti short flags; /* Flags to control treatment of job */ 168144483Sharti#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ 169144483Sharti#define JOB_SILENT 0x002 /* no output */ 170144483Sharti#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally 171144483Sharti * if we can't export it and maxLocal is 0 */ 172144483Sharti#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing 173144483Sharti * commands */ 174144483Sharti#define JOB_FIRST 0x020 /* Job is first job for the node */ 175144483Sharti#define JOB_RESTART 0x080 /* Job needs to be completely restarted */ 176144483Sharti#define JOB_RESUME 0x100 /* Job needs to be resumed b/c it stopped, 177144483Sharti * for some reason */ 178144483Sharti#define JOB_CONTINUING 0x200 /* We are in the process of resuming this job. 179144483Sharti * Used to avoid infinite recursion between 180144483Sharti * JobFinish and JobRestart */ 181144483Sharti 182144483Sharti /* union for handling shell's output */ 183144483Sharti union { 184144483Sharti /* 185144483Sharti * This part is used when usePipes is true. 186144483Sharti * The output is being caught via a pipe and the descriptors 187144483Sharti * of our pipe, an array in which output is line buffered and 188144483Sharti * the current position in that buffer are all maintained for 189144483Sharti * each job. 190144483Sharti */ 191144483Sharti struct { 192144483Sharti /* 193144483Sharti * Input side of pipe associated with 194144483Sharti * job's output channel 195144483Sharti */ 196144483Sharti int op_inPipe; 197144483Sharti 198144483Sharti /* 199144483Sharti * Output side of pipe associated with job's 200144483Sharti * output channel 201144483Sharti */ 202144483Sharti int op_outPipe; 203144483Sharti 204144483Sharti /* 205144483Sharti * Buffer for storing the output of the 206144483Sharti * job, line by line 207144483Sharti */ 208144483Sharti char op_outBuf[JOB_BUFSIZE + 1]; 209144483Sharti 210144483Sharti /* Current position in op_outBuf */ 211144483Sharti int op_curPos; 212144483Sharti } o_pipe; 213144483Sharti 214144483Sharti /* 215144483Sharti * If usePipes is false the output is routed to a temporary 216144483Sharti * file and all that is kept is the name of the file and the 217144483Sharti * descriptor open to the file. 218144483Sharti */ 219144483Sharti struct { 220144483Sharti /* Name of file to which shell output was rerouted */ 221144483Sharti char of_outFile[sizeof(TMPPAT)]; 222144483Sharti 223144483Sharti /* 224144483Sharti * Stream open to the output file. Used to funnel all 225144483Sharti * from a single job to one file while still allowing 226144483Sharti * multiple shell invocations 227144483Sharti */ 228144483Sharti int of_outFd; 229144483Sharti } o_file; 230144483Sharti 231144483Sharti } output; /* Data for tracking a shell's output */ 232144494Sharti 233144494Sharti TAILQ_ENTRY(Job) link; /* list link */ 234144483Sharti} Job; 235144483Sharti 236144483Sharti#define outPipe output.o_pipe.op_outPipe 237144483Sharti#define inPipe output.o_pipe.op_inPipe 238144483Sharti#define outBuf output.o_pipe.op_outBuf 239144483Sharti#define curPos output.o_pipe.op_curPos 240144483Sharti#define outFile output.o_file.of_outFile 241144483Sharti#define outFd output.o_file.of_outFd 242144483Sharti 243144494ShartiTAILQ_HEAD(JobList, Job); 244144494Sharti 245144483Sharti/* 246144483Sharti * Shell Specifications: 247144483Sharti * 248144483Sharti * Some special stuff goes on if a shell doesn't have error control. In such 249144483Sharti * a case, errCheck becomes a printf template for echoing the command, 250144483Sharti * should echoing be on and ignErr becomes another printf template for 251144483Sharti * executing the command while ignoring the return status. If either of these 252144483Sharti * strings is empty when hasErrCtl is FALSE, the command will be executed 253144483Sharti * anyway as is and if it causes an error, so be it. 254144483Sharti */ 255144483Sharti#define DEF_SHELL_STRUCT(TAG, CONST) \ 256144483Shartistruct TAG { \ 257144483Sharti /* \ 258144483Sharti * the name of the shell. For Bourne and C shells, this is used \ 259144483Sharti * only to find the shell description when used as the single \ 260144483Sharti * source of a .SHELL target. For user-defined shells, this is \ 261144483Sharti * the full path of the shell. \ 262144483Sharti */ \ 263144483Sharti CONST char *name; \ 264144483Sharti \ 265144483Sharti /* True if both echoOff and echoOn defined */ \ 266144483Sharti Boolean hasEchoCtl; \ 267144483Sharti \ 268144483Sharti CONST char *echoOff; /* command to turn off echo */ \ 269144483Sharti CONST char *echoOn; /* command to turn it back on */\ 270144483Sharti \ 271144483Sharti /* \ 272144483Sharti * What the shell prints, and its length, when given the \ 273144483Sharti * echo-off command. This line will not be printed when \ 274144483Sharti * received from the shell. This is usually the command which \ 275144483Sharti * was executed to turn off echoing \ 276144483Sharti */ \ 277144483Sharti CONST char *noPrint; \ 278144483Sharti \ 279144483Sharti /* set if can control error checking for individual commands */ \ 280144483Sharti Boolean hasErrCtl; \ 281144483Sharti \ 282144483Sharti /* string to turn error checking on */ \ 283144483Sharti CONST char *errCheck; \ 284144483Sharti \ 285144483Sharti /* string to turn off error checking */ \ 286144483Sharti CONST char *ignErr; \ 287144483Sharti \ 288144483Sharti CONST char *echo; /* command line flag: echo commands */ \ 289144483Sharti CONST char *exit; /* command line flag: exit on error */ \ 290144483Sharti} 291144483Sharti 292144483ShartiDEF_SHELL_STRUCT(Shell,); 293144483ShartiDEF_SHELL_STRUCT(CShell, const); 294144483Sharti 295144483Sharti/* 2968874Srgrimes * error handling variables 2971590Srgrimes */ 298144467Shartistatic int errors = 0; /* number of errors reported */ 299144467Shartistatic int aborting = 0; /* why is the make aborting? */ 300144467Sharti#define ABORT_ERROR 1 /* Because of an error */ 301144467Sharti#define ABORT_INTERRUPT 2 /* Because it was interrupted */ 302144467Sharti#define ABORT_WAIT 3 /* Waiting for jobs to finish */ 3031590Srgrimes 30418730Ssteve/* 30518730Ssteve * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file 30618730Ssteve * is a char! So when we go above 127 we turn negative! 30718730Ssteve */ 308138232Sharti#define FILENO(a) ((unsigned)fileno(a)) 3091590Srgrimes 3101590Srgrimes/* 3111590Srgrimes * post-make command processing. The node postCommands is really just the 3121590Srgrimes * .END target but we keep it around to avoid having to search for it 3131590Srgrimes * all the time. 3141590Srgrimes */ 315144467Shartistatic GNode *postCommands; 3161590Srgrimes 3171590Srgrimes/* 318144467Sharti * The number of commands actually printed for a target. Should this 319144467Sharti * number be 0, no shell will be executed. 320144467Sharti */ 321144467Shartistatic int numCommands; 322144467Sharti 323144467Sharti/* 3241590Srgrimes * Return values from JobStart. 3251590Srgrimes */ 326144467Sharti#define JOB_RUNNING 0 /* Job is running */ 327144467Sharti#define JOB_ERROR 1 /* Error in starting the job */ 328144467Sharti#define JOB_FINISHED 2 /* The job is already finished */ 329144467Sharti#define JOB_STOPPED 3 /* The job is stopped */ 3301590Srgrimes 3311590Srgrimes/* 3321590Srgrimes * Descriptions for various shells. 3331590Srgrimes */ 334144483Shartistatic const struct CShell shells[] = { 335144467Sharti /* 336144467Sharti * CSH description. The csh can do echo control by playing 337144467Sharti * with the setting of the 'echo' shell variable. Sadly, 338144467Sharti * however, it is unable to do error control nicely. 339144467Sharti */ 340144467Sharti { 341144467Sharti "csh", 342144741Sharti TRUE, "unset verbose", "set verbose", "unset verbose", 343144467Sharti FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"", 344144467Sharti "v", "e", 345144467Sharti }, 346144467Sharti /* 347144467Sharti * SH description. Echo control is also possible and, under 348144467Sharti * sun UNIX anyway, one can even control error checking. 349144467Sharti */ 350144467Sharti { 351144467Sharti "sh", 352144741Sharti TRUE, "set -", "set -v", "set -", 353144467Sharti TRUE, "set -e", "set +e", 35418730Ssteve#ifdef OLDBOURNESHELL 355144467Sharti FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n", 35618730Ssteve#endif 357144467Sharti "v", "e", 358144467Sharti }, 359144467Sharti /* 360144467Sharti * KSH description. The Korn shell has a superset of 361144467Sharti * the Bourne shell's functionality. 362144467Sharti */ 363144467Sharti { 364144467Sharti "ksh", 365144741Sharti TRUE, "set -", "set -v", "set -", 366144467Sharti TRUE, "set -e", "set +e", 367144467Sharti "v", "e", 368144467Sharti }, 3691590Srgrimes}; 3701590Srgrimes 371144467Sharti/* 372144467Sharti * This is the shell to which we pass all commands in the Makefile. 373144467Sharti * It is set by the Job_ParseShell function. 374144467Sharti */ 375144483Shartistatic struct Shell *commandShell = NULL; 376144467Shartichar *shellPath = NULL; /* full pathname of executable image */ 377144467Shartichar *shellName = NULL; /* last component of shell */ 3781590Srgrimes 379144467Shartiint maxJobs; /* The most children we can run at once */ 380144656Shartistatic int nJobs; /* The number of children currently running */ 381138916Sharti 382138916Sharti/* The structures that describe them */ 383144494Shartistatic struct JobList jobs = TAILQ_HEAD_INITIALIZER(jobs); 384138916Sharti 385144656Shartistatic Boolean jobFull; /* Flag to tell when the job table is full. It 3861590Srgrimes * is set TRUE when (1) the total number of 387137572Sphk * running jobs equals the maximum allowed */ 388104475Sphk#ifdef USE_KQUEUE 389104475Sphkstatic int kqfd; /* File descriptor obtained by kqueue() */ 390104475Sphk#else 3911590Srgrimesstatic fd_set outputs; /* Set of descriptors of pipes connected to 3921590Srgrimes * the output channels of children */ 3931590Srgrimes#endif 3941590Srgrimes 395144656Shartistatic GNode *lastNode; /* The node for which output was most recently 3961590Srgrimes * produced. */ 397144656Shartistatic const char *targFmt; /* Format string to use to head output from a 3981590Srgrimes * job when it's not the most-recent job heard 3991590Srgrimes * from */ 4001590Srgrimes 401137202Sharti#define TARG_FMT "--- %s ---\n" /* Default format */ 402137202Sharti#define MESSAGE(fp, gn) \ 403138232Sharti fprintf(fp, targFmt, gn->name); 40418730Ssteve 4051590Srgrimes/* 406137252Sharti * When JobStart attempts to run a job but isn't allowed to 407137252Sharti * or when Job_CatchChildren detects a job that has 408137252Sharti * been stopped somehow, the job is placed on the stoppedJobs queue to be run 4098874Srgrimes * when the next job finishes. 410138916Sharti * 411138916Sharti * Lst of Job structures describing jobs that were stopped due to 412138916Sharti * concurrency limits or externally 4131590Srgrimes */ 414144494Shartistatic struct JobList stoppedJobs = TAILQ_HEAD_INITIALIZER(stoppedJobs); 4151590Srgrimes 416144656Shartistatic int fifoFd; /* Fd of our job fifo */ 417144656Shartistatic char fifoName[] = "/tmp/make_fifo_XXXXXXXXX"; 418144656Shartistatic int fifoMaster; 4191590Srgrimes 420137605Shartistatic sig_atomic_t interrupted; 421137605Sharti 422137605Sharti 4231590Srgrimes#if defined(USE_PGRP) && defined(SYSV) 42418730Ssteve# define KILL(pid, sig) killpg(-(pid), (sig)) 4251590Srgrimes#else 4261590Srgrimes# if defined(USE_PGRP) 42718730Ssteve# define KILL(pid, sig) killpg((pid), (sig)) 4281590Srgrimes# else 42918730Ssteve# define KILL(pid, sig) kill((pid), (sig)) 4301590Srgrimes# endif 4311590Srgrimes#endif 4321590Srgrimes 43318730Ssteve/* 43418730Ssteve * Grmpf... There is no way to set bits of the wait structure 43518730Ssteve * anymore with the stupid W*() macros. I liked the union wait 43618730Ssteve * stuff much more. So, we devise our own macros... This is 43718730Ssteve * really ugly, use dramamine sparingly. You have been warned. 43818730Ssteve */ 439103503Sjmallett#define W_SETMASKED(st, val, fun) \ 44018730Ssteve { \ 441138232Sharti int sh = (int)~0; \ 44218730Ssteve int mask = fun(sh); \ 44318730Ssteve \ 44418730Ssteve for (sh = 0; ((mask >> sh) & 1) == 0; sh++) \ 44518730Ssteve continue; \ 44618730Ssteve *(st) = (*(st) & ~mask) | ((val) << sh); \ 44718730Ssteve } 44818730Ssteve 449103503Sjmallett#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG) 450103503Sjmallett#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) 45118730Ssteve 45292921Simpstatic void JobRestart(Job *); 45392921Simpstatic int JobStart(GNode *, int, Job *); 45492921Simpstatic void JobDoOutput(Job *, Boolean); 455144483Shartistatic struct Shell *JobMatchShell(const char *); 45692921Simpstatic void JobInterrupt(int, int); 45792921Simpstatic void JobRestartJobs(void); 4581590Srgrimes 459144467Sharti/** 460137605Sharti * JobCatchSignal 461144467Sharti * Got a signal. Set global variables and hope that someone will 462144467Sharti * handle it. 463137605Sharti */ 464137605Shartistatic void 465137605ShartiJobCatchSig(int signo) 466137605Sharti{ 467137605Sharti 468137605Sharti interrupted = signo; 469137605Sharti} 470137605Sharti 471144467Sharti/** 4721590Srgrimes * JobPassSig -- 473137252Sharti * Pass a signal on to all local jobs if 4741590Srgrimes * USE_PGRP is defined, then die ourselves. 4751590Srgrimes * 4761590Srgrimes * Side Effects: 4771590Srgrimes * We die by the same signal. 4781590Srgrimes */ 4791590Srgrimesstatic void 480104696SjmallettJobPassSig(int signo) 4811590Srgrimes{ 482144741Sharti Job *job; 483144467Sharti sigset_t nmask, omask; 484144467Sharti struct sigaction act; 4858874Srgrimes 486144467Sharti sigemptyset(&nmask); 487144467Sharti sigaddset(&nmask, signo); 488144467Sharti sigprocmask(SIG_SETMASK, &nmask, &omask); 489137605Sharti 490144467Sharti DEBUGF(JOB, ("JobPassSig(%d) called.\n", signo)); 491144741Sharti TAILQ_FOREACH(job, &jobs, link) { 492144741Sharti DEBUGF(JOB, ("JobPassSig passing signal %d to child %jd.\n", 493144741Sharti signo, (intmax_t)job->pid)); 494144741Sharti KILL(job->pid, signo); 495144741Sharti } 4961590Srgrimes 497144467Sharti /* 498144467Sharti * Deal with proper cleanup based on the signal received. We only run 499144467Sharti * the .INTERRUPT target if the signal was in fact an interrupt. 500144467Sharti * The other three termination signals are more of a "get out *now*" 501144467Sharti * command. 502144467Sharti */ 503144467Sharti if (signo == SIGINT) { 504144467Sharti JobInterrupt(TRUE, signo); 505144657Sharti } else if (signo == SIGHUP || signo == SIGTERM || signo == SIGQUIT) { 506144467Sharti JobInterrupt(FALSE, signo); 507144467Sharti } 5088874Srgrimes 509144467Sharti /* 510144467Sharti * Leave gracefully if SIGQUIT, rather than core dumping. 511144467Sharti */ 512144467Sharti if (signo == SIGQUIT) { 513144467Sharti signo = SIGINT; 514144467Sharti } 5158874Srgrimes 516144467Sharti /* 517144467Sharti * Send ourselves the signal now we've given the message to everyone 518144467Sharti * else. Note we block everything else possible while we're getting 519144467Sharti * the signal. This ensures that all our jobs get continued when we 520144467Sharti * wake up before we take any other signal. 521144467Sharti * XXX this comment seems wrong. 522144467Sharti */ 523144467Sharti act.sa_handler = SIG_DFL; 524144467Sharti sigemptyset(&act.sa_mask); 525144467Sharti act.sa_flags = 0; 526144467Sharti sigaction(signo, &act, NULL); 5271590Srgrimes 528144467Sharti DEBUGF(JOB, ("JobPassSig passing signal to self, mask = %x.\n", 529144467Sharti ~0 & ~(1 << (signo - 1)))); 530144467Sharti signal(signo, SIG_DFL); 5311590Srgrimes 532144467Sharti KILL(getpid(), signo); 53318730Ssteve 534144467Sharti signo = SIGCONT; 535144741Sharti TAILQ_FOREACH(job, &jobs, link) { 536144741Sharti DEBUGF(JOB, ("JobPassSig passing signal %d to child %jd.\n", 537144741Sharti signo, (intmax_t)job->pid)); 538144741Sharti KILL(job->pid, signo); 539144741Sharti } 5401590Srgrimes 541144467Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 542144467Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 543144467Sharti act.sa_handler = JobPassSig; 544144467Sharti sigaction(signo, &act, NULL); 5451590Srgrimes} 5461590Srgrimes 547144467Sharti/** 5481590Srgrimes * JobPrintCommand -- 5491590Srgrimes * Put out another command for the given job. If the command starts 5501590Srgrimes * with an @ or a - we process it specially. In the former case, 5511590Srgrimes * so long as the -s and -n flags weren't given to make, we stick 5521590Srgrimes * a shell-specific echoOff command in the script. In the latter, 5531590Srgrimes * we ignore errors for the entire job, unless the shell has error 5541590Srgrimes * control. 5551590Srgrimes * If the command is just "..." we take all future commands for this 5561590Srgrimes * job to be commands to be executed once the entire graph has been 5571590Srgrimes * made and return non-zero to signal that the end of the commands 5581590Srgrimes * was reached. These commands are later attached to the postCommands 55994594Sobrien * node and executed by Job_Finish when all things are done. 560142993Sharti * This function is called from JobStart via LST_FOREACH. 5611590Srgrimes * 5621590Srgrimes * Results: 5631590Srgrimes * Always 0, unless the command was "..." 5641590Srgrimes * 5651590Srgrimes * Side Effects: 5661590Srgrimes * If the command begins with a '-' and the shell has no error control, 5671590Srgrimes * the JOB_IGNERR flag is set in the job descriptor. 5681590Srgrimes * If the command is "..." and we're not ignoring such things, 5691590Srgrimes * tailCmds is set to the successor node of the cmd. 5701590Srgrimes * numCommands is incremented if the command is actually printed. 5711590Srgrimes */ 5721590Srgrimesstatic int 573144741ShartiJobPrintCommand(char *cmd, Job *job) 5741590Srgrimes{ 575144467Sharti Boolean noSpecials; /* true if we shouldn't worry about 576141258Sharti * inserting special commands into 577141258Sharti * the input stream. */ 578144467Sharti Boolean shutUp = FALSE; /* true if we put a no echo command 579141258Sharti * into the command file */ 580144467Sharti Boolean errOff = FALSE; /* true if we turned error checking 581141258Sharti * off before printing the command 582141258Sharti * and need to turn it back on */ 583144467Sharti const char *cmdTemplate;/* Template to use when printing the command */ 584144467Sharti char *cmdStart; /* Start of expanded command */ 585144467Sharti LstNode *cmdNode; /* Node for replacing the command */ 5861590Srgrimes 587144467Sharti noSpecials = (noExecute && !(job->node->type & OP_MAKE)); 5881590Srgrimes 589144467Sharti if (strcmp(cmd, "...") == 0) { 590144467Sharti job->node->type |= OP_SAVE_CMDS; 591144467Sharti if ((job->flags & JOB_IGNDOTS) == 0) { 592144467Sharti job->tailCmds = 593144467Sharti Lst_Succ(Lst_Member(&job->node->commands, cmd)); 594144467Sharti return (1); 595144467Sharti } 596144467Sharti return (0); 5971590Srgrimes } 5981590Srgrimes 599144467Sharti#define DBPRINTF(fmt, arg) \ 600144467Sharti DEBUGF(JOB, (fmt, arg)); \ 601144467Sharti fprintf(job->cmdFILE, fmt, arg); \ 602144467Sharti fflush(job->cmdFILE); 6031590Srgrimes 604144467Sharti numCommands += 1; 6051590Srgrimes 606144467Sharti /* 607144467Sharti * For debugging, we replace each command with the result of expanding 608144467Sharti * the variables in the command. 609144467Sharti */ 610144467Sharti cmdNode = Lst_Member(&job->node->commands, cmd); 611142457Sharti 612144467Sharti cmd = Buf_Peel(Var_Subst(NULL, cmd, job->node, FALSE)); 613144467Sharti cmdStart = cmd; 614142457Sharti 615144467Sharti Lst_Replace(cmdNode, cmdStart); 6161590Srgrimes 617144467Sharti cmdTemplate = "%s\n"; 6181590Srgrimes 619144467Sharti /* 620144467Sharti * Check for leading @', -' or +'s to control echoing, error checking, 621144467Sharti * and execution on -n. 622144467Sharti */ 623144467Sharti while (*cmd == '@' || *cmd == '-' || *cmd == '+') { 624144467Sharti switch (*cmd) { 625132839Sharti 626144467Sharti case '@': 627144467Sharti shutUp = DEBUG(LOUD) ? FALSE : TRUE; 628144467Sharti break; 629132839Sharti 630144467Sharti case '-': 631144467Sharti errOff = TRUE; 632144467Sharti break; 633132839Sharti 634144467Sharti case '+': 635144467Sharti if (noSpecials) { 636144467Sharti /* 637144467Sharti * We're not actually exececuting anything... 638144467Sharti * but this one needs to be - use compat mode 639144467Sharti * just for it. 640144467Sharti */ 641144741Sharti Compat_RunCommand(cmd, job->node); 642144467Sharti return (0); 643144467Sharti } 644144467Sharti break; 645144467Sharti } 646144467Sharti cmd++; 6471590Srgrimes } 6481590Srgrimes 649144467Sharti while (isspace((unsigned char)*cmd)) 650144467Sharti cmd++; 6511590Srgrimes 652144467Sharti if (shutUp) { 653144467Sharti if (!(job->flags & JOB_SILENT) && !noSpecials && 6541590Srgrimes commandShell->hasEchoCtl) { 65518730Ssteve DBPRINTF("%s\n", commandShell->echoOff); 6561590Srgrimes } else { 657144467Sharti shutUp = FALSE; 6581590Srgrimes } 659144467Sharti } 660144467Sharti 661144467Sharti if (errOff) { 662144467Sharti if (!(job->flags & JOB_IGNERR) && !noSpecials) { 663144467Sharti if (commandShell->hasErrCtl) { 664144467Sharti /* 665144467Sharti * We don't want the error-control commands 666144467Sharti * showing up either, so we turn off echoing 667144467Sharti * while executing them. We could put another 668144467Sharti * field in the shell structure to tell 669144467Sharti * JobDoOutput to look for this string too, 670144467Sharti * but why make it any more complex than 671144467Sharti * it already is? 672144467Sharti */ 673144467Sharti if (!(job->flags & JOB_SILENT) && !shutUp && 674144467Sharti commandShell->hasEchoCtl) { 675144467Sharti DBPRINTF("%s\n", commandShell->echoOff); 676144467Sharti DBPRINTF("%s\n", commandShell->ignErr); 677144467Sharti DBPRINTF("%s\n", commandShell->echoOn); 678144467Sharti } else { 679144467Sharti DBPRINTF("%s\n", commandShell->ignErr); 680144467Sharti } 681144467Sharti } else if (commandShell->ignErr && 682144657Sharti *commandShell->ignErr != '\0') { 683144467Sharti /* 684144467Sharti * The shell has no error control, so we need to 685144467Sharti * be weird to get it to ignore any errors from 686144467Sharti * the command. If echoing is turned on, we turn 687144467Sharti * it off and use the errCheck template to echo 688144467Sharti * the command. Leave echoing off so the user 689144467Sharti * doesn't see the weirdness we go through to 690144467Sharti * ignore errors. Set cmdTemplate to use the 691144467Sharti * weirdness instead of the simple "%s\n" 692144467Sharti * template. 693144467Sharti */ 694144467Sharti if (!(job->flags & JOB_SILENT) && !shutUp && 695144467Sharti commandShell->hasEchoCtl) { 696144467Sharti DBPRINTF("%s\n", commandShell->echoOff); 697144467Sharti DBPRINTF(commandShell->errCheck, cmd); 698144467Sharti shutUp = TRUE; 699144467Sharti } 700144467Sharti cmdTemplate = commandShell->ignErr; 701144467Sharti /* 702144467Sharti * The error ignoration (hee hee) is already 703144467Sharti * taken care of by the ignErr template, so 704144467Sharti * pretend error checking is still on. 705144467Sharti */ 706144467Sharti errOff = FALSE; 707144467Sharti } else { 708144467Sharti errOff = FALSE; 709144467Sharti } 710144467Sharti } else { 711144467Sharti errOff = FALSE; 712144467Sharti } 713144467Sharti } 714144467Sharti 715144467Sharti DBPRINTF(cmdTemplate, cmd); 716144467Sharti 717144467Sharti if (errOff) { 7181590Srgrimes /* 719144467Sharti * If echoing is already off, there's no point in issuing the 720144467Sharti * echoOff command. Otherwise we issue it and pretend it was on 721144467Sharti * for the whole command... 7221590Srgrimes */ 723144467Sharti if (!shutUp && !(job->flags & JOB_SILENT) && 7241590Srgrimes commandShell->hasEchoCtl) { 72518730Ssteve DBPRINTF("%s\n", commandShell->echoOff); 7261590Srgrimes shutUp = TRUE; 7271590Srgrimes } 728144467Sharti DBPRINTF("%s\n", commandShell->errCheck); 7291590Srgrimes } 730144467Sharti if (shutUp) { 731144467Sharti DBPRINTF("%s\n", commandShell->echoOn); 7321590Srgrimes } 733144467Sharti return (0); 7341590Srgrimes} 7351590Srgrimes 736144467Sharti/** 73718730Ssteve * JobClose -- 73818730Ssteve * Called to close both input and output pipes when a job is finished. 73918730Ssteve * 74018730Ssteve * Side Effects: 74118730Ssteve * The file descriptors associated with the job are closed. 74218730Ssteve */ 74318730Sstevestatic void 744104696SjmallettJobClose(Job *job) 74518730Ssteve{ 746138232Sharti 747144467Sharti if (usePipes) { 748137202Sharti#if !defined(USE_KQUEUE) 749144467Sharti FD_CLR(job->inPipe, &outputs); 75018730Ssteve#endif 751144467Sharti if (job->outPipe != job->inPipe) { 752144467Sharti close(job->outPipe); 753144467Sharti } 754144467Sharti JobDoOutput(job, TRUE); 755144467Sharti close(job->inPipe); 756144467Sharti } else { 757144467Sharti close(job->outFd); 758144467Sharti JobDoOutput(job, TRUE); 75918730Ssteve } 76018730Ssteve} 76118730Ssteve 762144467Sharti/** 7631590Srgrimes * JobFinish -- 7641590Srgrimes * Do final processing for the given job including updating 7651590Srgrimes * parents and starting new jobs as available/necessary. Note 7661590Srgrimes * that we pay no attention to the JOB_IGNERR flag here. 7671590Srgrimes * This is because when we're called because of a noexecute flag 7681590Srgrimes * or something, jstat.w_status is 0 and when called from 7691590Srgrimes * Job_CatchChildren, the status is zeroed if it s/b ignored. 7701590Srgrimes * 7711590Srgrimes * Side Effects: 7721590Srgrimes * Some nodes may be put on the toBeMade queue. 7731590Srgrimes * Final commands for the job are placed on postCommands. 7741590Srgrimes * 7751590Srgrimes * If we got an error and are aborting (aborting == ABORT_ERROR) and 7761590Srgrimes * the job list is now empty, we are done for the day. 7771590Srgrimes * If we recognized an error (errors !=0), we set the aborting flag 7781590Srgrimes * to ABORT_ERROR so no more jobs will be started. 7791590Srgrimes */ 7801590Srgrimesstatic void 781104696SjmallettJobFinish(Job *job, int *status) 7821590Srgrimes{ 783144467Sharti Boolean done; 784144467Sharti LstNode *ln; 7851590Srgrimes 786144657Sharti if ((WIFEXITED(*status) && WEXITSTATUS(*status) != 0 && 787144657Sharti !(job->flags & JOB_IGNERR)) || 788144657Sharti (WIFSIGNALED(*status) && WTERMSIG(*status) != SIGCONT)) { 789144467Sharti /* 790144467Sharti * If it exited non-zero and either we're doing things our 791144467Sharti * way or we're not ignoring errors, the job is finished. 792144467Sharti * Similarly, if the shell died because of a signal 793144467Sharti * the job is also finished. In these cases, finish out the 794144467Sharti * job's output before printing the exit status... 795144467Sharti */ 796144467Sharti JobClose(job); 797144467Sharti if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 798144467Sharti fclose(job->cmdFILE); 799144467Sharti } 800144467Sharti done = TRUE; 8018874Srgrimes 802144467Sharti } else if (WIFEXITED(*status)) { 803144467Sharti /* 804144467Sharti * Deal with ignored errors in -B mode. We need to print a 805144467Sharti * message telling of the ignored error as well as setting 806144467Sharti * status.w_status to 0 so the next command gets run. To do 807144467Sharti * this, we set done to be TRUE if in -B mode and the job 808144467Sharti * exited non-zero. 809144467Sharti */ 810144467Sharti done = WEXITSTATUS(*status) != 0; 8118874Srgrimes 812144467Sharti /* 813144467Sharti * Old comment said: "Note we don't want to close down any of 814144467Sharti * the streams until we know we're at the end." But we do. 815144467Sharti * Otherwise when are we going to print the rest of the stuff? 816144467Sharti */ 817144467Sharti JobClose(job); 8181590Srgrimes } else { 819144467Sharti /* 820144467Sharti * No need to close things down or anything. 821144467Sharti */ 822144467Sharti done = FALSE; 8231590Srgrimes } 8241590Srgrimes 825144467Sharti if (done || WIFSTOPPED(*status) || 826144657Sharti (WIFSIGNALED(*status) && WTERMSIG(*status) == SIGCONT) || 827144467Sharti DEBUG(JOB)) { 828144467Sharti FILE *out; 829144467Sharti 830144467Sharti if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) { 831144467Sharti /* 832144467Sharti * If output is going to a file and this job is ignoring 833144467Sharti * errors, arrange to have the exit status sent to the 834144467Sharti * output file as well. 835144467Sharti */ 836144467Sharti out = fdopen(job->outFd, "w"); 837144467Sharti if (out == NULL) 838144467Sharti Punt("Cannot fdopen"); 839144467Sharti } else { 840144467Sharti out = stdout; 8411590Srgrimes } 8421590Srgrimes 843144467Sharti if (WIFEXITED(*status)) { 844144665Sharti DEBUGF(JOB, ("Process %jd exited.\n", 845144665Sharti (intmax_t)job->pid)); 846144467Sharti if (WEXITSTATUS(*status) != 0) { 847144467Sharti if (usePipes && job->node != lastNode) { 848144467Sharti MESSAGE(out, job->node); 849144467Sharti lastNode = job->node; 850144467Sharti } 851144467Sharti fprintf(out, "*** Error code %d%s\n", 852144467Sharti WEXITSTATUS(*status), 853144467Sharti (job->flags & JOB_IGNERR) ? 854144467Sharti "(ignored)" : ""); 855144467Sharti 856144467Sharti if (job->flags & JOB_IGNERR) { 857144467Sharti *status = 0; 858144467Sharti } 859144467Sharti } else if (DEBUG(JOB)) { 860144467Sharti if (usePipes && job->node != lastNode) { 861144467Sharti MESSAGE(out, job->node); 862144467Sharti lastNode = job->node; 863144467Sharti } 864144467Sharti fprintf(out, "*** Completed successfully\n"); 865144467Sharti } 866144467Sharti 867144467Sharti } else if (WIFSTOPPED(*status)) { 868144665Sharti DEBUGF(JOB, ("Process %jd stopped.\n", 869144665Sharti (intmax_t)job->pid)); 870144467Sharti if (usePipes && job->node != lastNode) { 871144467Sharti MESSAGE(out, job->node); 872144467Sharti lastNode = job->node; 873144467Sharti } 874144467Sharti fprintf(out, "*** Stopped -- signal %d\n", 875144467Sharti WSTOPSIG(*status)); 876144467Sharti job->flags |= JOB_RESUME; 877144494Sharti TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 878144467Sharti fflush(out); 879144467Sharti return; 880144467Sharti 881144467Sharti } else if (WTERMSIG(*status) == SIGCONT) { 882144467Sharti /* 883144467Sharti * If the beastie has continued, shift the Job from 884144467Sharti * the stopped list to the running one (or re-stop it 885144467Sharti * if concurrency is exceeded) and go and get another 886144467Sharti * child. 887144467Sharti */ 888144657Sharti if (job->flags & (JOB_RESUME | JOB_RESTART)) { 889144467Sharti if (usePipes && job->node != lastNode) { 890144467Sharti MESSAGE(out, job->node); 891144467Sharti lastNode = job->node; 892144467Sharti } 893144467Sharti fprintf(out, "*** Continued\n"); 894144467Sharti } 895144467Sharti if (!(job->flags & JOB_CONTINUING)) { 896144665Sharti DEBUGF(JOB, ("Warning: process %jd was not " 897144665Sharti "continuing.\n", (intmax_t)job->pid)); 89818730Ssteve#ifdef notdef 899144467Sharti /* 900144467Sharti * We don't really want to restart a job from 901144467Sharti * scratch just because it continued, especially 902144467Sharti * not without killing the continuing process! 903144467Sharti * That's why this is ifdef'ed out. 904144467Sharti * FD - 9/17/90 905144467Sharti */ 906144467Sharti JobRestart(job); 90718730Ssteve#endif 908144467Sharti } 909144467Sharti job->flags &= ~JOB_CONTINUING; 910144494Sharti TAILQ_INSERT_TAIL(&jobs, job, link); 911144467Sharti nJobs += 1; 912144665Sharti DEBUGF(JOB, ("Process %jd is continuing locally.\n", 913144665Sharti (intmax_t)job->pid)); 914144467Sharti if (nJobs == maxJobs) { 915144467Sharti jobFull = TRUE; 916144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 917144467Sharti } 918144467Sharti fflush(out); 919144467Sharti return; 9201590Srgrimes 921144467Sharti } else { 922144467Sharti if (usePipes && job->node != lastNode) { 923144467Sharti MESSAGE(out, job->node); 924144467Sharti lastNode = job->node; 925144467Sharti } 926144467Sharti fprintf(out, "*** Signal %d\n", WTERMSIG(*status)); 927144467Sharti } 9281590Srgrimes 929144467Sharti fflush(out); 9301590Srgrimes } 9311590Srgrimes 9321590Srgrimes /* 933144467Sharti * Now handle the -B-mode stuff. If the beast still isn't finished, 934144467Sharti * try and restart the job on the next command. If JobStart says it's 935144467Sharti * ok, it's ok. If there's an error, this puppy is done. 9361590Srgrimes */ 937144467Sharti if (compatMake && WIFEXITED(*status) && 938144467Sharti Lst_Succ(job->node->compat_command) != NULL) { 939144467Sharti switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) { 940144467Sharti case JOB_RUNNING: 941144467Sharti done = FALSE; 942144467Sharti break; 943144467Sharti case JOB_ERROR: 944144467Sharti done = TRUE; 945144467Sharti W_SETEXITSTATUS(status, 1); 946144467Sharti break; 947144467Sharti case JOB_FINISHED: 948144467Sharti /* 949144467Sharti * If we got back a JOB_FINISHED code, JobStart has 950144467Sharti * already called Make_Update and freed the job 951144467Sharti * descriptor. We set done to false here to avoid fake 952144467Sharti * cycles and double frees. JobStart needs to do the 953144467Sharti * update so we can proceed up the graph when given 954144467Sharti * the -n flag.. 955144467Sharti */ 956144467Sharti done = FALSE; 957144467Sharti break; 958144467Sharti default: 959144467Sharti break; 960144467Sharti } 961144467Sharti } else { 962144467Sharti done = TRUE; 9631590Srgrimes } 964143703Sharti 965144657Sharti if (done && aborting != ABORT_ERROR && 966144657Sharti aborting != ABORT_INTERRUPT && *status == 0) { 967144467Sharti /* 968144467Sharti * As long as we aren't aborting and the job didn't return a 969144467Sharti * non-zero status that we shouldn't ignore, we call 970144467Sharti * Make_Update to update the parents. In addition, any saved 971144467Sharti * commands for the node are placed on the .END target. 972144467Sharti */ 973144467Sharti for (ln = job->tailCmds; ln != NULL; ln = LST_NEXT(ln)) { 974144467Sharti Lst_AtEnd(&postCommands->commands, 975144467Sharti Buf_Peel(Var_Subst(NULL, Lst_Datum(ln), 976144467Sharti job->node, FALSE))); 977144467Sharti } 9781590Srgrimes 979144467Sharti job->node->made = MADE; 980144467Sharti Make_Update(job->node); 981144467Sharti free(job); 9821590Srgrimes 983144467Sharti } else if (*status != 0) { 984144467Sharti errors += 1; 985144467Sharti free(job); 986144467Sharti } 987144467Sharti 988144467Sharti JobRestartJobs(); 989144467Sharti 9901590Srgrimes /* 991144467Sharti * Set aborting if any error. 9921590Srgrimes */ 993144657Sharti if (errors && !keepgoing && aborting != ABORT_INTERRUPT) { 994144467Sharti /* 995144467Sharti * If we found any errors in this batch of children and the -k 996144467Sharti * flag wasn't given, we set the aborting flag so no more jobs 997144467Sharti * get started. 998144467Sharti */ 999144467Sharti aborting = ABORT_ERROR; 1000144467Sharti } 10018874Srgrimes 1002144657Sharti if (aborting == ABORT_ERROR && Job_Empty()) { 1003144467Sharti /* 1004144467Sharti * If we are aborting and the job table is now empty, we finish. 1005144467Sharti */ 1006144467Sharti Finish(errors); 1007144467Sharti } 10081590Srgrimes} 10091590Srgrimes 1010144467Sharti/** 1011144467Sharti * Job_Touch 10121590Srgrimes * Touch the given target. Called by JobStart when the -t flag was 1013104696Sjmallett * given. Prints messages unless told to be silent. 10141590Srgrimes * 10151590Srgrimes * Side Effects: 10161590Srgrimes * The data modification of the file is changed. In addition, if the 10171590Srgrimes * file did not exist, it is created. 10181590Srgrimes */ 10191590Srgrimesvoid 1020104696SjmallettJob_Touch(GNode *gn, Boolean silent) 10211590Srgrimes{ 1022144467Sharti int streamID; /* ID of stream opened to do the touch */ 1023144467Sharti struct utimbuf times; /* Times for utime() call */ 10241590Srgrimes 1025144467Sharti if (gn->type & (OP_JOIN | OP_USE | OP_EXEC | OP_OPTIONAL)) { 1026144467Sharti /* 1027144467Sharti * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" 1028144467Sharti * targets and, as such, shouldn't really be created. 1029144467Sharti */ 1030144467Sharti return; 1031144467Sharti } 10328874Srgrimes 1033144467Sharti if (!silent) { 1034144467Sharti fprintf(stdout, "touch %s\n", gn->name); 1035144467Sharti fflush(stdout); 1036144467Sharti } 10371590Srgrimes 1038144467Sharti if (noExecute) { 1039144467Sharti return; 1040144467Sharti } 10411590Srgrimes 1042144467Sharti if (gn->type & OP_ARCHV) { 1043144467Sharti Arch_Touch(gn); 1044144467Sharti } else if (gn->type & OP_LIB) { 1045144467Sharti Arch_TouchLib(gn); 1046144467Sharti } else { 1047144467Sharti char *file = gn->path ? gn->path : gn->name; 10481590Srgrimes 1049144467Sharti times.actime = times.modtime = now; 1050144467Sharti if (utime(file, ×) < 0) { 1051144467Sharti streamID = open(file, O_RDWR | O_CREAT, 0666); 10521590Srgrimes 1053144467Sharti if (streamID >= 0) { 1054144467Sharti char c; 10551590Srgrimes 1056144467Sharti /* 1057144467Sharti * Read and write a byte to the file to change 1058144467Sharti * the modification time, then close the file. 1059144467Sharti */ 1060144467Sharti if (read(streamID, &c, 1) == 1) { 1061144467Sharti lseek(streamID, (off_t)0, SEEK_SET); 1062144467Sharti write(streamID, &c, 1); 1063144467Sharti } 1064144467Sharti 1065144467Sharti close(streamID); 1066144467Sharti } else { 1067144467Sharti fprintf(stdout, "*** couldn't touch %s: %s", 1068144467Sharti file, strerror(errno)); 1069144467Sharti fflush(stdout); 1070144467Sharti } 10711590Srgrimes } 10721590Srgrimes } 10731590Srgrimes} 10741590Srgrimes 1075144467Sharti/** 1076144467Sharti * Job_CheckCommands 10778874Srgrimes * Make sure the given node has all the commands it needs. 10781590Srgrimes * 10791590Srgrimes * Results: 10801590Srgrimes * TRUE if the commands list is/was ok. 10811590Srgrimes * 10821590Srgrimes * Side Effects: 10831590Srgrimes * The node will have commands from the .DEFAULT rule added to it 10841590Srgrimes * if it needs them. 10851590Srgrimes */ 10861590SrgrimesBoolean 1087104696SjmallettJob_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) 10881590Srgrimes{ 1089138232Sharti 1090144467Sharti if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) && 1091144467Sharti (gn->type & OP_LIB) == 0) { 1092144467Sharti /* 1093144467Sharti * No commands. Look for .DEFAULT rule from which we might infer 1094144467Sharti * commands. 1095144467Sharti */ 1096144657Sharti if (DEFAULT != NULL && !Lst_IsEmpty(&DEFAULT->commands)) { 1097144467Sharti char *p1; 1098144467Sharti /* 1099144467Sharti * Make only looks for a .DEFAULT if the node was 1100144467Sharti * never the target of an operator, so that's what we 1101144467Sharti * do too. If a .DEFAULT was given, we substitute its 1102144467Sharti * commands for gn's commands and set the IMPSRC 1103144467Sharti * variable to be the target's name The DEFAULT node 1104144467Sharti * acts like a transformation rule, in that gn also 1105144467Sharti * inherits any attributes or sources attached to 1106144467Sharti * .DEFAULT itself. 1107144467Sharti */ 1108144467Sharti Make_HandleUse(DEFAULT, gn); 1109144467Sharti Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn); 1110144467Sharti free(p1); 111118730Ssteve 1112144467Sharti } else if (Dir_MTime(gn) == 0) { 1113144467Sharti /* 1114144467Sharti * The node wasn't the target of an operator we have 1115144467Sharti * no .DEFAULT rule to go on and the target doesn't 1116144467Sharti * already exist. There's nothing more we can do for 1117144467Sharti * this branch. If the -k flag wasn't given, we stop 1118144467Sharti * in our tracks, otherwise we just don't update 1119144467Sharti * this node's parents so they never get examined. 1120144467Sharti */ 1121144467Sharti static const char msg[] = 1122144467Sharti "make: don't know how to make"; 1123144467Sharti 1124144467Sharti if (gn->type & OP_OPTIONAL) { 1125144467Sharti fprintf(stdout, "%s %s(ignored)\n", 1126144467Sharti msg, gn->name); 1127144467Sharti fflush(stdout); 1128144467Sharti } else if (keepgoing) { 1129144467Sharti fprintf(stdout, "%s %s(continuing)\n", 1130144467Sharti msg, gn->name); 1131144467Sharti fflush(stdout); 1132144467Sharti return (FALSE); 1133144467Sharti } else { 113435483Simp#if OLD_JOKE 1135144467Sharti if (strcmp(gn->name,"love") == 0) 1136144467Sharti (*abortProc)("Not war."); 1137144467Sharti else 113835483Simp#endif 1139144467Sharti (*abortProc)("%s %s. Stop", 1140144467Sharti msg, gn->name); 1141144467Sharti return (FALSE); 1142144467Sharti } 1143144467Sharti } 11441590Srgrimes } 1145144467Sharti return (TRUE); 11461590Srgrimes} 11471590Srgrimes 1148144467Sharti/** 1149144467Sharti * JobExec 11501590Srgrimes * Execute the shell for the given job. Called from JobStart and 11511590Srgrimes * JobRestart. 11521590Srgrimes * 11531590Srgrimes * Side Effects: 11541590Srgrimes * A shell is executed, outputs is altered and the Job structure added 11551590Srgrimes * to the job table. 11561590Srgrimes */ 11571590Srgrimesstatic void 1158104696SjmallettJobExec(Job *job, char **argv) 11591590Srgrimes{ 1160144665Sharti pid_t cpid; /* ID of new child */ 11618874Srgrimes 1162144467Sharti if (DEBUG(JOB)) { 1163144467Sharti int i; 11648874Srgrimes 1165144467Sharti DEBUGF(JOB, ("Running %s\n", job->node->name)); 1166144467Sharti DEBUGF(JOB, ("\tCommand: ")); 1167144467Sharti for (i = 0; argv[i] != NULL; i++) { 1168144467Sharti DEBUGF(JOB, ("%s ", argv[i])); 1169144467Sharti } 1170144467Sharti DEBUGF(JOB, ("\n")); 11711590Srgrimes } 11728874Srgrimes 11731590Srgrimes /* 1174144467Sharti * Some jobs produce no output and it's disconcerting to have 1175144467Sharti * no feedback of their running (since they produce no output, the 1176144467Sharti * banner with their name in it never appears). This is an attempt to 1177144467Sharti * provide that feedback, even if nothing follows it. 11781590Srgrimes */ 1179144657Sharti if (lastNode != job->node && (job->flags & JOB_FIRST) && 1180144467Sharti !(job->flags & JOB_SILENT)) { 1181144467Sharti MESSAGE(stdout, job->node); 1182144467Sharti lastNode = job->node; 11831590Srgrimes } 11841590Srgrimes 1185144665Sharti if ((cpid = vfork()) == -1) 1186144467Sharti Punt("Cannot fork"); 1187144467Sharti 1188144665Sharti if (cpid == 0) { 1189144665Sharti /* 1190144665Sharti * Child 1191144665Sharti */ 1192144467Sharti if (fifoFd >= 0) 1193144467Sharti close(fifoFd); 1194144467Sharti 1195144467Sharti /* 1196144467Sharti * Must duplicate the input stream down to the child's input and 1197144467Sharti * reset it to the beginning (again). Since the stream was 1198144467Sharti * marked close-on-exec, we must clear that bit in the new 1199144467Sharti * input. 1200144467Sharti */ 1201144467Sharti if (dup2(FILENO(job->cmdFILE), 0) == -1) 1202144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1203144467Sharti fcntl(0, F_SETFD, 0); 1204144467Sharti lseek(0, (off_t)0, SEEK_SET); 1205144467Sharti 1206144467Sharti if (usePipes) { 1207144467Sharti /* 1208144467Sharti * Set up the child's output to be routed through the 1209144467Sharti * pipe we've created for it. 1210144467Sharti */ 1211144467Sharti if (dup2(job->outPipe, 1) == -1) 1212144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1213144467Sharti } else { 1214144467Sharti /* 1215144467Sharti * We're capturing output in a file, so we duplicate the 1216144467Sharti * descriptor to the temporary file into the standard 1217144467Sharti * output. 1218144467Sharti */ 1219144467Sharti if (dup2(job->outFd, 1) == -1) 1220144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1221144467Sharti } 1222144467Sharti /* 1223144467Sharti * The output channels are marked close on exec. This bit was 1224144467Sharti * duplicated by the dup2 (on some systems), so we have to clear 1225144467Sharti * it before routing the shell's error output to the same place 1226144467Sharti * as its standard output. 1227144467Sharti */ 1228144467Sharti fcntl(1, F_SETFD, 0); 1229144467Sharti if (dup2(1, 2) == -1) 1230144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1231144467Sharti 12321590Srgrimes#ifdef USE_PGRP 1233144467Sharti /* 1234144467Sharti * We want to switch the child into a different process family 1235144467Sharti * so we can kill it and all its descendants in one fell swoop, 1236144467Sharti * by killing its process family, but not commit suicide. 1237144467Sharti */ 123818730Ssteve# if defined(SYSV) 1239144467Sharti setsid(); 124018730Ssteve# else 1241144467Sharti setpgid(0, getpid()); 124218730Ssteve# endif 124318730Ssteve#endif /* USE_PGRP */ 12448874Srgrimes 1245144467Sharti execv(shellPath, argv); 12461590Srgrimes 1247144467Sharti write(STDERR_FILENO, "Could not execute shell\n", 1248144467Sharti sizeof("Could not execute shell")); 1249144467Sharti _exit(1); 1250144665Sharti } 12511590Srgrimes 1252144665Sharti /* 1253144665Sharti * Parent 1254144665Sharti */ 1255144665Sharti job->pid = cpid; 1256144467Sharti 1257144665Sharti if (usePipes && (job->flags & JOB_FIRST)) { 1258144665Sharti /* 1259144665Sharti * The first time a job is run for a node, we set the 1260144665Sharti * current position in the buffer to the beginning and 1261144665Sharti * mark another stream to watch in the outputs mask. 1262144665Sharti */ 1263104475Sphk#ifdef USE_KQUEUE 1264144665Sharti struct kevent kev[2]; 1265104475Sphk#endif 1266144665Sharti job->curPos = 0; 12678874Srgrimes 1268137202Sharti#if defined(USE_KQUEUE) 1269144665Sharti EV_SET(&kev[0], job->inPipe, EVFILT_READ, EV_ADD, 0, 0, job); 1270144665Sharti EV_SET(&kev[1], job->pid, EVFILT_PROC, 1271144665Sharti EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, NULL); 1272144665Sharti if (kevent(kqfd, kev, 2, NULL, 0, NULL) != 0) { 1273144665Sharti /* 1274144665Sharti * kevent() will fail if the job is already 1275144665Sharti * finished 1276144665Sharti */ 1277144665Sharti if (errno != EINTR && errno != EBADF && errno != ESRCH) 1278144665Sharti Punt("kevent: %s", strerror(errno)); 1279144665Sharti } 12801590Srgrimes#else 1281144665Sharti FD_SET(job->inPipe, &outputs); 1282137202Sharti#endif /* USE_KQUEUE */ 1283144665Sharti } 1284144467Sharti 1285144665Sharti if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1286144665Sharti fclose(job->cmdFILE); 1287144665Sharti job->cmdFILE = NULL; 12881590Srgrimes } 12891590Srgrimes 1290144467Sharti /* 1291144467Sharti * Now the job is actually running, add it to the table. 1292144467Sharti */ 1293144467Sharti nJobs += 1; 1294144494Sharti TAILQ_INSERT_TAIL(&jobs, job, link); 1295144467Sharti if (nJobs == maxJobs) { 1296144467Sharti jobFull = TRUE; 12971590Srgrimes } 12981590Srgrimes} 12991590Srgrimes 1300144467Sharti/** 1301144467Sharti * JobMakeArgv 13021590Srgrimes * Create the argv needed to execute the shell for a given job. 13031590Srgrimes */ 13041590Srgrimesstatic void 1305104696SjmallettJobMakeArgv(Job *job, char **argv) 13061590Srgrimes{ 1307144467Sharti int argc; 1308144467Sharti static char args[10]; /* For merged arguments */ 13098874Srgrimes 1310144467Sharti argv[0] = shellName; 1311144467Sharti argc = 1; 13121590Srgrimes 1313144657Sharti if ((commandShell->exit && *commandShell->exit != '-') || 1314144657Sharti (commandShell->echo && *commandShell->echo != '-')) { 1315144467Sharti /* 1316144467Sharti * At least one of the flags doesn't have a minus before it, so 1317144467Sharti * merge them together. Have to do this because the *(&(@*#*&#$# 1318144467Sharti * Bourne shell thinks its second argument is a file to source. 1319144467Sharti * Grrrr. Note the ten-character limitation on the combined 1320144467Sharti * arguments. 1321144467Sharti */ 1322144657Sharti sprintf(args, "-%s%s", (job->flags & JOB_IGNERR) ? "" : 1323144657Sharti commandShell->exit ? commandShell->exit : "", 1324144657Sharti (job->flags & JOB_SILENT) ? "" : 1325144657Sharti commandShell->echo ? commandShell->echo : ""); 13261590Srgrimes 1327144467Sharti if (args[1]) { 1328144467Sharti argv[argc] = args; 1329144467Sharti argc++; 1330144467Sharti } 1331144467Sharti } else { 1332144467Sharti if (!(job->flags & JOB_IGNERR) && commandShell->exit) { 1333144467Sharti argv[argc] = commandShell->exit; 1334144467Sharti argc++; 1335144467Sharti } 1336144467Sharti if (!(job->flags & JOB_SILENT) && commandShell->echo) { 1337144467Sharti argv[argc] = commandShell->echo; 1338144467Sharti argc++; 1339144467Sharti } 13401590Srgrimes } 1341144467Sharti argv[argc] = NULL; 13421590Srgrimes} 13431590Srgrimes 1344144467Sharti/** 1345144467Sharti * JobRestart 1346144494Sharti * Restart a job that stopped for some reason. The job must be neither 1347144494Sharti * on the jobs nor on the stoppedJobs list. 13481590Srgrimes * 13491590Srgrimes * Side Effects: 13501590Srgrimes * jobFull will be set if the job couldn't be run. 13511590Srgrimes */ 13521590Srgrimesstatic void 1353104696SjmallettJobRestart(Job *job) 13541590Srgrimes{ 135518730Ssteve 1356144467Sharti if (job->flags & JOB_RESTART) { 1357144467Sharti /* 1358144467Sharti * Set up the control arguments to the shell. This is based on 1359144467Sharti * the flags set earlier for this job. If the JOB_IGNERR flag 1360144467Sharti * is clear, the 'exit' flag of the commandShell is used to 1361144467Sharti * cause it to exit upon receiving an error. If the JOB_SILENT 1362144467Sharti * flag is clear, the 'echo' flag of the commandShell is used 1363144467Sharti * to get it to start echoing as soon as it starts 1364144467Sharti * processing commands. 1365144467Sharti */ 1366144467Sharti char *argv[4]; 13678874Srgrimes 1368144467Sharti JobMakeArgv(job, argv); 13698874Srgrimes 1370144467Sharti DEBUGF(JOB, ("Restarting %s...", job->node->name)); 1371144657Sharti if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) { 1372144467Sharti /* 1373144657Sharti * Not allowed to run -- put it back on the hold 1374144657Sharti * queue and mark the table full 1375144467Sharti */ 1376144467Sharti DEBUGF(JOB, ("holding\n")); 1377144494Sharti TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1378144467Sharti jobFull = TRUE; 1379144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 1380144467Sharti return; 1381144467Sharti } else { 1382144467Sharti /* 1383144467Sharti * Job may be run locally. 1384144467Sharti */ 1385144467Sharti DEBUGF(JOB, ("running locally\n")); 1386144467Sharti } 1387144467Sharti JobExec(job, argv); 1388144467Sharti 1389137202Sharti } else { 13901590Srgrimes /* 1391144467Sharti * The job has stopped and needs to be restarted. 1392144467Sharti * Why it stopped, we don't know... 13931590Srgrimes */ 1394144467Sharti DEBUGF(JOB, ("Resuming %s...", job->node->name)); 1395144657Sharti if ((nJobs < maxJobs || ((job->flags & JOB_SPECIAL) && 1396144657Sharti maxJobs == 0)) && nJobs != maxJobs) { 1397144467Sharti /* 1398144467Sharti * If we haven't reached the concurrency limit already 1399144467Sharti * (or the job must be run and maxJobs is 0), it's ok 1400144467Sharti * to resume it. 1401144467Sharti */ 1402144467Sharti Boolean error; 1403144467Sharti int status; 14048874Srgrimes 1405144467Sharti error = (KILL(job->pid, SIGCONT) != 0); 1406144467Sharti 1407144467Sharti if (!error) { 1408144467Sharti /* 1409144467Sharti * Make sure the user knows we've continued 1410144467Sharti * the beast and actually put the thing in the 1411144467Sharti * job table. 1412144467Sharti */ 1413144467Sharti job->flags |= JOB_CONTINUING; 1414144467Sharti status = 0; 1415144467Sharti W_SETTERMSIG(&status, SIGCONT); 1416144467Sharti JobFinish(job, &status); 1417144467Sharti 1418144467Sharti job->flags &= ~(JOB_RESUME|JOB_CONTINUING); 1419144467Sharti DEBUGF(JOB, ("done\n")); 1420144467Sharti } else { 1421144467Sharti Error("couldn't resume %s: %s", 1422144467Sharti job->node->name, strerror(errno)); 1423144467Sharti status = 0; 1424144467Sharti W_SETEXITSTATUS(&status, 1); 1425144467Sharti JobFinish(job, &status); 1426144467Sharti } 1427144467Sharti } else { 1428144467Sharti /* 1429144467Sharti * Job cannot be restarted. Mark the table as full and 1430144467Sharti * place the job back on the list of stopped jobs. 1431144467Sharti */ 1432144467Sharti DEBUGF(JOB, ("table full\n")); 1433144494Sharti TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1434144467Sharti jobFull = TRUE; 1435144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 1436144467Sharti } 14371590Srgrimes } 14381590Srgrimes} 14391590Srgrimes 1440144467Sharti/** 1441144467Sharti * JobStart 14421590Srgrimes * Start a target-creation process going for the target described 14438874Srgrimes * by the graph node gn. 14441590Srgrimes * 14451590Srgrimes * Results: 14461590Srgrimes * JOB_ERROR if there was an error in the commands, JOB_FINISHED 14471590Srgrimes * if there isn't actually anything left to do for the job and 14481590Srgrimes * JOB_RUNNING if the job has been started. 14491590Srgrimes * 14501590Srgrimes * Side Effects: 14511590Srgrimes * A new Job node is created and added to the list of running 14521590Srgrimes * jobs. PMake is forked and a child shell created. 14531590Srgrimes */ 14541590Srgrimesstatic int 1455104696SjmallettJobStart(GNode *gn, int flags, Job *previous) 14561590Srgrimes{ 1457144467Sharti Job *job; /* new job descriptor */ 1458144467Sharti char *argv[4]; /* Argument vector to shell */ 1459144467Sharti Boolean cmdsOK; /* true if the nodes commands were all right */ 1460144467Sharti Boolean noExec; /* Set true if we decide not to run the job */ 1461144467Sharti int tfd; /* File descriptor for temp file */ 1462144467Sharti LstNode *ln; 1463144654Sharti char tfile[sizeof(TMPPAT)]; 14641590Srgrimes 1465144467Sharti if (interrupted) { 1466144467Sharti JobPassSig(interrupted); 1467144467Sharti return (JOB_ERROR); 1468144467Sharti } 1469144467Sharti if (previous != NULL) { 1470144467Sharti previous->flags &= ~(JOB_FIRST | JOB_IGNERR | JOB_SILENT); 1471144467Sharti job = previous; 1472144467Sharti } else { 1473144467Sharti job = emalloc(sizeof(Job)); 1474144467Sharti flags |= JOB_FIRST; 1475144467Sharti } 14761590Srgrimes 1477144467Sharti job->node = gn; 1478144467Sharti job->tailCmds = NULL; 14791590Srgrimes 14801590Srgrimes /* 1481144467Sharti * Set the initial value of the flags for this job based on the global 1482144467Sharti * ones and the node's attributes... Any flags supplied by the caller 1483144467Sharti * are also added to the field. 14841590Srgrimes */ 1485144467Sharti job->flags = 0; 1486144467Sharti if (Targ_Ignore(gn)) { 1487144467Sharti job->flags |= JOB_IGNERR; 14881590Srgrimes } 1489144467Sharti if (Targ_Silent(gn)) { 1490144467Sharti job->flags |= JOB_SILENT; 1491144467Sharti } 1492144467Sharti job->flags |= flags; 14938874Srgrimes 14941590Srgrimes /* 1495144467Sharti * Check the commands now so any attributes from .DEFAULT have a chance 1496144658Sharti * to migrate to the node. 14971590Srgrimes */ 1498144658Sharti if (!compatMake && (job->flags & JOB_FIRST)) { 1499144467Sharti cmdsOK = Job_CheckCommands(gn, Error); 1500144467Sharti } else { 1501144467Sharti cmdsOK = TRUE; 1502144467Sharti } 15031590Srgrimes 15041590Srgrimes /* 1505144467Sharti * If the -n flag wasn't given, we open up OUR (not the child's) 1506144467Sharti * temporary file to stuff commands in it. The thing is rd/wr so we 1507144467Sharti * don't need to reopen it to feed it to the shell. If the -n flag 1508144467Sharti * *was* given, we just set the file to be stdout. Cute, huh? 15091590Srgrimes */ 1510144467Sharti if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) { 1511144467Sharti /* 1512144467Sharti * We're serious here, but if the commands were bogus, we're 1513144467Sharti * also dead... 1514144467Sharti */ 1515144467Sharti if (!cmdsOK) { 1516144467Sharti DieHorribly(); 1517144467Sharti } 15188874Srgrimes 1519144467Sharti strcpy(tfile, TMPPAT); 1520144467Sharti if ((tfd = mkstemp(tfile)) == -1) 1521144467Sharti Punt("Cannot create temp file: %s", strerror(errno)); 1522144467Sharti job->cmdFILE = fdopen(tfd, "w+"); 1523144467Sharti eunlink(tfile); 1524144467Sharti if (job->cmdFILE == NULL) { 1525144467Sharti close(tfd); 1526144467Sharti Punt("Could not open %s", tfile); 1527144467Sharti } 1528144467Sharti fcntl(FILENO(job->cmdFILE), F_SETFD, 1); 1529144467Sharti /* 1530144467Sharti * Send the commands to the command file, flush all its 1531144467Sharti * buffers then rewind and remove the thing. 1532144467Sharti */ 1533144467Sharti noExec = FALSE; 1534138564Sharti 1535138564Sharti /* 1536144467Sharti * Used to be backwards; replace when start doing multiple 1537144467Sharti * commands per shell. 1538138564Sharti */ 1539144467Sharti if (compatMake) { 1540144467Sharti /* 1541144467Sharti * Be compatible: If this is the first time for this 1542144467Sharti * node, verify its commands are ok and open the 1543144467Sharti * commands list for sequential access by later 1544144467Sharti * invocations of JobStart. Once that is done, we take 1545144467Sharti * the next command off the list and print it to the 1546144467Sharti * command file. If the command was an ellipsis, note 1547144467Sharti * that there's nothing more to execute. 1548144467Sharti */ 1549144467Sharti if (job->flags & JOB_FIRST) 1550144467Sharti gn->compat_command = Lst_First(&gn->commands); 1551144467Sharti else 1552144467Sharti gn->compat_command = 1553144467Sharti Lst_Succ(gn->compat_command); 15548874Srgrimes 1555144467Sharti if (gn->compat_command == NULL || 1556144467Sharti JobPrintCommand(Lst_Datum(gn->compat_command), job)) 1557144467Sharti noExec = TRUE; 1558144467Sharti 1559144467Sharti if (noExec && !(job->flags & JOB_FIRST)) { 1560144467Sharti /* 1561144467Sharti * If we're not going to execute anything, the 1562144467Sharti * job is done and we need to close down the 1563144467Sharti * various file descriptors we've opened for 1564144467Sharti * output, then call JobDoOutput to catch the 1565144467Sharti * final characters or send the file to the 1566144467Sharti * screen... Note that the i/o streams are only 1567144467Sharti * open if this isn't the first job. Note also 1568144467Sharti * that this could not be done in 1569144467Sharti * Job_CatchChildren b/c it wasn't clear if 1570144467Sharti * there were more commands to execute or not... 1571144467Sharti */ 1572144467Sharti JobClose(job); 1573144467Sharti } 1574144467Sharti } else { 1575144467Sharti /* 1576144467Sharti * We can do all the commands at once. hooray for sanity 1577144467Sharti */ 1578144467Sharti numCommands = 0; 1579144467Sharti LST_FOREACH(ln, &gn->commands) { 1580144467Sharti if (JobPrintCommand(Lst_Datum(ln), job)) 1581144467Sharti break; 1582144467Sharti } 1583144467Sharti 1584144467Sharti /* 1585144467Sharti * If we didn't print out any commands to the shell 1586144467Sharti * script, there's not much point in executing the 1587144467Sharti * shell, is there? 1588144467Sharti */ 1589144467Sharti if (numCommands == 0) { 1590144467Sharti noExec = TRUE; 1591144467Sharti } 1592144467Sharti } 1593144467Sharti 1594144467Sharti } else if (noExecute) { 1595144467Sharti /* 1596144467Sharti * Not executing anything -- just print all the commands to 1597144467Sharti * stdout in one fell swoop. This will still set up 1598144467Sharti * job->tailCmds correctly. 1599144467Sharti */ 1600144467Sharti if (lastNode != gn) { 1601144467Sharti MESSAGE(stdout, gn); 1602144467Sharti lastNode = gn; 1603144467Sharti } 1604144467Sharti job->cmdFILE = stdout; 1605144467Sharti 1606144467Sharti /* 1607144467Sharti * Only print the commands if they're ok, but don't die if 1608144467Sharti * they're not -- just let the user know they're bad and keep 1609144467Sharti * going. It doesn't do any harm in this case and may do 1610144467Sharti * some good. 1611144467Sharti */ 1612144467Sharti if (cmdsOK) { 1613144467Sharti LST_FOREACH(ln, &gn->commands) { 1614144467Sharti if (JobPrintCommand(Lst_Datum(ln), job)) 1615144467Sharti break; 1616144467Sharti } 1617144467Sharti } 1618144467Sharti /* 1619144467Sharti * Don't execute the shell, thank you. 1620144467Sharti */ 16211590Srgrimes noExec = TRUE; 1622144467Sharti 1623144467Sharti } else { 1624144467Sharti /* 1625144467Sharti * Just touch the target and note that no shell should be 1626144467Sharti * executed. Set cmdFILE to stdout to make life easier. Check 1627144467Sharti * the commands, too, but don't die if they're no good -- it 1628144467Sharti * does no harm to keep working up the graph. 1629144467Sharti */ 1630144467Sharti job->cmdFILE = stdout; 1631144467Sharti Job_Touch(gn, job->flags & JOB_SILENT); 1632144467Sharti noExec = TRUE; 16331590Srgrimes } 1634144467Sharti 16351590Srgrimes /* 1636144467Sharti * If we're not supposed to execute a shell, don't. 16371590Srgrimes */ 1638144467Sharti if (noExec) { 1639144467Sharti /* 1640144467Sharti * Unlink and close the command file if we opened one 1641144467Sharti */ 1642144467Sharti if (job->cmdFILE != stdout) { 1643144467Sharti if (job->cmdFILE != NULL) 1644144467Sharti fclose(job->cmdFILE); 1645144467Sharti } else { 1646144467Sharti fflush(stdout); 1647144467Sharti } 1648144467Sharti 1649144467Sharti /* 1650144467Sharti * We only want to work our way up the graph if we aren't here 1651144467Sharti * because the commands for the job were no good. 1652144467Sharti */ 1653144467Sharti if (cmdsOK) { 1654144467Sharti if (aborting == 0) { 1655144467Sharti for (ln = job->tailCmds; ln != NULL; 1656144467Sharti ln = LST_NEXT(ln)) { 1657144467Sharti Lst_AtEnd(&postCommands->commands, 1658144467Sharti Buf_Peel(Var_Subst(NULL, 1659144467Sharti Lst_Datum(ln), job->node, FALSE))); 1660144467Sharti } 1661144467Sharti job->node->made = MADE; 1662144467Sharti Make_Update(job->node); 1663144467Sharti } 1664144467Sharti free(job); 1665144467Sharti return(JOB_FINISHED); 1666144467Sharti } else { 1667144467Sharti free(job); 1668144467Sharti return(JOB_ERROR); 1669144467Sharti } 1670144467Sharti } else { 1671144467Sharti fflush(job->cmdFILE); 16721590Srgrimes } 1673144467Sharti 16741590Srgrimes /* 1675144467Sharti * Set up the control arguments to the shell. This is based on the flags 1676144467Sharti * set earlier for this job. 16771590Srgrimes */ 1678144467Sharti JobMakeArgv(job, argv); 16791590Srgrimes 16801590Srgrimes /* 1681144467Sharti * If we're using pipes to catch output, create the pipe by which we'll 1682144467Sharti * get the shell's output. If we're using files, print out that we're 1683144467Sharti * starting a job and then set up its temporary-file name. 16841590Srgrimes */ 1685144467Sharti if (!compatMake || (job->flags & JOB_FIRST)) { 1686144467Sharti if (usePipes) { 1687144467Sharti int fd[2]; 16881590Srgrimes 1689144467Sharti if (pipe(fd) == -1) 1690144467Sharti Punt("Cannot create pipe: %s", strerror(errno)); 1691144467Sharti job->inPipe = fd[0]; 1692144467Sharti job->outPipe = fd[1]; 1693144467Sharti fcntl(job->inPipe, F_SETFD, 1); 1694144467Sharti fcntl(job->outPipe, F_SETFD, 1); 1695144467Sharti } else { 1696144467Sharti fprintf(stdout, "Remaking `%s'\n", gn->name); 1697144467Sharti fflush(stdout); 1698144467Sharti strcpy(job->outFile, TMPPAT); 1699144467Sharti if ((job->outFd = mkstemp(job->outFile)) == -1) 1700144467Sharti Punt("cannot create temp file: %s", 1701144467Sharti strerror(errno)); 1702144467Sharti fcntl(job->outFd, F_SETFD, 1); 17031590Srgrimes } 17041590Srgrimes } 17051590Srgrimes 1706144657Sharti if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) && maxJobs != 0) { 1707144467Sharti /* 1708144467Sharti * We've hit the limit of concurrency, so put the job on hold 1709144467Sharti * until some other job finishes. Note that the special jobs 1710144467Sharti * (.BEGIN, .INTERRUPT and .END) may be run even when the 1711144467Sharti * limit has been reached (e.g. when maxJobs == 0). 1712144467Sharti */ 1713144467Sharti jobFull = TRUE; 17141590Srgrimes 1715144467Sharti DEBUGF(JOB, ("Can only run job locally.\n")); 1716144467Sharti job->flags |= JOB_RESTART; 1717144494Sharti TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 17181590Srgrimes } else { 1719144467Sharti if (nJobs >= maxJobs) { 1720144467Sharti /* 1721144657Sharti * If we're running this job as a special case 1722144467Sharti * (see above), at least say the table is full. 1723144467Sharti */ 1724144467Sharti jobFull = TRUE; 1725144467Sharti DEBUGF(JOB, ("Local job queue is full.\n")); 1726144467Sharti } 1727144467Sharti JobExec(job, argv); 17281590Srgrimes } 1729144467Sharti return (JOB_RUNNING); 17301590Srgrimes} 17311590Srgrimes 173218730Sstevestatic char * 1733104696SjmallettJobOutput(Job *job, char *cp, char *endp, int msg) 173418730Ssteve{ 1735144467Sharti char *ecp; 173618730Ssteve 1737144467Sharti if (commandShell->noPrint) { 1738144467Sharti ecp = strstr(cp, commandShell->noPrint); 1739144467Sharti while (ecp != NULL) { 1740144467Sharti if (cp != ecp) { 1741144467Sharti *ecp = '\0'; 1742144467Sharti if (msg && job->node != lastNode) { 1743144467Sharti MESSAGE(stdout, job->node); 1744144467Sharti lastNode = job->node; 1745144467Sharti } 1746144467Sharti /* 1747144467Sharti * The only way there wouldn't be a newline 1748144467Sharti * after this line is if it were the last in 1749144467Sharti * the buffer. However, since the non-printable 1750144467Sharti * comes after it, there must be a newline, so 1751144467Sharti * we don't print one. 1752144467Sharti */ 1753144467Sharti fprintf(stdout, "%s", cp); 1754144467Sharti fflush(stdout); 1755144467Sharti } 1756144741Sharti cp = ecp + strlen(commandShell->noPrint); 1757144467Sharti if (cp != endp) { 1758144467Sharti /* 1759144467Sharti * Still more to print, look again after 1760144467Sharti * skipping the whitespace following the 1761144467Sharti * non-printable command.... 1762144467Sharti */ 1763144467Sharti cp++; 1764144467Sharti while (*cp == ' ' || *cp == '\t' || 1765144467Sharti *cp == '\n') { 1766144467Sharti cp++; 1767144467Sharti } 1768144467Sharti ecp = strstr(cp, commandShell->noPrint); 1769144467Sharti } else { 1770144467Sharti return (cp); 1771144467Sharti } 177218730Ssteve } 177318730Ssteve } 1774144467Sharti return (cp); 177518730Ssteve} 177618730Ssteve 1777144467Sharti/** 1778144467Sharti * JobDoOutput 17791590Srgrimes * This function is called at different times depending on 17801590Srgrimes * whether the user has specified that output is to be collected 17811590Srgrimes * via pipes or temporary files. In the former case, we are called 17821590Srgrimes * whenever there is something to read on the pipe. We collect more 17831590Srgrimes * output from the given job and store it in the job's outBuf. If 17841590Srgrimes * this makes up a line, we print it tagged by the job's identifier, 17851590Srgrimes * as necessary. 17861590Srgrimes * If output has been collected in a temporary file, we open the 17871590Srgrimes * file and read it line by line, transfering it to our own 17881590Srgrimes * output channel until the file is empty. At which point we 17891590Srgrimes * remove the temporary file. 17901590Srgrimes * In both cases, however, we keep our figurative eye out for the 17911590Srgrimes * 'noPrint' line for the shell from which the output came. If 17921590Srgrimes * we recognize a line, we don't print it. If the command is not 17931590Srgrimes * alone on the line (the character after it is not \0 or \n), we 17941590Srgrimes * do print whatever follows it. 17951590Srgrimes * 17961590Srgrimes * Side Effects: 17971590Srgrimes * curPos may be shifted as may the contents of outBuf. 17981590Srgrimes */ 1799144656Shartistatic void 1800104696SjmallettJobDoOutput(Job *job, Boolean finish) 18011590Srgrimes{ 1802144467Sharti Boolean gotNL = FALSE; /* true if got a newline */ 1803144467Sharti Boolean fbuf; /* true if our buffer filled up */ 1804144467Sharti int nr; /* number of bytes read */ 1805144467Sharti int i; /* auxiliary index into outBuf */ 1806144467Sharti int max; /* limit for i (end of current data) */ 1807144467Sharti int nRead; /* (Temporary) number of bytes read */ 1808144467Sharti FILE *oFILE; /* Stream pointer to shell's output file */ 1809144467Sharti char inLine[132]; 18101590Srgrimes 1811144467Sharti if (usePipes) { 18121590Srgrimes /* 1813144467Sharti * Read as many bytes as will fit in the buffer. 18141590Srgrimes */ 1815144467Sharti end_loop: 1816144467Sharti gotNL = FALSE; 1817144467Sharti fbuf = FALSE; 18188874Srgrimes 1819144467Sharti nRead = read(job->inPipe, &job->outBuf[job->curPos], 1820144467Sharti JOB_BUFSIZE - job->curPos); 18211590Srgrimes /* 1822144467Sharti * Check for interrupt here too, because the above read may 1823144467Sharti * block when the child process is stopped. In this case the 1824144467Sharti * interrupt will unblock it (we don't use SA_RESTART). 18251590Srgrimes */ 1826144467Sharti if (interrupted) 1827144467Sharti JobPassSig(interrupted); 18281590Srgrimes 1829144467Sharti if (nRead < 0) { 1830144467Sharti DEBUGF(JOB, ("JobDoOutput(piperead)")); 1831144467Sharti nr = 0; 1832144467Sharti } else { 1833144467Sharti nr = nRead; 1834144467Sharti } 18351590Srgrimes 18361590Srgrimes /* 1837144467Sharti * If we hit the end-of-file (the job is dead), we must flush 1838144467Sharti * its remaining output, so pretend we read a newline if 1839144467Sharti * there's any output remaining in the buffer. 1840144467Sharti * Also clear the 'finish' flag so we stop looping. 18411590Srgrimes */ 1842144657Sharti if (nr == 0 && job->curPos != 0) { 1843144467Sharti job->outBuf[job->curPos] = '\n'; 1844144467Sharti nr = 1; 1845144467Sharti finish = FALSE; 1846144467Sharti } else if (nr == 0) { 1847144467Sharti finish = FALSE; 18481590Srgrimes } 18498874Srgrimes 18501590Srgrimes /* 1851144467Sharti * Look for the last newline in the bytes we just got. If there 1852144467Sharti * is one, break out of the loop with 'i' as its index and 1853144467Sharti * gotNL set TRUE. 1854144467Sharti */ 1855144467Sharti max = job->curPos + nr; 1856144467Sharti for (i = job->curPos + nr - 1; i >= job->curPos; i--) { 1857144467Sharti if (job->outBuf[i] == '\n') { 1858144467Sharti gotNL = TRUE; 1859144467Sharti break; 1860144467Sharti } else if (job->outBuf[i] == '\0') { 1861144467Sharti /* 1862144467Sharti * Why? 1863144467Sharti */ 1864144467Sharti job->outBuf[i] = ' '; 1865144467Sharti } 1866144467Sharti } 18671590Srgrimes 1868144467Sharti if (!gotNL) { 1869144467Sharti job->curPos += nr; 1870144467Sharti if (job->curPos == JOB_BUFSIZE) { 1871144467Sharti /* 1872144467Sharti * If we've run out of buffer space, we have 1873144467Sharti * no choice but to print the stuff. sigh. 1874144467Sharti */ 1875144467Sharti fbuf = TRUE; 1876144467Sharti i = job->curPos; 1877144467Sharti } 18781590Srgrimes } 1879144467Sharti if (gotNL || fbuf) { 1880144467Sharti /* 1881144467Sharti * Need to send the output to the screen. Null terminate 1882144467Sharti * it first, overwriting the newline character if there 1883144467Sharti * was one. So long as the line isn't one we should 1884144467Sharti * filter (according to the shell description), we print 1885144467Sharti * the line, preceded by a target banner if this target 1886144467Sharti * isn't the same as the one for which we last printed 1887144467Sharti * something. The rest of the data in the buffer are 1888144467Sharti * then shifted down to the start of the buffer and 1889144467Sharti * curPos is set accordingly. 1890144467Sharti */ 1891144467Sharti job->outBuf[i] = '\0'; 1892144467Sharti if (i >= job->curPos) { 1893144467Sharti char *cp; 18941590Srgrimes 1895144467Sharti cp = JobOutput(job, job->outBuf, 1896144467Sharti &job->outBuf[i], FALSE); 1897144467Sharti 1898144467Sharti /* 1899144467Sharti * There's still more in that buffer. This time, 1900144467Sharti * though, we know there's no newline at the 1901144467Sharti * end, so we add one of our own free will. 1902144467Sharti */ 1903144467Sharti if (*cp != '\0') { 1904144467Sharti if (job->node != lastNode) { 1905144467Sharti MESSAGE(stdout, job->node); 1906144467Sharti lastNode = job->node; 1907144467Sharti } 1908144467Sharti fprintf(stdout, "%s%s", cp, 1909144467Sharti gotNL ? "\n" : ""); 1910144467Sharti fflush(stdout); 1911144467Sharti } 1912144467Sharti } 1913144467Sharti if (i < max - 1) { 1914144467Sharti /* shift the remaining characters down */ 1915144467Sharti memcpy(job->outBuf, &job->outBuf[i + 1], 1916144467Sharti max - (i + 1)); 1917144467Sharti job->curPos = max - (i + 1); 1918144467Sharti 1919144467Sharti } else { 1920144467Sharti /* 1921144467Sharti * We have written everything out, so we just 1922144467Sharti * start over from the start of the buffer. 1923144467Sharti * No copying. No nothing. 1924144467Sharti */ 1925144467Sharti job->curPos = 0; 1926144467Sharti } 1927144467Sharti } 1928144467Sharti if (finish) { 1929144467Sharti /* 1930144467Sharti * If the finish flag is true, we must loop until we hit 1931144467Sharti * end-of-file on the pipe. This is guaranteed to happen 1932144467Sharti * eventually since the other end of the pipe is now 1933144467Sharti * closed (we closed it explicitly and the child has 1934144467Sharti * exited). When we do get an EOF, finish will be set 1935144467Sharti * FALSE and we'll fall through and out. 1936144467Sharti */ 1937144467Sharti goto end_loop; 1938144467Sharti } 1939144467Sharti 1940144467Sharti } else { 19411590Srgrimes /* 1942144467Sharti * We've been called to retrieve the output of the job from the 1943144467Sharti * temporary file where it's been squirreled away. This consists 1944144467Sharti * of opening the file, reading the output line by line, being 1945144467Sharti * sure not to print the noPrint line for the shell we used, 1946144467Sharti * then close and remove the temporary file. Very simple. 1947144467Sharti * 1948144467Sharti * Change to read in blocks and do FindSubString type things 1949144467Sharti * as for pipes? That would allow for "@echo -n..." 19501590Srgrimes */ 1951144467Sharti oFILE = fopen(job->outFile, "r"); 1952144467Sharti if (oFILE != NULL) { 1953144467Sharti fprintf(stdout, "Results of making %s:\n", 1954144467Sharti job->node->name); 1955144467Sharti fflush(stdout); 1956144467Sharti 1957144467Sharti while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { 1958144467Sharti char *cp, *endp, *oendp; 1959144467Sharti 1960144467Sharti cp = inLine; 1961144467Sharti oendp = endp = inLine + strlen(inLine); 1962144467Sharti if (endp[-1] == '\n') { 1963144467Sharti *--endp = '\0'; 1964144467Sharti } 1965144467Sharti cp = JobOutput(job, inLine, endp, FALSE); 1966144467Sharti 1967144467Sharti /* 1968144467Sharti * There's still more in that buffer. This time, 1969144467Sharti * though, we know there's no newline at the 1970144467Sharti * end, so we add one of our own free will. 1971144467Sharti */ 1972144467Sharti fprintf(stdout, "%s", cp); 1973144467Sharti fflush(stdout); 1974144467Sharti if (endp != oendp) { 1975144467Sharti fprintf(stdout, "\n"); 1976144467Sharti fflush(stdout); 1977144467Sharti } 1978144467Sharti } 1979144467Sharti fclose(oFILE); 1980144467Sharti eunlink(job->outFile); 19811590Srgrimes } 19821590Srgrimes } 19831590Srgrimes} 19841590Srgrimes 1985144467Sharti/** 1986144467Sharti * Job_CatchChildren 19871590Srgrimes * Handle the exit of a child. Called from Make_Make. 19881590Srgrimes * 19891590Srgrimes * Side Effects: 19901590Srgrimes * The job descriptor is removed from the list of children. 19911590Srgrimes * 19921590Srgrimes * Notes: 19931590Srgrimes * We do waits, blocking or not, according to the wisdom of our 19941590Srgrimes * caller, until there are no more children to report. For each 19951590Srgrimes * job, call JobFinish to finish things off. This will take care of 19961590Srgrimes * putting jobs on the stoppedJobs queue. 19971590Srgrimes */ 19981590Srgrimesvoid 1999104696SjmallettJob_CatchChildren(Boolean block) 20001590Srgrimes{ 2001144665Sharti pid_t pid; /* pid of dead child */ 2002144467Sharti Job *job; /* job descriptor for dead child */ 2003144467Sharti int status; /* Exit/termination status */ 20041590Srgrimes 2005144467Sharti /* 2006144467Sharti * Don't even bother if we know there's no one around. 2007144467Sharti */ 2008144467Sharti if (nJobs == 0) { 2009144467Sharti return; 2010144467Sharti } 20118874Srgrimes 2012144467Sharti for (;;) { 2013144467Sharti pid = waitpid((pid_t)-1, &status, 2014144467Sharti (block ? 0 : WNOHANG) | WUNTRACED); 2015144467Sharti if (pid <= 0) 2016144467Sharti break; 20171590Srgrimes 2018144665Sharti DEBUGF(JOB, ("Process %jd exited or stopped.\n", 2019144665Sharti (intmax_t)pid)); 20201590Srgrimes 2021144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2022144494Sharti if (job->pid == pid) 2023144467Sharti break; 2024143810Sharti } 2025144467Sharti 2026144494Sharti if (job == NULL) { 2027144467Sharti if (WIFSIGNALED(status) && 2028144467Sharti (WTERMSIG(status) == SIGCONT)) { 2029144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2030144494Sharti if (job->pid == pid) 2031144467Sharti break; 2032144467Sharti } 2033144494Sharti if (job == NULL) { 2034144665Sharti Error("Resumed child (%jd) " 2035144665Sharti "not in table", (intmax_t)pid); 2036144467Sharti continue; 2037144467Sharti } 2038144494Sharti TAILQ_REMOVE(&stoppedJobs, job, link); 2039144467Sharti } else { 2040144665Sharti Error("Child (%jd) not in table?", 2041144665Sharti (intmax_t)pid); 2042144467Sharti continue; 2043144467Sharti } 2044144467Sharti } else { 2045144494Sharti TAILQ_REMOVE(&jobs, job, link); 2046144467Sharti nJobs -= 1; 2047144467Sharti if (fifoFd >= 0 && maxJobs > 1) { 2048144467Sharti write(fifoFd, "+", 1); 2049144467Sharti maxJobs--; 2050144467Sharti if (nJobs >= maxJobs) 2051144467Sharti jobFull = TRUE; 2052144467Sharti else 2053144467Sharti jobFull = FALSE; 2054144467Sharti } else { 2055144467Sharti DEBUGF(JOB, ("Job queue is no longer full.\n")); 2056144467Sharti jobFull = FALSE; 2057144467Sharti } 20581590Srgrimes } 2059144467Sharti 2060144467Sharti JobFinish(job, &status); 20611590Srgrimes } 2062144467Sharti if (interrupted) 2063144467Sharti JobPassSig(interrupted); 20641590Srgrimes} 20651590Srgrimes 2066144467Sharti/** 2067144467Sharti * Job_CatchOutput 20681590Srgrimes * Catch the output from our children, if we're using 20691590Srgrimes * pipes do so. Otherwise just block time until we get a 2070138232Sharti * signal(most likely a SIGCHLD) since there's no point in 20711590Srgrimes * just spinning when there's nothing to do and the reaping 20728874Srgrimes * of a child can wait for a while. 20731590Srgrimes * 20741590Srgrimes * Side Effects: 20751590Srgrimes * Output is read from pipes if we're piping. 20761590Srgrimes * ----------------------------------------------------------------------- 20771590Srgrimes */ 20781590Srgrimesvoid 2079139064Sharti#ifdef USE_KQUEUE 2080139064ShartiJob_CatchOutput(int flag __unused) 2081139064Sharti#else 2082137606SphkJob_CatchOutput(int flag) 2083139064Sharti#endif 20841590Srgrimes{ 2085144467Sharti int nfds; 2086104475Sphk#ifdef USE_KQUEUE 2087104475Sphk#define KEV_SIZE 4 2088144467Sharti struct kevent kev[KEV_SIZE]; 2089144467Sharti int i; 2090104475Sphk#else 2091144467Sharti struct timeval timeout; 2092144467Sharti fd_set readfds; 2093144467Sharti Job *job; 2094104475Sphk#endif 20951590Srgrimes 2096144467Sharti fflush(stdout); 20971590Srgrimes 2098144467Sharti if (usePipes) { 2099104475Sphk#ifdef USE_KQUEUE 2100144467Sharti if ((nfds = kevent(kqfd, NULL, 0, kev, KEV_SIZE, NULL)) == -1) { 2101144467Sharti if (errno != EINTR) 2102144467Sharti Punt("kevent: %s", strerror(errno)); 2103144467Sharti if (interrupted) 2104144467Sharti JobPassSig(interrupted); 2105144467Sharti } else { 2106144467Sharti for (i = 0; i < nfds; i++) { 2107144467Sharti if (kev[i].flags & EV_ERROR) { 2108144467Sharti warnc(kev[i].data, "kevent"); 2109144467Sharti continue; 2110144467Sharti } 2111144467Sharti switch (kev[i].filter) { 2112144467Sharti case EVFILT_READ: 2113144467Sharti JobDoOutput(kev[i].udata, FALSE); 2114144467Sharti break; 2115144467Sharti case EVFILT_PROC: 2116144467Sharti /* 2117144467Sharti * Just wake up and let 2118144467Sharti * Job_CatchChildren() collect the 2119144467Sharti * terminated job. 2120144467Sharti */ 2121144467Sharti break; 2122144467Sharti } 2123144467Sharti } 2124104475Sphk } 2125104475Sphk#else 2126144467Sharti readfds = outputs; 2127144467Sharti timeout.tv_sec = SEL_SEC; 2128144467Sharti timeout.tv_usec = SEL_USEC; 2129144467Sharti if (flag && jobFull && fifoFd >= 0) 2130144467Sharti FD_SET(fifoFd, &readfds); 21311590Srgrimes 2132144467Sharti nfds = select(FD_SETSIZE, &readfds, (fd_set *)NULL, 2133144467Sharti (fd_set *)NULL, &timeout); 2134144467Sharti if (nfds <= 0) { 2135144467Sharti if (interrupted) 2136144467Sharti JobPassSig(interrupted); 2137144467Sharti return; 2138144467Sharti } 2139144467Sharti if (fifoFd >= 0 && FD_ISSET(fifoFd, &readfds)) { 2140144467Sharti if (--nfds <= 0) 2141144467Sharti return; 2142144467Sharti } 2143144494Sharti job = TAILQ_FIRST(&jobs); 2144144494Sharti while (nfds != 0 && job != NULL) { 2145144467Sharti if (FD_ISSET(job->inPipe, &readfds)) { 2146144467Sharti JobDoOutput(job, FALSE); 2147144494Sharti nfds--; 2148144467Sharti } 2149144494Sharti job = TAILQ_NEXT(job, link); 2150144467Sharti } 2151144467Sharti#endif /* !USE_KQUEUE */ 2152137606Sphk } 21531590Srgrimes} 21541590Srgrimes 2155144467Sharti/** 2156144467Sharti * Job_Make 21571590Srgrimes * Start the creation of a target. Basically a front-end for 21581590Srgrimes * JobStart used by the Make module. 21591590Srgrimes * 21601590Srgrimes * Side Effects: 21611590Srgrimes * Another job is started. 21621590Srgrimes */ 21631590Srgrimesvoid 2164104696SjmallettJob_Make(GNode *gn) 21651590Srgrimes{ 2166138232Sharti 2167144467Sharti JobStart(gn, 0, NULL); 21681590Srgrimes} 21691590Srgrimes 2170144467Sharti/** 2171144467Sharti * JobCopyShell 2172144467Sharti * Make a new copy of the shell structure including a copy of the strings 2173144467Sharti * in it. This also defaults some fields in case they are NULL. 2174138079Sharti * 2175144467Sharti * Returns: 2176144467Sharti * The function returns a pointer to the new shell structure. 2177138079Sharti */ 2178144483Shartistatic struct Shell * 2179144483ShartiJobCopyShell(const struct Shell *osh) 2180138079Sharti{ 2181144483Sharti struct Shell *nsh; 2182138079Sharti 2183138079Sharti nsh = emalloc(sizeof(*nsh)); 2184138079Sharti nsh->name = estrdup(osh->name); 2185138079Sharti 2186138079Sharti if (osh->echoOff != NULL) 2187138079Sharti nsh->echoOff = estrdup(osh->echoOff); 2188138079Sharti else 2189138079Sharti nsh->echoOff = NULL; 2190138079Sharti if (osh->echoOn != NULL) 2191138079Sharti nsh->echoOn = estrdup(osh->echoOn); 2192138079Sharti else 2193138079Sharti nsh->echoOn = NULL; 2194138079Sharti nsh->hasEchoCtl = osh->hasEchoCtl; 2195138079Sharti 2196138079Sharti if (osh->noPrint != NULL) 2197138079Sharti nsh->noPrint = estrdup(osh->noPrint); 2198138079Sharti else 2199138079Sharti nsh->noPrint = NULL; 2200138079Sharti 2201138079Sharti nsh->hasErrCtl = osh->hasErrCtl; 2202138079Sharti if (osh->errCheck == NULL) 2203138079Sharti nsh->errCheck = estrdup(""); 2204138079Sharti else 2205138079Sharti nsh->errCheck = estrdup(osh->errCheck); 2206138079Sharti if (osh->ignErr == NULL) 2207138079Sharti nsh->ignErr = estrdup("%s"); 2208138079Sharti else 2209138079Sharti nsh->ignErr = estrdup(osh->ignErr); 2210138079Sharti 2211138079Sharti if (osh->echo == NULL) 2212138079Sharti nsh->echo = estrdup(""); 2213138079Sharti else 2214138079Sharti nsh->echo = estrdup(osh->echo); 2215138079Sharti 2216138079Sharti if (osh->exit == NULL) 2217138079Sharti nsh->exit = estrdup(""); 2218138079Sharti else 2219138079Sharti nsh->exit = estrdup(osh->exit); 2220138079Sharti 2221138079Sharti return (nsh); 2222138079Sharti} 2223138079Sharti 2224144467Sharti/** 2225144467Sharti * JobFreeShell 2226144467Sharti * Free a shell structure and all associated strings. 2227138079Sharti */ 2228138079Shartistatic void 2229144483ShartiJobFreeShell(struct Shell *sh) 2230138079Sharti{ 2231138079Sharti 2232138079Sharti if (sh != NULL) { 2233138079Sharti free(sh->name); 2234138079Sharti free(sh->echoOff); 2235138079Sharti free(sh->echoOn); 2236138079Sharti free(sh->noPrint); 2237138079Sharti free(sh->errCheck); 2238138079Sharti free(sh->ignErr); 2239138079Sharti free(sh->echo); 2240138079Sharti free(sh->exit); 2241138079Sharti free(sh); 2242138079Sharti } 2243138079Sharti} 2244138079Sharti 2245136840Sruvoid 2246136840SruShell_Init(void) 2247136840Sru{ 2248138079Sharti 2249144467Sharti if (commandShell == NULL) 2250144467Sharti commandShell = JobMatchShell(shells[DEFSHELL].name); 2251138079Sharti 2252144467Sharti if (shellPath == NULL) { 2253144467Sharti /* 2254144467Sharti * The user didn't specify a shell to use, so we are using the 2255144467Sharti * default one... Both the absolute path and the last component 2256144467Sharti * must be set. The last component is taken from the 'name' 2257144467Sharti * field of the default shell description pointed-to by 2258144467Sharti * commandShell. All default shells are located in 2259144467Sharti * PATH_DEFSHELLDIR. 2260144467Sharti */ 2261144467Sharti shellName = commandShell->name; 2262144467Sharti shellPath = str_concat(PATH_DEFSHELLDIR, shellName, 2263144467Sharti STR_ADDSLASH); 2264144467Sharti } 2265136840Sru} 2266136840Sru 2267144467Sharti/** 2268144467Sharti * Job_Init 2269137572Sphk * Initialize the process module, given a maximum number of jobs. 22701590Srgrimes * 22711590Srgrimes * Side Effects: 22721590Srgrimes * lists and counters are initialized 22731590Srgrimes */ 22741590Srgrimesvoid 2275137572SphkJob_Init(int maxproc) 22761590Srgrimes{ 2277144467Sharti GNode *begin; /* node for commands to do at the very start */ 2278144467Sharti const char *env; 2279144467Sharti struct sigaction sa; 22801590Srgrimes 2281144467Sharti fifoFd = -1; 2282144467Sharti env = getenv("MAKE_JOBS_FIFO"); 2283137606Sphk 2284144467Sharti if (env == NULL && maxproc > 1) { 2285144467Sharti /* 2286144467Sharti * We did not find the environment variable so we are the 2287144467Sharti * leader. Create the fifo, open it, write one char per 2288144467Sharti * allowed job into the pipe. 2289144467Sharti */ 2290144467Sharti mktemp(fifoName); 2291144467Sharti if (!mkfifo(fifoName, 0600)) { 2292144467Sharti fifoFd = open(fifoName, O_RDWR | O_NONBLOCK, 0); 2293144467Sharti if (fifoFd >= 0) { 2294144467Sharti fifoMaster = 1; 2295144467Sharti fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2296144467Sharti env = fifoName; 2297144467Sharti setenv("MAKE_JOBS_FIFO", env, 1); 2298144467Sharti while (maxproc-- > 0) { 2299144467Sharti write(fifoFd, "+", 1); 2300144467Sharti } 2301144467Sharti /* The master make does not get a magic token */ 2302144467Sharti jobFull = TRUE; 2303144467Sharti maxJobs = 0; 2304144467Sharti } else { 2305144467Sharti unlink(fifoName); 2306144467Sharti env = NULL; 2307144467Sharti } 2308137606Sphk } 2309144467Sharti 2310144467Sharti } else if (env != NULL) { 2311144467Sharti /* 2312144467Sharti * We had the environment variable so we are a slave. 2313144467Sharti * Open fifo and give ourselves a magic token which represents 2314144467Sharti * the token our parent make has grabbed to start his make 2315144467Sharti * process. Otherwise the sub-makes would gobble up tokens and 2316144467Sharti * the proper number of tokens to specify to -j would depend 2317144467Sharti * on the depth of the tree and the order of execution. 2318144467Sharti */ 2319144467Sharti fifoFd = open(env, O_RDWR, 0); 2320144467Sharti if (fifoFd >= 0) { 2321144467Sharti fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2322144467Sharti maxJobs = 1; 2323144467Sharti jobFull = FALSE; 2324144467Sharti } 2325137606Sphk } 2326144467Sharti if (fifoFd <= 0) { 2327144467Sharti maxJobs = maxproc; 2328144467Sharti jobFull = FALSE; 2329144467Sharti } else { 2330137606Sphk } 2331144467Sharti nJobs = 0; 23321590Srgrimes 2333144467Sharti aborting = 0; 2334144467Sharti errors = 0; 23351590Srgrimes 2336144467Sharti lastNode = NULL; 23371590Srgrimes 2338144467Sharti if ((maxJobs == 1 && fifoFd < 0) || beVerbose == 0) { 2339144467Sharti /* 2340144467Sharti * If only one job can run at a time, there's no need for a 2341144467Sharti * banner, no is there? 2342144467Sharti */ 2343144467Sharti targFmt = ""; 2344144467Sharti } else { 2345144467Sharti targFmt = TARG_FMT; 2346144467Sharti } 2347144467Sharti 2348144467Sharti Shell_Init(); 2349144467Sharti 23501590Srgrimes /* 2351144467Sharti * Catch the four signals that POSIX specifies if they aren't ignored. 2352144467Sharti * JobCatchSignal will just set global variables and hope someone 2353144467Sharti * else is going to handle the interrupt. 23541590Srgrimes */ 2355144467Sharti sa.sa_handler = JobCatchSig; 2356144467Sharti sigemptyset(&sa.sa_mask); 2357144467Sharti sa.sa_flags = 0; 23588874Srgrimes 2359144467Sharti if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 2360144467Sharti sigaction(SIGINT, &sa, NULL); 2361144467Sharti } 2362144467Sharti if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { 2363144467Sharti sigaction(SIGHUP, &sa, NULL); 2364144467Sharti } 2365144467Sharti if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { 2366144467Sharti sigaction(SIGQUIT, &sa, NULL); 2367144467Sharti } 2368144467Sharti if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { 2369144467Sharti sigaction(SIGTERM, &sa, NULL); 2370144467Sharti } 2371144467Sharti /* 2372144467Sharti * There are additional signals that need to be caught and passed if 2373144467Sharti * either the export system wants to be told directly of signals or if 2374144467Sharti * we're giving each job its own process group (since then it won't get 2375144467Sharti * signals from the terminal driver as we own the terminal) 2376144467Sharti */ 2377137202Sharti#if defined(USE_PGRP) 2378144467Sharti if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { 2379144467Sharti sigaction(SIGTSTP, &sa, NULL); 2380144467Sharti } 2381144467Sharti if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) { 2382144467Sharti sigaction(SIGTTOU, &sa, NULL); 2383144467Sharti } 2384144467Sharti if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) { 2385144467Sharti sigaction(SIGTTIN, &sa, NULL); 2386144467Sharti } 2387144467Sharti if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) { 2388144467Sharti sigaction(SIGWINCH, &sa, NULL); 2389144467Sharti } 23901590Srgrimes#endif 23918874Srgrimes 2392104475Sphk#ifdef USE_KQUEUE 2393144467Sharti if ((kqfd = kqueue()) == -1) { 2394144467Sharti Punt("kqueue: %s", strerror(errno)); 2395144467Sharti } 2396104475Sphk#endif 2397104475Sphk 2398144467Sharti begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); 23991590Srgrimes 2400144467Sharti if (begin != NULL) { 2401144467Sharti JobStart(begin, JOB_SPECIAL, (Job *)NULL); 2402144467Sharti while (nJobs) { 2403144467Sharti Job_CatchOutput(0); 2404144467Sharti Job_CatchChildren(!usePipes); 2405144467Sharti } 24061590Srgrimes } 2407144467Sharti postCommands = Targ_FindNode(".END", TARG_CREATE); 24081590Srgrimes} 24091590Srgrimes 2410144467Sharti/** 2411144467Sharti * Job_Full 24121590Srgrimes * See if the job table is full. It is considered full if it is OR 24131590Srgrimes * if we are in the process of aborting OR if we have 24141590Srgrimes * reached/exceeded our local quota. This prevents any more jobs 24151590Srgrimes * from starting up. 24161590Srgrimes * 24171590Srgrimes * Results: 24181590Srgrimes * TRUE if the job table is full, FALSE otherwise 24191590Srgrimes */ 24201590SrgrimesBoolean 2421104696SjmallettJob_Full(void) 24221590Srgrimes{ 2423144467Sharti char c; 2424144467Sharti int i; 2425137606Sphk 2426144467Sharti if (aborting) 2427144467Sharti return (aborting); 2428144467Sharti if (fifoFd >= 0 && jobFull) { 2429144467Sharti i = read(fifoFd, &c, 1); 2430144467Sharti if (i > 0) { 2431144467Sharti maxJobs++; 2432144467Sharti jobFull = FALSE; 2433144467Sharti } 2434137606Sphk } 2435144467Sharti return (jobFull); 24361590Srgrimes} 24371590Srgrimes 2438144467Sharti/** 2439144467Sharti * Job_Empty 24401590Srgrimes * See if the job table is empty. Because the local concurrency may 24411590Srgrimes * be set to 0, it is possible for the job table to become empty, 24421590Srgrimes * while the list of stoppedJobs remains non-empty. In such a case, 24431590Srgrimes * we want to restart as many jobs as we can. 24441590Srgrimes * 24451590Srgrimes * Results: 24461590Srgrimes * TRUE if it is. FALSE if it ain't. 24471590Srgrimes */ 24481590SrgrimesBoolean 2449104696SjmallettJob_Empty(void) 24501590Srgrimes{ 2451144467Sharti if (nJobs == 0) { 2452144494Sharti if (!TAILQ_EMPTY(&stoppedJobs) && !aborting) { 2453144467Sharti /* 2454144467Sharti * The job table is obviously not full if it has no 2455144467Sharti * jobs in it...Try and restart the stopped jobs. 2456144467Sharti */ 2457144467Sharti jobFull = FALSE; 2458144467Sharti JobRestartJobs(); 2459144467Sharti return (FALSE); 2460144467Sharti } else { 2461144467Sharti return (TRUE); 2462144467Sharti } 24631590Srgrimes } else { 2464144467Sharti return (FALSE); 24651590Srgrimes } 24661590Srgrimes} 24671590Srgrimes 2468144467Sharti/** 2469144467Sharti * JobMatchShell 24701590Srgrimes * Find a matching shell in 'shells' given its final component. 24711590Srgrimes * 24721590Srgrimes * Results: 2473138334Sharti * A pointer to a freshly allocated Shell structure with a copy 2474138228Sharti * of the static structure or NULL if no shell with the given name 2475138228Sharti * is found. 24761590Srgrimes */ 2477144483Shartistatic struct Shell * 2478138228ShartiJobMatchShell(const char *name) 24791590Srgrimes{ 2480144467Sharti const struct CShell *sh; /* Pointer into shells table */ 2481144483Sharti struct Shell *nsh; 24821590Srgrimes 2483144467Sharti for (sh = shells; sh < shells + sizeof(shells)/sizeof(shells[0]); sh++) 2484144467Sharti if (strcmp(sh->name, name) == 0) 2485144467Sharti break; 24861590Srgrimes 2487144467Sharti if (sh == shells + sizeof(shells)/sizeof(shells[0])) 2488144467Sharti return (NULL); 2489138228Sharti 2490144467Sharti /* make a copy */ 2491144467Sharti nsh = emalloc(sizeof(*nsh)); 2492138228Sharti 2493144467Sharti nsh->name = estrdup(sh->name); 2494144467Sharti nsh->echoOff = estrdup(sh->echoOff); 2495144467Sharti nsh->echoOn = estrdup(sh->echoOn); 2496144467Sharti nsh->hasEchoCtl = sh->hasEchoCtl; 2497144467Sharti nsh->noPrint = estrdup(sh->noPrint); 2498144467Sharti nsh->hasErrCtl = sh->hasErrCtl; 2499144467Sharti nsh->errCheck = estrdup(sh->errCheck); 2500144467Sharti nsh->ignErr = estrdup(sh->ignErr); 2501144467Sharti nsh->echo = estrdup(sh->echo); 2502144467Sharti nsh->exit = estrdup(sh->exit); 2503138228Sharti 2504144467Sharti return (nsh); 25051590Srgrimes} 25061590Srgrimes 2507144467Sharti/** 2508144467Sharti * Job_ParseShell 25091590Srgrimes * Parse a shell specification and set up commandShell, shellPath 25101590Srgrimes * and shellName appropriately. 25111590Srgrimes * 25121590Srgrimes * Results: 25131590Srgrimes * FAILURE if the specification was incorrect. 25141590Srgrimes * 25151590Srgrimes * Side Effects: 25161590Srgrimes * commandShell points to a Shell structure (either predefined or 25171590Srgrimes * created from the shell spec), shellPath is the full path of the 25181590Srgrimes * shell described by commandShell, while shellName is just the 25191590Srgrimes * final component of shellPath. 25201590Srgrimes * 25211590Srgrimes * Notes: 25221590Srgrimes * A shell specification consists of a .SHELL target, with dependency 25231590Srgrimes * operator, followed by a series of blank-separated words. Double 25241590Srgrimes * quotes can be used to use blanks in words. A backslash escapes 25251590Srgrimes * anything (most notably a double-quote and a space) and 25261590Srgrimes * provides the functionality it does in C. Each word consists of 25271590Srgrimes * keyword and value separated by an equal sign. There should be no 25281590Srgrimes * unnecessary spaces in the word. The keywords are as follows: 25291590Srgrimes * name Name of shell. 25301590Srgrimes * path Location of shell. Overrides "name" if given 25311590Srgrimes * quiet Command to turn off echoing. 25321590Srgrimes * echo Command to turn echoing on 25331590Srgrimes * filter Result of turning off echoing that shouldn't be 25341590Srgrimes * printed. 25351590Srgrimes * echoFlag Flag to turn echoing on at the start 25361590Srgrimes * errFlag Flag to turn error checking on at the start 25371590Srgrimes * hasErrCtl True if shell has error checking control 25381590Srgrimes * check Command to turn on error checking if hasErrCtl 25391590Srgrimes * is TRUE or template of command to echo a command 25401590Srgrimes * for which error checking is off if hasErrCtl is 25411590Srgrimes * FALSE. 25421590Srgrimes * ignore Command to turn off error checking if hasErrCtl 25431590Srgrimes * is TRUE or template of command to execute a 25441590Srgrimes * command so as to ignore any errors it returns if 25451590Srgrimes * hasErrCtl is FALSE. 25461590Srgrimes */ 25471590SrgrimesReturnStatus 2548104696SjmallettJob_ParseShell(char *line) 25491590Srgrimes{ 2550144467Sharti char **words; 2551144467Sharti int wordCount; 2552144467Sharti char **argv; 2553144467Sharti int argc; 2554144467Sharti char *path; 2555144741Sharti char *eq; 2556144467Sharti Boolean fullSpec = FALSE; 2557144483Sharti struct Shell newShell; 2558144483Sharti struct Shell *sh; 25591590Srgrimes 2560144467Sharti while (isspace((unsigned char)*line)) { 2561144467Sharti line++; 2562144467Sharti } 2563144467Sharti words = brk_string(line, &wordCount, TRUE); 25641590Srgrimes 2565144467Sharti memset(&newShell, 0, sizeof(newShell)); 2566144741Sharti path = NULL; 25678874Srgrimes 25681590Srgrimes /* 2569144741Sharti * Parse the specification by keyword but skip the first word - it 2570144741Sharti * is not set by brk_string. 25711590Srgrimes */ 2572144741Sharti wordCount--; 2573144741Sharti words++; 2574144741Sharti 2575144741Sharti for (argc = wordCount, argv = words; argc != 0; argc--, argv++) { 2576144741Sharti /* 2577144741Sharti * Split keyword and value 2578144741Sharti */ 2579144741Sharti if ((eq = strchr(*argv, '=')) == NULL) { 2580144741Sharti Parse_Error(PARSE_FATAL, "missing '=' in shell " 2581144741Sharti "specification keyword '%s'", *argv); 2582144741Sharti return (FAILURE); 2583144741Sharti } 2584144741Sharti *eq++ = '\0'; 2585144741Sharti 2586144741Sharti if (strcmp(*argv, "path") == 0) { 2587144741Sharti path = eq; 2588144741Sharti } else if (strcmp(*argv, "name") == 0) { 2589144741Sharti newShell.name = eq; 2590144741Sharti } else if (strcmp(*argv, "quiet") == 0) { 2591144741Sharti newShell.echoOff = eq; 2592144741Sharti fullSpec = TRUE; 2593144741Sharti } else if (strcmp(*argv, "echo") == 0) { 2594144741Sharti newShell.echoOn = eq; 2595144741Sharti fullSpec = TRUE; 2596144741Sharti } else if (strcmp(*argv, "filter") == 0) { 2597144741Sharti newShell.noPrint = eq; 2598144741Sharti fullSpec = TRUE; 2599144741Sharti } else if (strcmp(*argv, "echoFlag") == 0) { 2600144741Sharti newShell.echo = eq; 2601144741Sharti fullSpec = TRUE; 2602144741Sharti } else if (strcmp(*argv, "errFlag") == 0) { 2603144741Sharti newShell.exit = eq; 2604144741Sharti fullSpec = TRUE; 2605144741Sharti } else if (strcmp(*argv, "hasErrCtl") == 0) { 2606144741Sharti newShell.hasErrCtl = (*eq == 'Y' || *eq == 'y' || 2607144741Sharti *eq == 'T' || *eq == 't'); 2608144741Sharti fullSpec = TRUE; 2609144741Sharti } else if (strcmp(*argv, "check") == 0) { 2610144741Sharti newShell.errCheck = eq; 2611144741Sharti fullSpec = TRUE; 2612144741Sharti } else if (strcmp(*argv, "ignore") == 0) { 2613144741Sharti newShell.ignErr = eq; 2614144741Sharti fullSpec = TRUE; 2615144467Sharti } else { 2616144741Sharti Parse_Error(PARSE_FATAL, "unknown keyword in shell " 2617144741Sharti "specification '%s'", *argv); 2618144741Sharti return (FAILURE); 2619144467Sharti } 26201590Srgrimes } 2621138079Sharti 26221590Srgrimes /* 2623144467Sharti * Some checks (could be more) 26241590Srgrimes */ 2625144467Sharti if (fullSpec) { 2626144467Sharti if ((newShell.echoOn != NULL) ^ (newShell.echoOff != NULL)) 2627144467Sharti Parse_Error(PARSE_FATAL, "Shell must have either both " 2628144467Sharti "echoOff and echoOn or none of them"); 2629144467Sharti 2630144467Sharti if (newShell.echoOn != NULL && newShell.echoOff) 2631144467Sharti newShell.hasEchoCtl = TRUE; 26321590Srgrimes } 2633138079Sharti 2634144467Sharti if (path == NULL) { 2635144467Sharti /* 2636144467Sharti * If no path was given, the user wants one of the pre-defined 2637144467Sharti * shells, yes? So we find the one s/he wants with the help of 2638144467Sharti * JobMatchShell and set things up the right way. shellPath 2639144467Sharti * will be set up by Job_Init. 2640144467Sharti */ 2641144467Sharti if (newShell.name == NULL) { 2642144467Sharti Parse_Error(PARSE_FATAL, 2643144467Sharti "Neither path nor name specified"); 2644144467Sharti return (FAILURE); 2645144467Sharti } 2646144467Sharti if ((sh = JobMatchShell(newShell.name)) == NULL) { 2647144467Sharti Parse_Error(PARSE_FATAL, "%s: no matching shell", 2648144467Sharti newShell.name); 2649144467Sharti return (FAILURE); 2650144467Sharti } 2651144467Sharti 26521590Srgrimes } else { 2653144467Sharti /* 2654144467Sharti * The user provided a path. If s/he gave nothing else 2655144467Sharti * (fullSpec is FALSE), try and find a matching shell in the 2656144467Sharti * ones we know of. Else we just take the specification at its 2657144467Sharti * word and copy it to a new location. In either case, we need 2658144467Sharti * to record the path the user gave for the shell. 2659144467Sharti */ 2660144467Sharti free(shellPath); 2661144467Sharti shellPath = estrdup(path); 2662144467Sharti if (newShell.name == NULL) { 2663144467Sharti /* get the base name as the name */ 2664144467Sharti path = strrchr(path, '/'); 2665144467Sharti if (path == NULL) { 2666144467Sharti path = shellPath; 2667144467Sharti } else { 2668144467Sharti path += 1; 2669144467Sharti } 2670144467Sharti newShell.name = path; 2671144467Sharti } 2672144467Sharti 2673144467Sharti if (!fullSpec) { 2674144467Sharti if ((sh = JobMatchShell(newShell.name)) == NULL) { 2675144467Sharti Parse_Error(PARSE_FATAL, 2676144467Sharti "%s: no matching shell", newShell.name); 2677144467Sharti return (FAILURE); 2678144467Sharti } 2679144467Sharti } else { 2680144467Sharti sh = JobCopyShell(&newShell); 2681144467Sharti } 26821590Srgrimes } 26831590Srgrimes 2684144467Sharti /* set the new shell */ 2685144467Sharti JobFreeShell(commandShell); 2686144467Sharti commandShell = sh; 26878874Srgrimes 2688144467Sharti shellName = commandShell->name; 26898874Srgrimes 2690144467Sharti return (SUCCESS); 26911590Srgrimes} 26921590Srgrimes 2693144467Sharti/** 2694144467Sharti * JobInterrupt 26951590Srgrimes * Handle the receipt of an interrupt. 26961590Srgrimes * 26971590Srgrimes * Side Effects: 26981590Srgrimes * All children are killed. Another job will be started if the 26991590Srgrimes * .INTERRUPT target was given. 27001590Srgrimes */ 27011590Srgrimesstatic void 2702104696SjmallettJobInterrupt(int runINTERRUPT, int signo) 27031590Srgrimes{ 2704144467Sharti Job *job; /* job descriptor in that element */ 2705144467Sharti GNode *interrupt; /* the node describing the .INTERRUPT target */ 27068874Srgrimes 2707144467Sharti aborting = ABORT_INTERRUPT; 27081590Srgrimes 2709144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2710144467Sharti if (!Targ_Precious(job->node)) { 2711144467Sharti char *file = (job->node->path == NULL ? 2712144467Sharti job->node->name : job->node->path); 2713144467Sharti 2714144467Sharti if (!noExecute && eunlink(file) != -1) { 2715144467Sharti Error("*** %s removed", file); 2716144467Sharti } 2717144467Sharti } 2718144467Sharti if (job->pid) { 2719144467Sharti DEBUGF(JOB, ("JobInterrupt passing signal to child " 2720144665Sharti "%jd.\n", (intmax_t)job->pid)); 2721144467Sharti KILL(job->pid, signo); 2722144467Sharti } 27231590Srgrimes } 272418730Ssteve 2725144467Sharti if (runINTERRUPT && !touchFlag) { 2726144467Sharti /* 2727144467Sharti * clear the interrupted flag because we would get an 2728144467Sharti * infinite loop otherwise. 2729144467Sharti */ 2730144467Sharti interrupted = 0; 2731137605Sharti 2732144467Sharti interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 2733144467Sharti if (interrupt != NULL) { 2734144467Sharti ignoreErrors = FALSE; 27351590Srgrimes 2736144467Sharti JobStart(interrupt, JOB_IGNDOTS, (Job *)NULL); 2737144467Sharti while (nJobs) { 2738144467Sharti Job_CatchOutput(0); 2739144467Sharti Job_CatchChildren(!usePipes); 2740144467Sharti } 2741144467Sharti } 27421590Srgrimes } 27431590Srgrimes} 27441590Srgrimes 2745144467Sharti/** 2746144467Sharti * Job_Finish 27471590Srgrimes * Do final processing such as the running of the commands 27488874Srgrimes * attached to the .END target. 27491590Srgrimes * 27501590Srgrimes * Results: 27511590Srgrimes * Number of errors reported. 27521590Srgrimes */ 27531590Srgrimesint 2754104696SjmallettJob_Finish(void) 27551590Srgrimes{ 2756138232Sharti 2757144467Sharti if (postCommands != NULL && !Lst_IsEmpty(&postCommands->commands)) { 2758144467Sharti if (errors) { 2759144467Sharti Error("Errors reported so .END ignored"); 2760144467Sharti } else { 2761144467Sharti JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL); 27621590Srgrimes 2763144467Sharti while (nJobs) { 2764144467Sharti Job_CatchOutput(0); 2765144467Sharti Job_CatchChildren(!usePipes); 2766144467Sharti } 2767144467Sharti } 27681590Srgrimes } 2769144467Sharti if (fifoFd >= 0) { 2770144467Sharti close(fifoFd); 2771144467Sharti fifoFd = -1; 2772144467Sharti if (fifoMaster) 2773144467Sharti unlink(fifoName); 2774144467Sharti } 2775144467Sharti return (errors); 27761590Srgrimes} 27771590Srgrimes 2778144467Sharti/** 2779144467Sharti * Job_Wait 27801590Srgrimes * Waits for all running jobs to finish and returns. Sets 'aborting' 27811590Srgrimes * to ABORT_WAIT to prevent other jobs from starting. 27821590Srgrimes * 27831590Srgrimes * Side Effects: 27841590Srgrimes * Currently running jobs finish. 27851590Srgrimes */ 27861590Srgrimesvoid 2787104696SjmallettJob_Wait(void) 27881590Srgrimes{ 2789138232Sharti 2790144467Sharti aborting = ABORT_WAIT; 2791144467Sharti while (nJobs != 0) { 2792144467Sharti Job_CatchOutput(0); 2793144467Sharti Job_CatchChildren(!usePipes); 2794144467Sharti } 2795144467Sharti aborting = 0; 27961590Srgrimes} 27971590Srgrimes 2798144467Sharti/** 2799144467Sharti * Job_AbortAll 28001590Srgrimes * Abort all currently running jobs without handling output or anything. 28011590Srgrimes * This function is to be called only in the event of a major 28021590Srgrimes * error. Most definitely NOT to be called from JobInterrupt. 28031590Srgrimes * 28041590Srgrimes * Side Effects: 28051590Srgrimes * All children are killed, not just the firstborn 28061590Srgrimes */ 28071590Srgrimesvoid 2808104696SjmallettJob_AbortAll(void) 28091590Srgrimes{ 2810144467Sharti Job *job; /* the job descriptor in that element */ 2811144467Sharti int foo; 28128874Srgrimes 2813144467Sharti aborting = ABORT_ERROR; 28148874Srgrimes 2815144467Sharti if (nJobs) { 2816144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2817144467Sharti /* 2818144467Sharti * kill the child process with increasingly drastic 2819144467Sharti * signals to make darn sure it's dead. 2820144467Sharti */ 2821144467Sharti KILL(job->pid, SIGINT); 2822144467Sharti KILL(job->pid, SIGKILL); 2823144467Sharti } 28241590Srgrimes } 28258874Srgrimes 2826144467Sharti /* 2827144467Sharti * Catch as many children as want to report in at first, then give up 2828144467Sharti */ 2829144467Sharti while (waitpid((pid_t)-1, &foo, WNOHANG) > 0) 2830144665Sharti ; 28311590Srgrimes} 283218730Ssteve 2833144467Sharti/** 2834144467Sharti * JobRestartJobs 283518730Ssteve * Tries to restart stopped jobs if there are slots available. 283618730Ssteve * Note that this tries to restart them regardless of pending errors. 283718730Ssteve * It's not good to leave stopped jobs lying around! 283818730Ssteve * 283918730Ssteve * Side Effects: 284018730Ssteve * Resumes(and possibly migrates) jobs. 284118730Ssteve */ 284218730Sstevestatic void 2843104696SjmallettJobRestartJobs(void) 284418730Ssteve{ 2845144494Sharti Job *job; 2846144494Sharti 2847144494Sharti while (!jobFull && (job = TAILQ_FIRST(&stoppedJobs)) != NULL) { 2848144467Sharti DEBUGF(JOB, ("Job queue is not full. " 2849144467Sharti "Restarting a stopped job.\n")); 2850144494Sharti TAILQ_REMOVE(&stoppedJobs, job, link); 2851144494Sharti JobRestart(job); 2852144467Sharti } 285318730Ssteve} 2854