job.c revision 146061
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 146061 2005-05-10 14:13:20Z 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" 121146056Sharti#include "config.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" 130146056Sharti#include "suff.h" 131141104Sharti#include "targ.h" 132141104Sharti#include "util.h" 133141104Sharti#include "var.h" 1341590Srgrimes 135146057Sharti#define TMPPAT "/tmp/makeXXXXXXXXXX" 136146057Sharti 137146057Sharti#ifndef USE_KQUEUE 1381590Srgrimes/* 139146057Sharti * The SEL_ constants determine the maximum amount of time spent in select 140146057Sharti * before coming out to see if a child has finished. SEL_SEC is the number of 141146057Sharti * seconds and SEL_USEC is the number of micro-seconds 142146057Sharti */ 143146057Sharti#define SEL_SEC 2 144146057Sharti#define SEL_USEC 0 145146057Sharti#endif /* !USE_KQUEUE */ 146146057Sharti 147146057Sharti/* 148144483Sharti * Job Table definitions. 149144483Sharti * 150144483Sharti * The job "table" is kept as a linked Lst in 'jobs', with the number of 151144483Sharti * active jobs maintained in the 'nJobs' variable. At no time will this 152144483Sharti * exceed the value of 'maxJobs', initialized by the Job_Init function. 153144483Sharti * 154144483Sharti * When a job is finished, the Make_Update function is called on each of the 155144483Sharti * parents of the node which was just remade. This takes care of the upward 156144483Sharti * traversal of the dependency graph. 157144483Sharti */ 158144483Sharti#define JOB_BUFSIZE 1024 159144483Shartitypedef struct Job { 160144665Sharti pid_t pid; /* The child's process ID */ 161144483Sharti 162144483Sharti struct GNode *node; /* The target the child is making */ 163144483Sharti 164144483Sharti /* 165144483Sharti * A LstNode for the first command to be saved after the job completes. 166144483Sharti * This is NULL if there was no "..." in the job's commands. 167144483Sharti */ 168144483Sharti LstNode *tailCmds; 169144483Sharti 170144483Sharti /* 171144483Sharti * An FILE* for writing out the commands. This is only 172144483Sharti * used before the job is actually started. 173144483Sharti */ 174144483Sharti FILE *cmdFILE; 175144483Sharti 176144483Sharti /* 177144483Sharti * A word of flags which determine how the module handles errors, 178144483Sharti * echoing, etc. for the job 179144483Sharti */ 180144483Sharti short flags; /* Flags to control treatment of job */ 181144483Sharti#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ 182144483Sharti#define JOB_SILENT 0x002 /* no output */ 183144483Sharti#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally 184144483Sharti * if we can't export it and maxLocal is 0 */ 185146061Sharti#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing 186144483Sharti * commands */ 187144483Sharti#define JOB_FIRST 0x020 /* Job is first job for the node */ 188144483Sharti#define JOB_RESTART 0x080 /* Job needs to be completely restarted */ 189144483Sharti#define JOB_RESUME 0x100 /* Job needs to be resumed b/c it stopped, 190144483Sharti * for some reason */ 191144483Sharti#define JOB_CONTINUING 0x200 /* We are in the process of resuming this job. 192144483Sharti * Used to avoid infinite recursion between 193144483Sharti * JobFinish and JobRestart */ 194144483Sharti 195144483Sharti /* union for handling shell's output */ 196144483Sharti union { 197144483Sharti /* 198144483Sharti * This part is used when usePipes is true. 199146061Sharti * The output is being caught via a pipe and the descriptors 200144483Sharti * of our pipe, an array in which output is line buffered and 201144483Sharti * the current position in that buffer are all maintained for 202144483Sharti * each job. 203144483Sharti */ 204144483Sharti struct { 205144483Sharti /* 206144483Sharti * Input side of pipe associated with 207144483Sharti * job's output channel 208144483Sharti */ 209144483Sharti int op_inPipe; 210144483Sharti 211144483Sharti /* 212144483Sharti * Output side of pipe associated with job's 213144483Sharti * output channel 214144483Sharti */ 215144483Sharti int op_outPipe; 216144483Sharti 217144483Sharti /* 218144483Sharti * Buffer for storing the output of the 219144483Sharti * job, line by line 220144483Sharti */ 221144483Sharti char op_outBuf[JOB_BUFSIZE + 1]; 222144483Sharti 223144483Sharti /* Current position in op_outBuf */ 224144483Sharti int op_curPos; 225144483Sharti } o_pipe; 226144483Sharti 227144483Sharti /* 228144483Sharti * If usePipes is false the output is routed to a temporary 229144483Sharti * file and all that is kept is the name of the file and the 230144483Sharti * descriptor open to the file. 231144483Sharti */ 232144483Sharti struct { 233144483Sharti /* Name of file to which shell output was rerouted */ 234144483Sharti char of_outFile[sizeof(TMPPAT)]; 235144483Sharti 236144483Sharti /* 237144483Sharti * Stream open to the output file. Used to funnel all 238144483Sharti * from a single job to one file while still allowing 239144483Sharti * multiple shell invocations 240144483Sharti */ 241144483Sharti int of_outFd; 242144483Sharti } o_file; 243144483Sharti 244144483Sharti } output; /* Data for tracking a shell's output */ 245144494Sharti 246144494Sharti TAILQ_ENTRY(Job) link; /* list link */ 247144483Sharti} Job; 248144483Sharti 249146061Sharti#define outPipe output.o_pipe.op_outPipe 250146061Sharti#define inPipe output.o_pipe.op_inPipe 251144483Sharti#define outBuf output.o_pipe.op_outBuf 252144483Sharti#define curPos output.o_pipe.op_curPos 253144483Sharti#define outFile output.o_file.of_outFile 254146061Sharti#define outFd output.o_file.of_outFd 255144483Sharti 256144494ShartiTAILQ_HEAD(JobList, Job); 257144494Sharti 258144483Sharti/* 259144483Sharti * Shell Specifications: 260144483Sharti * 261144483Sharti * Some special stuff goes on if a shell doesn't have error control. In such 262144483Sharti * a case, errCheck becomes a printf template for echoing the command, 263144483Sharti * should echoing be on and ignErr becomes another printf template for 264144483Sharti * executing the command while ignoring the return status. If either of these 265144483Sharti * strings is empty when hasErrCtl is FALSE, the command will be executed 266144483Sharti * anyway as is and if it causes an error, so be it. 267144483Sharti */ 268144483Sharti#define DEF_SHELL_STRUCT(TAG, CONST) \ 269144483Shartistruct TAG { \ 270144483Sharti /* \ 271144483Sharti * the name of the shell. For Bourne and C shells, this is used \ 272144483Sharti * only to find the shell description when used as the single \ 273144483Sharti * source of a .SHELL target. For user-defined shells, this is \ 274144483Sharti * the full path of the shell. \ 275144483Sharti */ \ 276144483Sharti CONST char *name; \ 277144483Sharti \ 278144483Sharti /* True if both echoOff and echoOn defined */ \ 279144483Sharti Boolean hasEchoCtl; \ 280144483Sharti \ 281144483Sharti CONST char *echoOff; /* command to turn off echo */ \ 282144483Sharti CONST char *echoOn; /* command to turn it back on */\ 283144483Sharti \ 284144483Sharti /* \ 285144483Sharti * What the shell prints, and its length, when given the \ 286144483Sharti * echo-off command. This line will not be printed when \ 287144483Sharti * received from the shell. This is usually the command which \ 288144483Sharti * was executed to turn off echoing \ 289144483Sharti */ \ 290144483Sharti CONST char *noPrint; \ 291144483Sharti \ 292144483Sharti /* set if can control error checking for individual commands */ \ 293144483Sharti Boolean hasErrCtl; \ 294144483Sharti \ 295144483Sharti /* string to turn error checking on */ \ 296144483Sharti CONST char *errCheck; \ 297144483Sharti \ 298144483Sharti /* string to turn off error checking */ \ 299144483Sharti CONST char *ignErr; \ 300144483Sharti \ 301144483Sharti CONST char *echo; /* command line flag: echo commands */ \ 302144483Sharti CONST char *exit; /* command line flag: exit on error */ \ 303144483Sharti} 304144483Sharti 305144483ShartiDEF_SHELL_STRUCT(Shell,); 306144483ShartiDEF_SHELL_STRUCT(CShell, const); 307144483Sharti 308144483Sharti/* 3098874Srgrimes * error handling variables 3101590Srgrimes */ 311144467Shartistatic int errors = 0; /* number of errors reported */ 312144467Shartistatic int aborting = 0; /* why is the make aborting? */ 313144467Sharti#define ABORT_ERROR 1 /* Because of an error */ 314144467Sharti#define ABORT_INTERRUPT 2 /* Because it was interrupted */ 315144467Sharti#define ABORT_WAIT 3 /* Waiting for jobs to finish */ 3161590Srgrimes 31718730Ssteve/* 31818730Ssteve * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file 31918730Ssteve * is a char! So when we go above 127 we turn negative! 32018730Ssteve */ 321138232Sharti#define FILENO(a) ((unsigned)fileno(a)) 3221590Srgrimes 3231590Srgrimes/* 3241590Srgrimes * post-make command processing. The node postCommands is really just the 3251590Srgrimes * .END target but we keep it around to avoid having to search for it 3261590Srgrimes * all the time. 3271590Srgrimes */ 328144467Shartistatic GNode *postCommands; 3291590Srgrimes 3301590Srgrimes/* 331144467Sharti * The number of commands actually printed for a target. Should this 332144467Sharti * number be 0, no shell will be executed. 333144467Sharti */ 334144467Shartistatic int numCommands; 335144467Sharti 336144467Sharti/* 3371590Srgrimes * Return values from JobStart. 3381590Srgrimes */ 339144467Sharti#define JOB_RUNNING 0 /* Job is running */ 340146061Sharti#define JOB_ERROR 1 /* Error in starting the job */ 341144467Sharti#define JOB_FINISHED 2 /* The job is already finished */ 342144467Sharti#define JOB_STOPPED 3 /* The job is stopped */ 3431590Srgrimes 3441590Srgrimes/* 3451590Srgrimes * Descriptions for various shells. 3461590Srgrimes */ 347144483Shartistatic const struct CShell shells[] = { 348144467Sharti /* 349144467Sharti * CSH description. The csh can do echo control by playing 350144467Sharti * with the setting of the 'echo' shell variable. Sadly, 351144467Sharti * however, it is unable to do error control nicely. 352144467Sharti */ 353144467Sharti { 354144467Sharti "csh", 355144741Sharti TRUE, "unset verbose", "set verbose", "unset verbose", 356144467Sharti FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"", 357144467Sharti "v", "e", 358144467Sharti }, 359144467Sharti /* 360144467Sharti * SH description. Echo control is also possible and, under 361144467Sharti * sun UNIX anyway, one can even control error checking. 362144467Sharti */ 363144467Sharti { 364144467Sharti "sh", 365144741Sharti TRUE, "set -", "set -v", "set -", 366144467Sharti TRUE, "set -e", "set +e", 36718730Ssteve#ifdef OLDBOURNESHELL 368144467Sharti FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n", 36918730Ssteve#endif 370144467Sharti "v", "e", 371144467Sharti }, 372144467Sharti /* 373144467Sharti * KSH description. The Korn shell has a superset of 374144467Sharti * the Bourne shell's functionality. 375144467Sharti */ 376144467Sharti { 377144467Sharti "ksh", 378144741Sharti TRUE, "set -", "set -v", "set -", 379144467Sharti TRUE, "set -e", "set +e", 380144467Sharti "v", "e", 381144467Sharti }, 3821590Srgrimes}; 3831590Srgrimes 384144467Sharti/* 385144467Sharti * This is the shell to which we pass all commands in the Makefile. 386144467Sharti * It is set by the Job_ParseShell function. 387144467Sharti */ 388144483Shartistatic struct Shell *commandShell = NULL; 389146059Shartistatic char *shellPath = NULL; /* full pathname of executable image */ 390146059Shartistatic char *shellName = NULL; /* last component of shell */ 3911590Srgrimes 392144467Shartiint maxJobs; /* The most children we can run at once */ 393144656Shartistatic int nJobs; /* The number of children currently running */ 394138916Sharti 395138916Sharti/* The structures that describe them */ 396144494Shartistatic struct JobList jobs = TAILQ_HEAD_INITIALIZER(jobs); 397138916Sharti 398146061Shartistatic Boolean jobFull; /* Flag to tell when the job table is full. It 3991590Srgrimes * is set TRUE when (1) the total number of 400137572Sphk * running jobs equals the maximum allowed */ 401104475Sphk#ifdef USE_KQUEUE 402104475Sphkstatic int kqfd; /* File descriptor obtained by kqueue() */ 403104475Sphk#else 404146061Shartistatic fd_set outputs; /* Set of descriptors of pipes connected to 4051590Srgrimes * the output channels of children */ 4061590Srgrimes#endif 4071590Srgrimes 408146061Shartistatic GNode *lastNode; /* The node for which output was most recently 4091590Srgrimes * produced. */ 410146061Shartistatic const char *targFmt; /* Format string to use to head output from a 4111590Srgrimes * job when it's not the most-recent job heard 4121590Srgrimes * from */ 4131590Srgrimes 414137202Sharti#define TARG_FMT "--- %s ---\n" /* Default format */ 415137202Sharti#define MESSAGE(fp, gn) \ 416138232Sharti fprintf(fp, targFmt, gn->name); 41718730Ssteve 4181590Srgrimes/* 419137252Sharti * When JobStart attempts to run a job but isn't allowed to 420137252Sharti * or when Job_CatchChildren detects a job that has 421137252Sharti * been stopped somehow, the job is placed on the stoppedJobs queue to be run 4228874Srgrimes * when the next job finishes. 423138916Sharti * 424138916Sharti * Lst of Job structures describing jobs that were stopped due to 425138916Sharti * concurrency limits or externally 4261590Srgrimes */ 427144494Shartistatic struct JobList stoppedJobs = TAILQ_HEAD_INITIALIZER(stoppedJobs); 4281590Srgrimes 429144656Shartistatic int fifoFd; /* Fd of our job fifo */ 430144656Shartistatic char fifoName[] = "/tmp/make_fifo_XXXXXXXXX"; 431144656Shartistatic int fifoMaster; 4321590Srgrimes 433137605Shartistatic sig_atomic_t interrupted; 434137605Sharti 435137605Sharti 4361590Srgrimes#if defined(USE_PGRP) && defined(SYSV) 43718730Ssteve# define KILL(pid, sig) killpg(-(pid), (sig)) 4381590Srgrimes#else 4391590Srgrimes# if defined(USE_PGRP) 44018730Ssteve# define KILL(pid, sig) killpg((pid), (sig)) 4411590Srgrimes# else 44218730Ssteve# define KILL(pid, sig) kill((pid), (sig)) 4431590Srgrimes# endif 4441590Srgrimes#endif 4451590Srgrimes 44618730Ssteve/* 44718730Ssteve * Grmpf... There is no way to set bits of the wait structure 44818730Ssteve * anymore with the stupid W*() macros. I liked the union wait 44918730Ssteve * stuff much more. So, we devise our own macros... This is 45018730Ssteve * really ugly, use dramamine sparingly. You have been warned. 45118730Ssteve */ 452103503Sjmallett#define W_SETMASKED(st, val, fun) \ 45318730Ssteve { \ 454138232Sharti int sh = (int)~0; \ 45518730Ssteve int mask = fun(sh); \ 45618730Ssteve \ 45718730Ssteve for (sh = 0; ((mask >> sh) & 1) == 0; sh++) \ 45818730Ssteve continue; \ 45918730Ssteve *(st) = (*(st) & ~mask) | ((val) << sh); \ 46018730Ssteve } 46118730Ssteve 462103503Sjmallett#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG) 463103503Sjmallett#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) 46418730Ssteve 46592921Simpstatic void JobRestart(Job *); 46692921Simpstatic int JobStart(GNode *, int, Job *); 46792921Simpstatic void JobDoOutput(Job *, Boolean); 468144483Shartistatic struct Shell *JobMatchShell(const char *); 46992921Simpstatic void JobInterrupt(int, int); 47092921Simpstatic void JobRestartJobs(void); 4711590Srgrimes 472144467Sharti/** 473137605Sharti * JobCatchSignal 474144467Sharti * Got a signal. Set global variables and hope that someone will 475144467Sharti * handle it. 476137605Sharti */ 477137605Shartistatic void 478137605ShartiJobCatchSig(int signo) 479137605Sharti{ 480137605Sharti 481137605Sharti interrupted = signo; 482137605Sharti} 483137605Sharti 484144467Sharti/** 4851590Srgrimes * JobPassSig -- 486137252Sharti * Pass a signal on to all local jobs if 4871590Srgrimes * USE_PGRP is defined, then die ourselves. 4881590Srgrimes * 4891590Srgrimes * Side Effects: 4901590Srgrimes * We die by the same signal. 4911590Srgrimes */ 4921590Srgrimesstatic void 493104696SjmallettJobPassSig(int signo) 4941590Srgrimes{ 495144741Sharti Job *job; 496144467Sharti sigset_t nmask, omask; 497144467Sharti struct sigaction act; 4988874Srgrimes 499144467Sharti sigemptyset(&nmask); 500144467Sharti sigaddset(&nmask, signo); 501144467Sharti sigprocmask(SIG_SETMASK, &nmask, &omask); 502137605Sharti 503144467Sharti DEBUGF(JOB, ("JobPassSig(%d) called.\n", signo)); 504144741Sharti TAILQ_FOREACH(job, &jobs, link) { 505144741Sharti DEBUGF(JOB, ("JobPassSig passing signal %d to child %jd.\n", 506144741Sharti signo, (intmax_t)job->pid)); 507144741Sharti KILL(job->pid, signo); 508144741Sharti } 5091590Srgrimes 510144467Sharti /* 511144467Sharti * Deal with proper cleanup based on the signal received. We only run 512144467Sharti * the .INTERRUPT target if the signal was in fact an interrupt. 513144467Sharti * The other three termination signals are more of a "get out *now*" 514144467Sharti * command. 515144467Sharti */ 516144467Sharti if (signo == SIGINT) { 517144467Sharti JobInterrupt(TRUE, signo); 518144657Sharti } else if (signo == SIGHUP || signo == SIGTERM || signo == SIGQUIT) { 519144467Sharti JobInterrupt(FALSE, signo); 520144467Sharti } 5218874Srgrimes 522144467Sharti /* 523144467Sharti * Leave gracefully if SIGQUIT, rather than core dumping. 524144467Sharti */ 525144467Sharti if (signo == SIGQUIT) { 526144467Sharti signo = SIGINT; 527144467Sharti } 5288874Srgrimes 529144467Sharti /* 530144467Sharti * Send ourselves the signal now we've given the message to everyone 531144467Sharti * else. Note we block everything else possible while we're getting 532144467Sharti * the signal. This ensures that all our jobs get continued when we 533144467Sharti * wake up before we take any other signal. 534144467Sharti * XXX this comment seems wrong. 535144467Sharti */ 536144467Sharti act.sa_handler = SIG_DFL; 537144467Sharti sigemptyset(&act.sa_mask); 538144467Sharti act.sa_flags = 0; 539144467Sharti sigaction(signo, &act, NULL); 5401590Srgrimes 541144467Sharti DEBUGF(JOB, ("JobPassSig passing signal to self, mask = %x.\n", 542144467Sharti ~0 & ~(1 << (signo - 1)))); 543144467Sharti signal(signo, SIG_DFL); 5441590Srgrimes 545144467Sharti KILL(getpid(), signo); 54618730Ssteve 547144467Sharti signo = SIGCONT; 548144741Sharti TAILQ_FOREACH(job, &jobs, link) { 549144741Sharti DEBUGF(JOB, ("JobPassSig passing signal %d to child %jd.\n", 550144741Sharti signo, (intmax_t)job->pid)); 551144741Sharti KILL(job->pid, signo); 552144741Sharti } 5531590Srgrimes 554144467Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 555144467Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 556144467Sharti act.sa_handler = JobPassSig; 557144467Sharti sigaction(signo, &act, NULL); 5581590Srgrimes} 5591590Srgrimes 560144467Sharti/** 5611590Srgrimes * JobPrintCommand -- 5621590Srgrimes * Put out another command for the given job. If the command starts 5631590Srgrimes * with an @ or a - we process it specially. In the former case, 5641590Srgrimes * so long as the -s and -n flags weren't given to make, we stick 5651590Srgrimes * a shell-specific echoOff command in the script. In the latter, 5661590Srgrimes * we ignore errors for the entire job, unless the shell has error 5671590Srgrimes * control. 5681590Srgrimes * If the command is just "..." we take all future commands for this 5691590Srgrimes * job to be commands to be executed once the entire graph has been 5701590Srgrimes * made and return non-zero to signal that the end of the commands 5711590Srgrimes * was reached. These commands are later attached to the postCommands 57294594Sobrien * node and executed by Job_Finish when all things are done. 573142993Sharti * This function is called from JobStart via LST_FOREACH. 5741590Srgrimes * 5751590Srgrimes * Results: 5761590Srgrimes * Always 0, unless the command was "..." 5771590Srgrimes * 5781590Srgrimes * Side Effects: 5791590Srgrimes * If the command begins with a '-' and the shell has no error control, 5801590Srgrimes * the JOB_IGNERR flag is set in the job descriptor. 5811590Srgrimes * If the command is "..." and we're not ignoring such things, 5821590Srgrimes * tailCmds is set to the successor node of the cmd. 5831590Srgrimes * numCommands is incremented if the command is actually printed. 5841590Srgrimes */ 5851590Srgrimesstatic int 586144741ShartiJobPrintCommand(char *cmd, Job *job) 5871590Srgrimes{ 588144467Sharti Boolean noSpecials; /* true if we shouldn't worry about 589141258Sharti * inserting special commands into 590141258Sharti * the input stream. */ 591144467Sharti Boolean shutUp = FALSE; /* true if we put a no echo command 592141258Sharti * into the command file */ 593144467Sharti Boolean errOff = FALSE; /* true if we turned error checking 594141258Sharti * off before printing the command 595141258Sharti * and need to turn it back on */ 596144467Sharti const char *cmdTemplate;/* Template to use when printing the command */ 597144467Sharti char *cmdStart; /* Start of expanded command */ 598144467Sharti LstNode *cmdNode; /* Node for replacing the command */ 5991590Srgrimes 600144467Sharti noSpecials = (noExecute && !(job->node->type & OP_MAKE)); 6011590Srgrimes 602144467Sharti if (strcmp(cmd, "...") == 0) { 603144467Sharti job->node->type |= OP_SAVE_CMDS; 604144467Sharti if ((job->flags & JOB_IGNDOTS) == 0) { 605144467Sharti job->tailCmds = 606144467Sharti Lst_Succ(Lst_Member(&job->node->commands, cmd)); 607144467Sharti return (1); 608144467Sharti } 609144467Sharti return (0); 6101590Srgrimes } 6111590Srgrimes 612144467Sharti#define DBPRINTF(fmt, arg) \ 613144467Sharti DEBUGF(JOB, (fmt, arg)); \ 614144467Sharti fprintf(job->cmdFILE, fmt, arg); \ 615144467Sharti fflush(job->cmdFILE); 6161590Srgrimes 617144467Sharti numCommands += 1; 6181590Srgrimes 619144467Sharti /* 620144467Sharti * For debugging, we replace each command with the result of expanding 621144467Sharti * the variables in the command. 622144467Sharti */ 623144467Sharti cmdNode = Lst_Member(&job->node->commands, cmd); 624142457Sharti 625146027Sharti cmd = Buf_Peel(Var_Subst(cmd, job->node, FALSE)); 626144467Sharti cmdStart = cmd; 627142457Sharti 628144467Sharti Lst_Replace(cmdNode, cmdStart); 6291590Srgrimes 630144467Sharti cmdTemplate = "%s\n"; 6311590Srgrimes 632144467Sharti /* 633144467Sharti * Check for leading @', -' or +'s to control echoing, error checking, 634144467Sharti * and execution on -n. 635144467Sharti */ 636144467Sharti while (*cmd == '@' || *cmd == '-' || *cmd == '+') { 637144467Sharti switch (*cmd) { 638132839Sharti 639144467Sharti case '@': 640144467Sharti shutUp = DEBUG(LOUD) ? FALSE : TRUE; 641144467Sharti break; 642132839Sharti 643144467Sharti case '-': 644144467Sharti errOff = TRUE; 645144467Sharti break; 646132839Sharti 647144467Sharti case '+': 648144467Sharti if (noSpecials) { 649144467Sharti /* 650144467Sharti * We're not actually exececuting anything... 651144467Sharti * but this one needs to be - use compat mode 652144467Sharti * just for it. 653144467Sharti */ 654144741Sharti Compat_RunCommand(cmd, job->node); 655144467Sharti return (0); 656144467Sharti } 657144467Sharti break; 658144467Sharti } 659144467Sharti cmd++; 6601590Srgrimes } 6611590Srgrimes 662144467Sharti while (isspace((unsigned char)*cmd)) 663144467Sharti cmd++; 6641590Srgrimes 665144467Sharti if (shutUp) { 666144467Sharti if (!(job->flags & JOB_SILENT) && !noSpecials && 6671590Srgrimes commandShell->hasEchoCtl) { 66818730Ssteve DBPRINTF("%s\n", commandShell->echoOff); 6691590Srgrimes } else { 670144467Sharti shutUp = FALSE; 6711590Srgrimes } 672144467Sharti } 673144467Sharti 674144467Sharti if (errOff) { 675144467Sharti if (!(job->flags & JOB_IGNERR) && !noSpecials) { 676144467Sharti if (commandShell->hasErrCtl) { 677144467Sharti /* 678144467Sharti * We don't want the error-control commands 679144467Sharti * showing up either, so we turn off echoing 680144467Sharti * while executing them. We could put another 681144467Sharti * field in the shell structure to tell 682144467Sharti * JobDoOutput to look for this string too, 683144467Sharti * but why make it any more complex than 684144467Sharti * it already is? 685144467Sharti */ 686144467Sharti if (!(job->flags & JOB_SILENT) && !shutUp && 687144467Sharti commandShell->hasEchoCtl) { 688144467Sharti DBPRINTF("%s\n", commandShell->echoOff); 689144467Sharti DBPRINTF("%s\n", commandShell->ignErr); 690144467Sharti DBPRINTF("%s\n", commandShell->echoOn); 691144467Sharti } else { 692144467Sharti DBPRINTF("%s\n", commandShell->ignErr); 693144467Sharti } 694144467Sharti } else if (commandShell->ignErr && 695144657Sharti *commandShell->ignErr != '\0') { 696144467Sharti /* 697144467Sharti * The shell has no error control, so we need to 698144467Sharti * be weird to get it to ignore any errors from 699144467Sharti * the command. If echoing is turned on, we turn 700144467Sharti * it off and use the errCheck template to echo 701144467Sharti * the command. Leave echoing off so the user 702144467Sharti * doesn't see the weirdness we go through to 703144467Sharti * ignore errors. Set cmdTemplate to use the 704144467Sharti * weirdness instead of the simple "%s\n" 705144467Sharti * template. 706144467Sharti */ 707144467Sharti if (!(job->flags & JOB_SILENT) && !shutUp && 708144467Sharti commandShell->hasEchoCtl) { 709144467Sharti DBPRINTF("%s\n", commandShell->echoOff); 710144467Sharti DBPRINTF(commandShell->errCheck, cmd); 711144467Sharti shutUp = TRUE; 712144467Sharti } 713144467Sharti cmdTemplate = commandShell->ignErr; 714144467Sharti /* 715144467Sharti * The error ignoration (hee hee) is already 716144467Sharti * taken care of by the ignErr template, so 717144467Sharti * pretend error checking is still on. 718144467Sharti */ 719144467Sharti errOff = FALSE; 720144467Sharti } else { 721144467Sharti errOff = FALSE; 722144467Sharti } 723144467Sharti } else { 724144467Sharti errOff = FALSE; 725144467Sharti } 726144467Sharti } 727144467Sharti 728144467Sharti DBPRINTF(cmdTemplate, cmd); 729144467Sharti 730144467Sharti if (errOff) { 7311590Srgrimes /* 732144467Sharti * If echoing is already off, there's no point in issuing the 733144467Sharti * echoOff command. Otherwise we issue it and pretend it was on 734144467Sharti * for the whole command... 7351590Srgrimes */ 736144467Sharti if (!shutUp && !(job->flags & JOB_SILENT) && 7371590Srgrimes commandShell->hasEchoCtl) { 73818730Ssteve DBPRINTF("%s\n", commandShell->echoOff); 7391590Srgrimes shutUp = TRUE; 7401590Srgrimes } 741144467Sharti DBPRINTF("%s\n", commandShell->errCheck); 7421590Srgrimes } 743144467Sharti if (shutUp) { 744144467Sharti DBPRINTF("%s\n", commandShell->echoOn); 7451590Srgrimes } 746144467Sharti return (0); 7471590Srgrimes} 7481590Srgrimes 749144467Sharti/** 75018730Ssteve * JobClose -- 75118730Ssteve * Called to close both input and output pipes when a job is finished. 75218730Ssteve * 75318730Ssteve * Side Effects: 75418730Ssteve * The file descriptors associated with the job are closed. 75518730Ssteve */ 75618730Sstevestatic void 757104696SjmallettJobClose(Job *job) 75818730Ssteve{ 759138232Sharti 760144467Sharti if (usePipes) { 761137202Sharti#if !defined(USE_KQUEUE) 762144467Sharti FD_CLR(job->inPipe, &outputs); 76318730Ssteve#endif 764144467Sharti if (job->outPipe != job->inPipe) { 765144467Sharti close(job->outPipe); 766144467Sharti } 767144467Sharti JobDoOutput(job, TRUE); 768144467Sharti close(job->inPipe); 769144467Sharti } else { 770144467Sharti close(job->outFd); 771144467Sharti JobDoOutput(job, TRUE); 77218730Ssteve } 77318730Ssteve} 77418730Ssteve 775144467Sharti/** 7761590Srgrimes * JobFinish -- 7771590Srgrimes * Do final processing for the given job including updating 7781590Srgrimes * parents and starting new jobs as available/necessary. Note 7791590Srgrimes * that we pay no attention to the JOB_IGNERR flag here. 7801590Srgrimes * This is because when we're called because of a noexecute flag 7811590Srgrimes * or something, jstat.w_status is 0 and when called from 7821590Srgrimes * Job_CatchChildren, the status is zeroed if it s/b ignored. 7831590Srgrimes * 7841590Srgrimes * Side Effects: 7851590Srgrimes * Some nodes may be put on the toBeMade queue. 7861590Srgrimes * Final commands for the job are placed on postCommands. 7871590Srgrimes * 7881590Srgrimes * If we got an error and are aborting (aborting == ABORT_ERROR) and 7891590Srgrimes * the job list is now empty, we are done for the day. 7901590Srgrimes * If we recognized an error (errors !=0), we set the aborting flag 7911590Srgrimes * to ABORT_ERROR so no more jobs will be started. 7921590Srgrimes */ 7931590Srgrimesstatic void 794104696SjmallettJobFinish(Job *job, int *status) 7951590Srgrimes{ 796144467Sharti Boolean done; 797144467Sharti LstNode *ln; 7981590Srgrimes 799144657Sharti if ((WIFEXITED(*status) && WEXITSTATUS(*status) != 0 && 800144657Sharti !(job->flags & JOB_IGNERR)) || 801144657Sharti (WIFSIGNALED(*status) && WTERMSIG(*status) != SIGCONT)) { 802144467Sharti /* 803144467Sharti * If it exited non-zero and either we're doing things our 804144467Sharti * way or we're not ignoring errors, the job is finished. 805144467Sharti * Similarly, if the shell died because of a signal 806144467Sharti * the job is also finished. In these cases, finish out the 807144467Sharti * job's output before printing the exit status... 808144467Sharti */ 809144467Sharti JobClose(job); 810144467Sharti if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 811144467Sharti fclose(job->cmdFILE); 812144467Sharti } 813144467Sharti done = TRUE; 8148874Srgrimes 815144467Sharti } else if (WIFEXITED(*status)) { 816144467Sharti /* 817144467Sharti * Deal with ignored errors in -B mode. We need to print a 818144467Sharti * message telling of the ignored error as well as setting 819144467Sharti * status.w_status to 0 so the next command gets run. To do 820144467Sharti * this, we set done to be TRUE if in -B mode and the job 821144467Sharti * exited non-zero. 822144467Sharti */ 823144467Sharti done = WEXITSTATUS(*status) != 0; 8248874Srgrimes 825144467Sharti /* 826144467Sharti * Old comment said: "Note we don't want to close down any of 827144467Sharti * the streams until we know we're at the end." But we do. 828144467Sharti * Otherwise when are we going to print the rest of the stuff? 829144467Sharti */ 830144467Sharti JobClose(job); 8311590Srgrimes } else { 832144467Sharti /* 833144467Sharti * No need to close things down or anything. 834144467Sharti */ 835144467Sharti done = FALSE; 8361590Srgrimes } 8371590Srgrimes 838144467Sharti if (done || WIFSTOPPED(*status) || 839144657Sharti (WIFSIGNALED(*status) && WTERMSIG(*status) == SIGCONT) || 840144467Sharti DEBUG(JOB)) { 841144467Sharti FILE *out; 842144467Sharti 843144467Sharti if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) { 844144467Sharti /* 845144467Sharti * If output is going to a file and this job is ignoring 846144467Sharti * errors, arrange to have the exit status sent to the 847144467Sharti * output file as well. 848144467Sharti */ 849144467Sharti out = fdopen(job->outFd, "w"); 850144467Sharti if (out == NULL) 851144467Sharti Punt("Cannot fdopen"); 852144467Sharti } else { 853144467Sharti out = stdout; 8541590Srgrimes } 8551590Srgrimes 856144467Sharti if (WIFEXITED(*status)) { 857144665Sharti DEBUGF(JOB, ("Process %jd exited.\n", 858144665Sharti (intmax_t)job->pid)); 859144467Sharti if (WEXITSTATUS(*status) != 0) { 860144467Sharti if (usePipes && job->node != lastNode) { 861144467Sharti MESSAGE(out, job->node); 862144467Sharti lastNode = job->node; 863144467Sharti } 864144467Sharti fprintf(out, "*** Error code %d%s\n", 865144467Sharti WEXITSTATUS(*status), 866144467Sharti (job->flags & JOB_IGNERR) ? 867144467Sharti "(ignored)" : ""); 868144467Sharti 869144467Sharti if (job->flags & JOB_IGNERR) { 870144467Sharti *status = 0; 871144467Sharti } 872144467Sharti } else if (DEBUG(JOB)) { 873144467Sharti if (usePipes && job->node != lastNode) { 874144467Sharti MESSAGE(out, job->node); 875144467Sharti lastNode = job->node; 876144467Sharti } 877144467Sharti fprintf(out, "*** Completed successfully\n"); 878144467Sharti } 879144467Sharti 880144467Sharti } else if (WIFSTOPPED(*status)) { 881144665Sharti DEBUGF(JOB, ("Process %jd stopped.\n", 882144665Sharti (intmax_t)job->pid)); 883144467Sharti if (usePipes && job->node != lastNode) { 884144467Sharti MESSAGE(out, job->node); 885144467Sharti lastNode = job->node; 886144467Sharti } 887144467Sharti fprintf(out, "*** Stopped -- signal %d\n", 888144467Sharti WSTOPSIG(*status)); 889144467Sharti job->flags |= JOB_RESUME; 890144494Sharti TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 891144467Sharti fflush(out); 892144467Sharti return; 893144467Sharti 894144467Sharti } else if (WTERMSIG(*status) == SIGCONT) { 895144467Sharti /* 896144467Sharti * If the beastie has continued, shift the Job from 897144467Sharti * the stopped list to the running one (or re-stop it 898144467Sharti * if concurrency is exceeded) and go and get another 899144467Sharti * child. 900144467Sharti */ 901144657Sharti if (job->flags & (JOB_RESUME | JOB_RESTART)) { 902144467Sharti if (usePipes && job->node != lastNode) { 903144467Sharti MESSAGE(out, job->node); 904144467Sharti lastNode = job->node; 905144467Sharti } 906144467Sharti fprintf(out, "*** Continued\n"); 907144467Sharti } 908144467Sharti if (!(job->flags & JOB_CONTINUING)) { 909144665Sharti DEBUGF(JOB, ("Warning: process %jd was not " 910144665Sharti "continuing.\n", (intmax_t)job->pid)); 91118730Ssteve#ifdef notdef 912144467Sharti /* 913144467Sharti * We don't really want to restart a job from 914144467Sharti * scratch just because it continued, especially 915144467Sharti * not without killing the continuing process! 916144467Sharti * That's why this is ifdef'ed out. 917144467Sharti * FD - 9/17/90 918144467Sharti */ 919144467Sharti JobRestart(job); 92018730Ssteve#endif 921144467Sharti } 922144467Sharti job->flags &= ~JOB_CONTINUING; 923144494Sharti TAILQ_INSERT_TAIL(&jobs, job, link); 924144467Sharti nJobs += 1; 925144665Sharti DEBUGF(JOB, ("Process %jd is continuing locally.\n", 926144665Sharti (intmax_t)job->pid)); 927144467Sharti if (nJobs == maxJobs) { 928144467Sharti jobFull = TRUE; 929144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 930144467Sharti } 931144467Sharti fflush(out); 932144467Sharti return; 9331590Srgrimes 934144467Sharti } else { 935144467Sharti if (usePipes && job->node != lastNode) { 936144467Sharti MESSAGE(out, job->node); 937144467Sharti lastNode = job->node; 938144467Sharti } 939144467Sharti fprintf(out, "*** Signal %d\n", WTERMSIG(*status)); 940144467Sharti } 9411590Srgrimes 942144467Sharti fflush(out); 9431590Srgrimes } 9441590Srgrimes 9451590Srgrimes /* 946144467Sharti * Now handle the -B-mode stuff. If the beast still isn't finished, 947144467Sharti * try and restart the job on the next command. If JobStart says it's 948144467Sharti * ok, it's ok. If there's an error, this puppy is done. 9491590Srgrimes */ 950144467Sharti if (compatMake && WIFEXITED(*status) && 951144467Sharti Lst_Succ(job->node->compat_command) != NULL) { 952144467Sharti switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) { 953144467Sharti case JOB_RUNNING: 954144467Sharti done = FALSE; 955144467Sharti break; 956144467Sharti case JOB_ERROR: 957144467Sharti done = TRUE; 958144467Sharti W_SETEXITSTATUS(status, 1); 959144467Sharti break; 960144467Sharti case JOB_FINISHED: 961144467Sharti /* 962144467Sharti * If we got back a JOB_FINISHED code, JobStart has 963144467Sharti * already called Make_Update and freed the job 964144467Sharti * descriptor. We set done to false here to avoid fake 965144467Sharti * cycles and double frees. JobStart needs to do the 966144467Sharti * update so we can proceed up the graph when given 967144467Sharti * the -n flag.. 968144467Sharti */ 969144467Sharti done = FALSE; 970144467Sharti break; 971144467Sharti default: 972144467Sharti break; 973144467Sharti } 974144467Sharti } else { 975144467Sharti done = TRUE; 9761590Srgrimes } 977143703Sharti 978144657Sharti if (done && aborting != ABORT_ERROR && 979144657Sharti aborting != ABORT_INTERRUPT && *status == 0) { 980144467Sharti /* 981144467Sharti * As long as we aren't aborting and the job didn't return a 982144467Sharti * non-zero status that we shouldn't ignore, we call 983144467Sharti * Make_Update to update the parents. In addition, any saved 984144467Sharti * commands for the node are placed on the .END target. 985144467Sharti */ 986144467Sharti for (ln = job->tailCmds; ln != NULL; ln = LST_NEXT(ln)) { 987144467Sharti Lst_AtEnd(&postCommands->commands, 988146027Sharti Buf_Peel( 989146027Sharti Var_Subst(Lst_Datum(ln), job->node, FALSE))); 990144467Sharti } 9911590Srgrimes 992144467Sharti job->node->made = MADE; 993144467Sharti Make_Update(job->node); 994144467Sharti free(job); 9951590Srgrimes 996144467Sharti } else if (*status != 0) { 997144467Sharti errors += 1; 998144467Sharti free(job); 999144467Sharti } 1000144467Sharti 1001144467Sharti JobRestartJobs(); 1002144467Sharti 10031590Srgrimes /* 1004144467Sharti * Set aborting if any error. 10051590Srgrimes */ 1006144657Sharti if (errors && !keepgoing && aborting != ABORT_INTERRUPT) { 1007144467Sharti /* 1008144467Sharti * If we found any errors in this batch of children and the -k 1009144467Sharti * flag wasn't given, we set the aborting flag so no more jobs 1010144467Sharti * get started. 1011144467Sharti */ 1012144467Sharti aborting = ABORT_ERROR; 1013144467Sharti } 10148874Srgrimes 1015144657Sharti if (aborting == ABORT_ERROR && Job_Empty()) { 1016144467Sharti /* 1017144467Sharti * If we are aborting and the job table is now empty, we finish. 1018144467Sharti */ 1019144467Sharti Finish(errors); 1020144467Sharti } 10211590Srgrimes} 10221590Srgrimes 1023144467Sharti/** 1024144467Sharti * Job_Touch 10251590Srgrimes * Touch the given target. Called by JobStart when the -t flag was 1026104696Sjmallett * given. Prints messages unless told to be silent. 10271590Srgrimes * 10281590Srgrimes * Side Effects: 10291590Srgrimes * The data modification of the file is changed. In addition, if the 10301590Srgrimes * file did not exist, it is created. 10311590Srgrimes */ 10321590Srgrimesvoid 1033104696SjmallettJob_Touch(GNode *gn, Boolean silent) 10341590Srgrimes{ 1035144467Sharti int streamID; /* ID of stream opened to do the touch */ 1036144467Sharti struct utimbuf times; /* Times for utime() call */ 10371590Srgrimes 1038144467Sharti if (gn->type & (OP_JOIN | OP_USE | OP_EXEC | OP_OPTIONAL)) { 1039144467Sharti /* 1040144467Sharti * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" 1041144467Sharti * targets and, as such, shouldn't really be created. 1042144467Sharti */ 1043144467Sharti return; 1044144467Sharti } 10458874Srgrimes 1046144467Sharti if (!silent) { 1047144467Sharti fprintf(stdout, "touch %s\n", gn->name); 1048144467Sharti fflush(stdout); 1049144467Sharti } 10501590Srgrimes 1051144467Sharti if (noExecute) { 1052144467Sharti return; 1053144467Sharti } 10541590Srgrimes 1055144467Sharti if (gn->type & OP_ARCHV) { 1056144467Sharti Arch_Touch(gn); 1057144467Sharti } else if (gn->type & OP_LIB) { 1058144467Sharti Arch_TouchLib(gn); 1059144467Sharti } else { 1060144467Sharti char *file = gn->path ? gn->path : gn->name; 10611590Srgrimes 1062144467Sharti times.actime = times.modtime = now; 1063144467Sharti if (utime(file, ×) < 0) { 1064144467Sharti streamID = open(file, O_RDWR | O_CREAT, 0666); 10651590Srgrimes 1066144467Sharti if (streamID >= 0) { 1067144467Sharti char c; 10681590Srgrimes 1069144467Sharti /* 1070144467Sharti * Read and write a byte to the file to change 1071144467Sharti * the modification time, then close the file. 1072144467Sharti */ 1073144467Sharti if (read(streamID, &c, 1) == 1) { 1074144467Sharti lseek(streamID, (off_t)0, SEEK_SET); 1075144467Sharti write(streamID, &c, 1); 1076144467Sharti } 1077144467Sharti 1078144467Sharti close(streamID); 1079144467Sharti } else { 1080144467Sharti fprintf(stdout, "*** couldn't touch %s: %s", 1081144467Sharti file, strerror(errno)); 1082144467Sharti fflush(stdout); 1083144467Sharti } 10841590Srgrimes } 10851590Srgrimes } 10861590Srgrimes} 10871590Srgrimes 1088144467Sharti/** 1089144467Sharti * Job_CheckCommands 10908874Srgrimes * Make sure the given node has all the commands it needs. 10911590Srgrimes * 10921590Srgrimes * Results: 10931590Srgrimes * TRUE if the commands list is/was ok. 10941590Srgrimes * 10951590Srgrimes * Side Effects: 10961590Srgrimes * The node will have commands from the .DEFAULT rule added to it 10971590Srgrimes * if it needs them. 10981590Srgrimes */ 10991590SrgrimesBoolean 1100104696SjmallettJob_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) 11011590Srgrimes{ 1102138232Sharti 1103144467Sharti if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) && 1104144467Sharti (gn->type & OP_LIB) == 0) { 1105144467Sharti /* 1106144467Sharti * No commands. Look for .DEFAULT rule from which we might infer 1107144467Sharti * commands. 1108144467Sharti */ 1109144657Sharti if (DEFAULT != NULL && !Lst_IsEmpty(&DEFAULT->commands)) { 1110144467Sharti char *p1; 1111144467Sharti /* 1112144467Sharti * Make only looks for a .DEFAULT if the node was 1113144467Sharti * never the target of an operator, so that's what we 1114144467Sharti * do too. If a .DEFAULT was given, we substitute its 1115144467Sharti * commands for gn's commands and set the IMPSRC 1116144467Sharti * variable to be the target's name The DEFAULT node 1117144467Sharti * acts like a transformation rule, in that gn also 1118144467Sharti * inherits any attributes or sources attached to 1119144467Sharti * .DEFAULT itself. 1120144467Sharti */ 1121144467Sharti Make_HandleUse(DEFAULT, gn); 1122144467Sharti Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn); 1123144467Sharti free(p1); 112418730Ssteve 1125144467Sharti } else if (Dir_MTime(gn) == 0) { 1126144467Sharti /* 1127144467Sharti * The node wasn't the target of an operator we have 1128144467Sharti * no .DEFAULT rule to go on and the target doesn't 1129144467Sharti * already exist. There's nothing more we can do for 1130144467Sharti * this branch. If the -k flag wasn't given, we stop 1131144467Sharti * in our tracks, otherwise we just don't update 1132144467Sharti * this node's parents so they never get examined. 1133144467Sharti */ 1134144467Sharti static const char msg[] = 1135144467Sharti "make: don't know how to make"; 1136144467Sharti 1137144467Sharti if (gn->type & OP_OPTIONAL) { 1138144467Sharti fprintf(stdout, "%s %s(ignored)\n", 1139144467Sharti msg, gn->name); 1140144467Sharti fflush(stdout); 1141144467Sharti } else if (keepgoing) { 1142144467Sharti fprintf(stdout, "%s %s(continuing)\n", 1143144467Sharti msg, gn->name); 1144144467Sharti fflush(stdout); 1145144467Sharti return (FALSE); 1146144467Sharti } else { 114735483Simp#if OLD_JOKE 1148144467Sharti if (strcmp(gn->name,"love") == 0) 1149144467Sharti (*abortProc)("Not war."); 1150144467Sharti else 115135483Simp#endif 1152144467Sharti (*abortProc)("%s %s. Stop", 1153144467Sharti msg, gn->name); 1154144467Sharti return (FALSE); 1155144467Sharti } 1156144467Sharti } 11571590Srgrimes } 1158144467Sharti return (TRUE); 11591590Srgrimes} 11601590Srgrimes 1161144467Sharti/** 1162144467Sharti * JobExec 11631590Srgrimes * Execute the shell for the given job. Called from JobStart and 11641590Srgrimes * JobRestart. 11651590Srgrimes * 11661590Srgrimes * Side Effects: 11671590Srgrimes * A shell is executed, outputs is altered and the Job structure added 11681590Srgrimes * to the job table. 11691590Srgrimes */ 11701590Srgrimesstatic void 1171104696SjmallettJobExec(Job *job, char **argv) 11721590Srgrimes{ 1173146061Sharti pid_t cpid; /* ID of new child */ 11748874Srgrimes 1175144467Sharti if (DEBUG(JOB)) { 1176146061Sharti int i; 11778874Srgrimes 1178144467Sharti DEBUGF(JOB, ("Running %s\n", job->node->name)); 1179144467Sharti DEBUGF(JOB, ("\tCommand: ")); 1180144467Sharti for (i = 0; argv[i] != NULL; i++) { 1181144467Sharti DEBUGF(JOB, ("%s ", argv[i])); 1182144467Sharti } 1183144467Sharti DEBUGF(JOB, ("\n")); 11841590Srgrimes } 11858874Srgrimes 11861590Srgrimes /* 1187144467Sharti * Some jobs produce no output and it's disconcerting to have 1188144467Sharti * no feedback of their running (since they produce no output, the 1189144467Sharti * banner with their name in it never appears). This is an attempt to 1190144467Sharti * provide that feedback, even if nothing follows it. 11911590Srgrimes */ 1192144657Sharti if (lastNode != job->node && (job->flags & JOB_FIRST) && 1193144467Sharti !(job->flags & JOB_SILENT)) { 1194144467Sharti MESSAGE(stdout, job->node); 1195144467Sharti lastNode = job->node; 11961590Srgrimes } 11971590Srgrimes 1198146058Sharti if ((cpid = vfork()) == -1) { 1199144467Sharti Punt("Cannot fork"); 1200146058Sharti } 1201144467Sharti 1202144665Sharti if (cpid == 0) { 1203144665Sharti /* 1204144665Sharti * Child 1205144665Sharti */ 1206144467Sharti if (fifoFd >= 0) 1207144467Sharti close(fifoFd); 1208144467Sharti 1209144467Sharti /* 1210144467Sharti * Must duplicate the input stream down to the child's input and 1211144467Sharti * reset it to the beginning (again). Since the stream was 1212144467Sharti * marked close-on-exec, we must clear that bit in the new 1213144467Sharti * input. 1214144467Sharti */ 1215144467Sharti if (dup2(FILENO(job->cmdFILE), 0) == -1) 1216144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1217144467Sharti fcntl(0, F_SETFD, 0); 1218144467Sharti lseek(0, (off_t)0, SEEK_SET); 1219144467Sharti 1220144467Sharti if (usePipes) { 1221144467Sharti /* 1222144467Sharti * Set up the child's output to be routed through the 1223144467Sharti * pipe we've created for it. 1224144467Sharti */ 1225144467Sharti if (dup2(job->outPipe, 1) == -1) 1226144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1227144467Sharti } else { 1228144467Sharti /* 1229144467Sharti * We're capturing output in a file, so we duplicate the 1230144467Sharti * descriptor to the temporary file into the standard 1231144467Sharti * output. 1232144467Sharti */ 1233144467Sharti if (dup2(job->outFd, 1) == -1) 1234144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1235144467Sharti } 1236144467Sharti /* 1237144467Sharti * The output channels are marked close on exec. This bit was 1238144467Sharti * duplicated by the dup2 (on some systems), so we have to clear 1239144467Sharti * it before routing the shell's error output to the same place 1240144467Sharti * as its standard output. 1241144467Sharti */ 1242144467Sharti fcntl(1, F_SETFD, 0); 1243144467Sharti if (dup2(1, 2) == -1) 1244144467Sharti Punt("Cannot dup2: %s", strerror(errno)); 1245144467Sharti 12461590Srgrimes#ifdef USE_PGRP 1247144467Sharti /* 1248144467Sharti * We want to switch the child into a different process family 1249144467Sharti * so we can kill it and all its descendants in one fell swoop, 1250144467Sharti * by killing its process family, but not commit suicide. 1251144467Sharti */ 125218730Ssteve# if defined(SYSV) 1253144467Sharti setsid(); 125418730Ssteve# else 1255144467Sharti setpgid(0, getpid()); 125618730Ssteve# endif 125718730Ssteve#endif /* USE_PGRP */ 12588874Srgrimes 1259144467Sharti execv(shellPath, argv); 12601590Srgrimes 1261144467Sharti write(STDERR_FILENO, "Could not execute shell\n", 1262144467Sharti sizeof("Could not execute shell")); 1263144467Sharti _exit(1); 1264144665Sharti } 1265144665Sharti /* 1266144665Sharti * Parent 1267144665Sharti */ 1268144665Sharti job->pid = cpid; 1269144467Sharti 1270144665Sharti if (usePipes && (job->flags & JOB_FIRST)) { 1271144665Sharti /* 1272144665Sharti * The first time a job is run for a node, we set the 1273144665Sharti * current position in the buffer to the beginning and 1274144665Sharti * mark another stream to watch in the outputs mask. 1275144665Sharti */ 1276104475Sphk#ifdef USE_KQUEUE 1277144665Sharti struct kevent kev[2]; 1278104475Sphk#endif 1279144665Sharti job->curPos = 0; 12808874Srgrimes 1281137202Sharti#if defined(USE_KQUEUE) 1282144665Sharti EV_SET(&kev[0], job->inPipe, EVFILT_READ, EV_ADD, 0, 0, job); 1283144665Sharti EV_SET(&kev[1], job->pid, EVFILT_PROC, 1284144665Sharti EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, NULL); 1285144665Sharti if (kevent(kqfd, kev, 2, NULL, 0, NULL) != 0) { 1286144665Sharti /* 1287144665Sharti * kevent() will fail if the job is already 1288144665Sharti * finished 1289144665Sharti */ 1290144665Sharti if (errno != EINTR && errno != EBADF && errno != ESRCH) 1291144665Sharti Punt("kevent: %s", strerror(errno)); 1292144665Sharti } 12931590Srgrimes#else 1294144665Sharti FD_SET(job->inPipe, &outputs); 1295137202Sharti#endif /* USE_KQUEUE */ 1296144665Sharti } 1297144467Sharti 1298144665Sharti if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1299144665Sharti fclose(job->cmdFILE); 1300144665Sharti job->cmdFILE = NULL; 13011590Srgrimes } 13021590Srgrimes 1303144467Sharti /* 1304144467Sharti * Now the job is actually running, add it to the table. 1305144467Sharti */ 1306144467Sharti nJobs += 1; 1307144494Sharti TAILQ_INSERT_TAIL(&jobs, job, link); 1308144467Sharti if (nJobs == maxJobs) { 1309144467Sharti jobFull = TRUE; 13101590Srgrimes } 13111590Srgrimes} 13121590Srgrimes 1313144467Sharti/** 1314144467Sharti * JobMakeArgv 13151590Srgrimes * Create the argv needed to execute the shell for a given job. 13161590Srgrimes */ 13171590Srgrimesstatic void 1318104696SjmallettJobMakeArgv(Job *job, char **argv) 13191590Srgrimes{ 1320144467Sharti int argc; 1321144467Sharti static char args[10]; /* For merged arguments */ 13228874Srgrimes 1323144467Sharti argv[0] = shellName; 1324144467Sharti argc = 1; 13251590Srgrimes 1326144657Sharti if ((commandShell->exit && *commandShell->exit != '-') || 1327144657Sharti (commandShell->echo && *commandShell->echo != '-')) { 1328144467Sharti /* 1329144467Sharti * At least one of the flags doesn't have a minus before it, so 1330144467Sharti * merge them together. Have to do this because the *(&(@*#*&#$# 1331144467Sharti * Bourne shell thinks its second argument is a file to source. 1332144467Sharti * Grrrr. Note the ten-character limitation on the combined 1333144467Sharti * arguments. 1334144467Sharti */ 1335144657Sharti sprintf(args, "-%s%s", (job->flags & JOB_IGNERR) ? "" : 1336144657Sharti commandShell->exit ? commandShell->exit : "", 1337144657Sharti (job->flags & JOB_SILENT) ? "" : 1338144657Sharti commandShell->echo ? commandShell->echo : ""); 13391590Srgrimes 1340144467Sharti if (args[1]) { 1341144467Sharti argv[argc] = args; 1342144467Sharti argc++; 1343144467Sharti } 1344144467Sharti } else { 1345144467Sharti if (!(job->flags & JOB_IGNERR) && commandShell->exit) { 1346144467Sharti argv[argc] = commandShell->exit; 1347144467Sharti argc++; 1348144467Sharti } 1349144467Sharti if (!(job->flags & JOB_SILENT) && commandShell->echo) { 1350144467Sharti argv[argc] = commandShell->echo; 1351144467Sharti argc++; 1352144467Sharti } 13531590Srgrimes } 1354144467Sharti argv[argc] = NULL; 13551590Srgrimes} 13561590Srgrimes 1357144467Sharti/** 1358144467Sharti * JobRestart 1359144494Sharti * Restart a job that stopped for some reason. The job must be neither 1360144494Sharti * on the jobs nor on the stoppedJobs list. 13611590Srgrimes * 13621590Srgrimes * Side Effects: 13631590Srgrimes * jobFull will be set if the job couldn't be run. 13641590Srgrimes */ 13651590Srgrimesstatic void 1366104696SjmallettJobRestart(Job *job) 13671590Srgrimes{ 136818730Ssteve 1369144467Sharti if (job->flags & JOB_RESTART) { 1370144467Sharti /* 1371144467Sharti * Set up the control arguments to the shell. This is based on 1372144467Sharti * the flags set earlier for this job. If the JOB_IGNERR flag 1373144467Sharti * is clear, the 'exit' flag of the commandShell is used to 1374144467Sharti * cause it to exit upon receiving an error. If the JOB_SILENT 1375144467Sharti * flag is clear, the 'echo' flag of the commandShell is used 1376144467Sharti * to get it to start echoing as soon as it starts 1377144467Sharti * processing commands. 1378144467Sharti */ 1379144467Sharti char *argv[4]; 13808874Srgrimes 1381144467Sharti JobMakeArgv(job, argv); 13828874Srgrimes 1383144467Sharti DEBUGF(JOB, ("Restarting %s...", job->node->name)); 1384144657Sharti if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) { 1385144467Sharti /* 1386144657Sharti * Not allowed to run -- put it back on the hold 1387144657Sharti * queue and mark the table full 1388144467Sharti */ 1389144467Sharti DEBUGF(JOB, ("holding\n")); 1390144494Sharti TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1391144467Sharti jobFull = TRUE; 1392144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 1393144467Sharti return; 1394144467Sharti } else { 1395144467Sharti /* 1396144467Sharti * Job may be run locally. 1397144467Sharti */ 1398144467Sharti DEBUGF(JOB, ("running locally\n")); 1399144467Sharti } 1400144467Sharti JobExec(job, argv); 1401144467Sharti 1402137202Sharti } else { 14031590Srgrimes /* 1404144467Sharti * The job has stopped and needs to be restarted. 1405144467Sharti * Why it stopped, we don't know... 14061590Srgrimes */ 1407144467Sharti DEBUGF(JOB, ("Resuming %s...", job->node->name)); 1408144657Sharti if ((nJobs < maxJobs || ((job->flags & JOB_SPECIAL) && 1409144657Sharti maxJobs == 0)) && nJobs != maxJobs) { 1410144467Sharti /* 1411144467Sharti * If we haven't reached the concurrency limit already 1412144467Sharti * (or the job must be run and maxJobs is 0), it's ok 1413144467Sharti * to resume it. 1414144467Sharti */ 1415144467Sharti Boolean error; 1416144467Sharti int status; 14178874Srgrimes 1418144467Sharti error = (KILL(job->pid, SIGCONT) != 0); 1419144467Sharti 1420144467Sharti if (!error) { 1421144467Sharti /* 1422144467Sharti * Make sure the user knows we've continued 1423144467Sharti * the beast and actually put the thing in the 1424144467Sharti * job table. 1425144467Sharti */ 1426144467Sharti job->flags |= JOB_CONTINUING; 1427144467Sharti status = 0; 1428144467Sharti W_SETTERMSIG(&status, SIGCONT); 1429144467Sharti JobFinish(job, &status); 1430144467Sharti 1431144467Sharti job->flags &= ~(JOB_RESUME|JOB_CONTINUING); 1432144467Sharti DEBUGF(JOB, ("done\n")); 1433144467Sharti } else { 1434144467Sharti Error("couldn't resume %s: %s", 1435144467Sharti job->node->name, strerror(errno)); 1436144467Sharti status = 0; 1437144467Sharti W_SETEXITSTATUS(&status, 1); 1438144467Sharti JobFinish(job, &status); 1439144467Sharti } 1440144467Sharti } else { 1441144467Sharti /* 1442144467Sharti * Job cannot be restarted. Mark the table as full and 1443144467Sharti * place the job back on the list of stopped jobs. 1444144467Sharti */ 1445144467Sharti DEBUGF(JOB, ("table full\n")); 1446144494Sharti TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1447144467Sharti jobFull = TRUE; 1448144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 1449144467Sharti } 14501590Srgrimes } 14511590Srgrimes} 14521590Srgrimes 1453144467Sharti/** 1454144467Sharti * JobStart 14551590Srgrimes * Start a target-creation process going for the target described 14568874Srgrimes * by the graph node gn. 14571590Srgrimes * 14581590Srgrimes * Results: 14591590Srgrimes * JOB_ERROR if there was an error in the commands, JOB_FINISHED 14601590Srgrimes * if there isn't actually anything left to do for the job and 14611590Srgrimes * JOB_RUNNING if the job has been started. 14621590Srgrimes * 14631590Srgrimes * Side Effects: 14641590Srgrimes * A new Job node is created and added to the list of running 14651590Srgrimes * jobs. PMake is forked and a child shell created. 14661590Srgrimes */ 14671590Srgrimesstatic int 1468104696SjmallettJobStart(GNode *gn, int flags, Job *previous) 14691590Srgrimes{ 1470144467Sharti Job *job; /* new job descriptor */ 1471144467Sharti char *argv[4]; /* Argument vector to shell */ 1472144467Sharti Boolean cmdsOK; /* true if the nodes commands were all right */ 1473144467Sharti Boolean noExec; /* Set true if we decide not to run the job */ 1474144467Sharti int tfd; /* File descriptor for temp file */ 1475144467Sharti LstNode *ln; 1476144654Sharti char tfile[sizeof(TMPPAT)]; 14771590Srgrimes 1478144467Sharti if (interrupted) { 1479144467Sharti JobPassSig(interrupted); 1480144467Sharti return (JOB_ERROR); 1481144467Sharti } 1482144467Sharti if (previous != NULL) { 1483144467Sharti previous->flags &= ~(JOB_FIRST | JOB_IGNERR | JOB_SILENT); 1484144467Sharti job = previous; 1485144467Sharti } else { 1486144467Sharti job = emalloc(sizeof(Job)); 1487144467Sharti flags |= JOB_FIRST; 1488144467Sharti } 14891590Srgrimes 1490144467Sharti job->node = gn; 1491144467Sharti job->tailCmds = NULL; 14921590Srgrimes 14931590Srgrimes /* 1494144467Sharti * Set the initial value of the flags for this job based on the global 1495144467Sharti * ones and the node's attributes... Any flags supplied by the caller 1496144467Sharti * are also added to the field. 14971590Srgrimes */ 1498144467Sharti job->flags = 0; 1499144467Sharti if (Targ_Ignore(gn)) { 1500144467Sharti job->flags |= JOB_IGNERR; 15011590Srgrimes } 1502144467Sharti if (Targ_Silent(gn)) { 1503144467Sharti job->flags |= JOB_SILENT; 1504144467Sharti } 1505144467Sharti job->flags |= flags; 15068874Srgrimes 15071590Srgrimes /* 1508144467Sharti * Check the commands now so any attributes from .DEFAULT have a chance 1509144658Sharti * to migrate to the node. 15101590Srgrimes */ 1511144658Sharti if (!compatMake && (job->flags & JOB_FIRST)) { 1512144467Sharti cmdsOK = Job_CheckCommands(gn, Error); 1513144467Sharti } else { 1514144467Sharti cmdsOK = TRUE; 1515144467Sharti } 15161590Srgrimes 15171590Srgrimes /* 1518144467Sharti * If the -n flag wasn't given, we open up OUR (not the child's) 1519144467Sharti * temporary file to stuff commands in it. The thing is rd/wr so we 1520144467Sharti * don't need to reopen it to feed it to the shell. If the -n flag 1521144467Sharti * *was* given, we just set the file to be stdout. Cute, huh? 15221590Srgrimes */ 1523144467Sharti if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) { 1524144467Sharti /* 1525144467Sharti * We're serious here, but if the commands were bogus, we're 1526144467Sharti * also dead... 1527144467Sharti */ 1528144467Sharti if (!cmdsOK) { 1529144467Sharti DieHorribly(); 1530144467Sharti } 15318874Srgrimes 1532144467Sharti strcpy(tfile, TMPPAT); 1533144467Sharti if ((tfd = mkstemp(tfile)) == -1) 1534144467Sharti Punt("Cannot create temp file: %s", strerror(errno)); 1535144467Sharti job->cmdFILE = fdopen(tfd, "w+"); 1536144467Sharti eunlink(tfile); 1537144467Sharti if (job->cmdFILE == NULL) { 1538144467Sharti close(tfd); 1539144467Sharti Punt("Could not open %s", tfile); 1540144467Sharti } 1541144467Sharti fcntl(FILENO(job->cmdFILE), F_SETFD, 1); 1542144467Sharti /* 1543144467Sharti * Send the commands to the command file, flush all its 1544144467Sharti * buffers then rewind and remove the thing. 1545144467Sharti */ 1546144467Sharti noExec = FALSE; 1547138564Sharti 1548138564Sharti /* 1549144467Sharti * Used to be backwards; replace when start doing multiple 1550144467Sharti * commands per shell. 1551138564Sharti */ 1552144467Sharti if (compatMake) { 1553144467Sharti /* 1554144467Sharti * Be compatible: If this is the first time for this 1555144467Sharti * node, verify its commands are ok and open the 1556144467Sharti * commands list for sequential access by later 1557144467Sharti * invocations of JobStart. Once that is done, we take 1558144467Sharti * the next command off the list and print it to the 1559144467Sharti * command file. If the command was an ellipsis, note 1560144467Sharti * that there's nothing more to execute. 1561144467Sharti */ 1562144467Sharti if (job->flags & JOB_FIRST) 1563144467Sharti gn->compat_command = Lst_First(&gn->commands); 1564144467Sharti else 1565144467Sharti gn->compat_command = 1566144467Sharti Lst_Succ(gn->compat_command); 15678874Srgrimes 1568144467Sharti if (gn->compat_command == NULL || 1569144467Sharti JobPrintCommand(Lst_Datum(gn->compat_command), job)) 1570144467Sharti noExec = TRUE; 1571144467Sharti 1572144467Sharti if (noExec && !(job->flags & JOB_FIRST)) { 1573144467Sharti /* 1574144467Sharti * If we're not going to execute anything, the 1575144467Sharti * job is done and we need to close down the 1576144467Sharti * various file descriptors we've opened for 1577144467Sharti * output, then call JobDoOutput to catch the 1578144467Sharti * final characters or send the file to the 1579144467Sharti * screen... Note that the i/o streams are only 1580144467Sharti * open if this isn't the first job. Note also 1581144467Sharti * that this could not be done in 1582144467Sharti * Job_CatchChildren b/c it wasn't clear if 1583144467Sharti * there were more commands to execute or not... 1584144467Sharti */ 1585144467Sharti JobClose(job); 1586144467Sharti } 1587144467Sharti } else { 1588144467Sharti /* 1589144467Sharti * We can do all the commands at once. hooray for sanity 1590144467Sharti */ 1591144467Sharti numCommands = 0; 1592144467Sharti LST_FOREACH(ln, &gn->commands) { 1593144467Sharti if (JobPrintCommand(Lst_Datum(ln), job)) 1594144467Sharti break; 1595144467Sharti } 1596144467Sharti 1597144467Sharti /* 1598144467Sharti * If we didn't print out any commands to the shell 1599144467Sharti * script, there's not much point in executing the 1600144467Sharti * shell, is there? 1601144467Sharti */ 1602144467Sharti if (numCommands == 0) { 1603144467Sharti noExec = TRUE; 1604144467Sharti } 1605144467Sharti } 1606144467Sharti 1607144467Sharti } else if (noExecute) { 1608144467Sharti /* 1609144467Sharti * Not executing anything -- just print all the commands to 1610144467Sharti * stdout in one fell swoop. This will still set up 1611144467Sharti * job->tailCmds correctly. 1612144467Sharti */ 1613144467Sharti if (lastNode != gn) { 1614144467Sharti MESSAGE(stdout, gn); 1615144467Sharti lastNode = gn; 1616144467Sharti } 1617144467Sharti job->cmdFILE = stdout; 1618144467Sharti 1619144467Sharti /* 1620144467Sharti * Only print the commands if they're ok, but don't die if 1621144467Sharti * they're not -- just let the user know they're bad and keep 1622144467Sharti * going. It doesn't do any harm in this case and may do 1623144467Sharti * some good. 1624144467Sharti */ 1625144467Sharti if (cmdsOK) { 1626144467Sharti LST_FOREACH(ln, &gn->commands) { 1627144467Sharti if (JobPrintCommand(Lst_Datum(ln), job)) 1628144467Sharti break; 1629144467Sharti } 1630144467Sharti } 1631144467Sharti /* 1632144467Sharti * Don't execute the shell, thank you. 1633144467Sharti */ 16341590Srgrimes noExec = TRUE; 1635144467Sharti 1636144467Sharti } else { 1637144467Sharti /* 1638144467Sharti * Just touch the target and note that no shell should be 1639144467Sharti * executed. Set cmdFILE to stdout to make life easier. Check 1640144467Sharti * the commands, too, but don't die if they're no good -- it 1641144467Sharti * does no harm to keep working up the graph. 1642144467Sharti */ 1643144467Sharti job->cmdFILE = stdout; 1644144467Sharti Job_Touch(gn, job->flags & JOB_SILENT); 1645144467Sharti noExec = TRUE; 16461590Srgrimes } 1647144467Sharti 16481590Srgrimes /* 1649144467Sharti * If we're not supposed to execute a shell, don't. 16501590Srgrimes */ 1651144467Sharti if (noExec) { 1652144467Sharti /* 1653144467Sharti * Unlink and close the command file if we opened one 1654144467Sharti */ 1655144467Sharti if (job->cmdFILE != stdout) { 1656144467Sharti if (job->cmdFILE != NULL) 1657144467Sharti fclose(job->cmdFILE); 1658144467Sharti } else { 1659144467Sharti fflush(stdout); 1660144467Sharti } 1661144467Sharti 1662144467Sharti /* 1663144467Sharti * We only want to work our way up the graph if we aren't here 1664144467Sharti * because the commands for the job were no good. 1665144467Sharti */ 1666144467Sharti if (cmdsOK) { 1667144467Sharti if (aborting == 0) { 1668144467Sharti for (ln = job->tailCmds; ln != NULL; 1669144467Sharti ln = LST_NEXT(ln)) { 1670144467Sharti Lst_AtEnd(&postCommands->commands, 1671146027Sharti Buf_Peel(Var_Subst(Lst_Datum(ln), 1672146027Sharti job->node, FALSE))); 1673144467Sharti } 1674144467Sharti job->node->made = MADE; 1675144467Sharti Make_Update(job->node); 1676144467Sharti } 1677144467Sharti free(job); 1678144467Sharti return(JOB_FINISHED); 1679144467Sharti } else { 1680144467Sharti free(job); 1681144467Sharti return(JOB_ERROR); 1682144467Sharti } 1683144467Sharti } else { 1684144467Sharti fflush(job->cmdFILE); 16851590Srgrimes } 1686144467Sharti 16871590Srgrimes /* 1688144467Sharti * Set up the control arguments to the shell. This is based on the flags 1689144467Sharti * set earlier for this job. 16901590Srgrimes */ 1691144467Sharti JobMakeArgv(job, argv); 16921590Srgrimes 16931590Srgrimes /* 1694144467Sharti * If we're using pipes to catch output, create the pipe by which we'll 1695144467Sharti * get the shell's output. If we're using files, print out that we're 1696144467Sharti * starting a job and then set up its temporary-file name. 16971590Srgrimes */ 1698144467Sharti if (!compatMake || (job->flags & JOB_FIRST)) { 1699144467Sharti if (usePipes) { 1700144467Sharti int fd[2]; 17011590Srgrimes 1702144467Sharti if (pipe(fd) == -1) 1703144467Sharti Punt("Cannot create pipe: %s", strerror(errno)); 1704144467Sharti job->inPipe = fd[0]; 1705144467Sharti job->outPipe = fd[1]; 1706144467Sharti fcntl(job->inPipe, F_SETFD, 1); 1707144467Sharti fcntl(job->outPipe, F_SETFD, 1); 1708144467Sharti } else { 1709144467Sharti fprintf(stdout, "Remaking `%s'\n", gn->name); 1710144467Sharti fflush(stdout); 1711144467Sharti strcpy(job->outFile, TMPPAT); 1712144467Sharti if ((job->outFd = mkstemp(job->outFile)) == -1) 1713144467Sharti Punt("cannot create temp file: %s", 1714144467Sharti strerror(errno)); 1715144467Sharti fcntl(job->outFd, F_SETFD, 1); 17161590Srgrimes } 17171590Srgrimes } 17181590Srgrimes 1719144657Sharti if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) && maxJobs != 0) { 1720144467Sharti /* 1721144467Sharti * We've hit the limit of concurrency, so put the job on hold 1722144467Sharti * until some other job finishes. Note that the special jobs 1723144467Sharti * (.BEGIN, .INTERRUPT and .END) may be run even when the 1724144467Sharti * limit has been reached (e.g. when maxJobs == 0). 1725144467Sharti */ 1726144467Sharti jobFull = TRUE; 17271590Srgrimes 1728144467Sharti DEBUGF(JOB, ("Can only run job locally.\n")); 1729144467Sharti job->flags |= JOB_RESTART; 1730144494Sharti TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 17311590Srgrimes } else { 1732144467Sharti if (nJobs >= maxJobs) { 1733144467Sharti /* 1734144657Sharti * If we're running this job as a special case 1735144467Sharti * (see above), at least say the table is full. 1736144467Sharti */ 1737144467Sharti jobFull = TRUE; 1738144467Sharti DEBUGF(JOB, ("Local job queue is full.\n")); 1739144467Sharti } 1740144467Sharti JobExec(job, argv); 17411590Srgrimes } 1742144467Sharti return (JOB_RUNNING); 17431590Srgrimes} 17441590Srgrimes 174518730Sstevestatic char * 1746104696SjmallettJobOutput(Job *job, char *cp, char *endp, int msg) 174718730Ssteve{ 1748144467Sharti char *ecp; 174918730Ssteve 1750144467Sharti if (commandShell->noPrint) { 1751144467Sharti ecp = strstr(cp, commandShell->noPrint); 1752144467Sharti while (ecp != NULL) { 1753144467Sharti if (cp != ecp) { 1754144467Sharti *ecp = '\0'; 1755144467Sharti if (msg && job->node != lastNode) { 1756144467Sharti MESSAGE(stdout, job->node); 1757144467Sharti lastNode = job->node; 1758144467Sharti } 1759144467Sharti /* 1760144467Sharti * The only way there wouldn't be a newline 1761144467Sharti * after this line is if it were the last in 1762144467Sharti * the buffer. However, since the non-printable 1763144467Sharti * comes after it, there must be a newline, so 1764144467Sharti * we don't print one. 1765144467Sharti */ 1766144467Sharti fprintf(stdout, "%s", cp); 1767144467Sharti fflush(stdout); 1768144467Sharti } 1769144741Sharti cp = ecp + strlen(commandShell->noPrint); 1770144467Sharti if (cp != endp) { 1771144467Sharti /* 1772144467Sharti * Still more to print, look again after 1773144467Sharti * skipping the whitespace following the 1774144467Sharti * non-printable command.... 1775144467Sharti */ 1776144467Sharti cp++; 1777144467Sharti while (*cp == ' ' || *cp == '\t' || 1778144467Sharti *cp == '\n') { 1779144467Sharti cp++; 1780144467Sharti } 1781144467Sharti ecp = strstr(cp, commandShell->noPrint); 1782144467Sharti } else { 1783144467Sharti return (cp); 1784144467Sharti } 178518730Ssteve } 178618730Ssteve } 1787144467Sharti return (cp); 178818730Ssteve} 178918730Ssteve 1790144467Sharti/** 1791144467Sharti * JobDoOutput 17921590Srgrimes * This function is called at different times depending on 17931590Srgrimes * whether the user has specified that output is to be collected 17941590Srgrimes * via pipes or temporary files. In the former case, we are called 17951590Srgrimes * whenever there is something to read on the pipe. We collect more 17961590Srgrimes * output from the given job and store it in the job's outBuf. If 17971590Srgrimes * this makes up a line, we print it tagged by the job's identifier, 17981590Srgrimes * as necessary. 17991590Srgrimes * If output has been collected in a temporary file, we open the 18001590Srgrimes * file and read it line by line, transfering it to our own 18011590Srgrimes * output channel until the file is empty. At which point we 18021590Srgrimes * remove the temporary file. 18031590Srgrimes * In both cases, however, we keep our figurative eye out for the 18041590Srgrimes * 'noPrint' line for the shell from which the output came. If 18051590Srgrimes * we recognize a line, we don't print it. If the command is not 18061590Srgrimes * alone on the line (the character after it is not \0 or \n), we 18071590Srgrimes * do print whatever follows it. 18081590Srgrimes * 18091590Srgrimes * Side Effects: 18101590Srgrimes * curPos may be shifted as may the contents of outBuf. 18111590Srgrimes */ 1812144656Shartistatic void 1813104696SjmallettJobDoOutput(Job *job, Boolean finish) 18141590Srgrimes{ 1815144467Sharti Boolean gotNL = FALSE; /* true if got a newline */ 1816144467Sharti Boolean fbuf; /* true if our buffer filled up */ 1817144467Sharti int nr; /* number of bytes read */ 1818144467Sharti int i; /* auxiliary index into outBuf */ 1819144467Sharti int max; /* limit for i (end of current data) */ 1820144467Sharti int nRead; /* (Temporary) number of bytes read */ 1821144467Sharti FILE *oFILE; /* Stream pointer to shell's output file */ 1822144467Sharti char inLine[132]; 18231590Srgrimes 1824144467Sharti if (usePipes) { 18251590Srgrimes /* 1826144467Sharti * Read as many bytes as will fit in the buffer. 18271590Srgrimes */ 1828144467Sharti end_loop: 1829144467Sharti gotNL = FALSE; 1830144467Sharti fbuf = FALSE; 18318874Srgrimes 1832144467Sharti nRead = read(job->inPipe, &job->outBuf[job->curPos], 1833144467Sharti JOB_BUFSIZE - job->curPos); 18341590Srgrimes /* 1835144467Sharti * Check for interrupt here too, because the above read may 1836144467Sharti * block when the child process is stopped. In this case the 1837144467Sharti * interrupt will unblock it (we don't use SA_RESTART). 18381590Srgrimes */ 1839144467Sharti if (interrupted) 1840144467Sharti JobPassSig(interrupted); 18411590Srgrimes 1842144467Sharti if (nRead < 0) { 1843144467Sharti DEBUGF(JOB, ("JobDoOutput(piperead)")); 1844144467Sharti nr = 0; 1845144467Sharti } else { 1846144467Sharti nr = nRead; 1847144467Sharti } 18481590Srgrimes 18491590Srgrimes /* 1850144467Sharti * If we hit the end-of-file (the job is dead), we must flush 1851144467Sharti * its remaining output, so pretend we read a newline if 1852144467Sharti * there's any output remaining in the buffer. 1853144467Sharti * Also clear the 'finish' flag so we stop looping. 18541590Srgrimes */ 1855144657Sharti if (nr == 0 && job->curPos != 0) { 1856144467Sharti job->outBuf[job->curPos] = '\n'; 1857144467Sharti nr = 1; 1858144467Sharti finish = FALSE; 1859144467Sharti } else if (nr == 0) { 1860144467Sharti finish = FALSE; 18611590Srgrimes } 18628874Srgrimes 18631590Srgrimes /* 1864144467Sharti * Look for the last newline in the bytes we just got. If there 1865144467Sharti * is one, break out of the loop with 'i' as its index and 1866144467Sharti * gotNL set TRUE. 1867144467Sharti */ 1868144467Sharti max = job->curPos + nr; 1869144467Sharti for (i = job->curPos + nr - 1; i >= job->curPos; i--) { 1870144467Sharti if (job->outBuf[i] == '\n') { 1871144467Sharti gotNL = TRUE; 1872144467Sharti break; 1873144467Sharti } else if (job->outBuf[i] == '\0') { 1874144467Sharti /* 1875144467Sharti * Why? 1876144467Sharti */ 1877144467Sharti job->outBuf[i] = ' '; 1878144467Sharti } 1879144467Sharti } 18801590Srgrimes 1881144467Sharti if (!gotNL) { 1882144467Sharti job->curPos += nr; 1883144467Sharti if (job->curPos == JOB_BUFSIZE) { 1884144467Sharti /* 1885144467Sharti * If we've run out of buffer space, we have 1886144467Sharti * no choice but to print the stuff. sigh. 1887144467Sharti */ 1888144467Sharti fbuf = TRUE; 1889144467Sharti i = job->curPos; 1890144467Sharti } 18911590Srgrimes } 1892144467Sharti if (gotNL || fbuf) { 1893144467Sharti /* 1894144467Sharti * Need to send the output to the screen. Null terminate 1895144467Sharti * it first, overwriting the newline character if there 1896144467Sharti * was one. So long as the line isn't one we should 1897144467Sharti * filter (according to the shell description), we print 1898144467Sharti * the line, preceded by a target banner if this target 1899144467Sharti * isn't the same as the one for which we last printed 1900144467Sharti * something. The rest of the data in the buffer are 1901144467Sharti * then shifted down to the start of the buffer and 1902144467Sharti * curPos is set accordingly. 1903144467Sharti */ 1904144467Sharti job->outBuf[i] = '\0'; 1905144467Sharti if (i >= job->curPos) { 1906144467Sharti char *cp; 19071590Srgrimes 1908144467Sharti cp = JobOutput(job, job->outBuf, 1909144467Sharti &job->outBuf[i], FALSE); 1910144467Sharti 1911144467Sharti /* 1912144467Sharti * There's still more in that buffer. This time, 1913144467Sharti * though, we know there's no newline at the 1914144467Sharti * end, so we add one of our own free will. 1915144467Sharti */ 1916144467Sharti if (*cp != '\0') { 1917144467Sharti if (job->node != lastNode) { 1918144467Sharti MESSAGE(stdout, job->node); 1919144467Sharti lastNode = job->node; 1920144467Sharti } 1921144467Sharti fprintf(stdout, "%s%s", cp, 1922144467Sharti gotNL ? "\n" : ""); 1923144467Sharti fflush(stdout); 1924144467Sharti } 1925144467Sharti } 1926144467Sharti if (i < max - 1) { 1927144467Sharti /* shift the remaining characters down */ 1928144467Sharti memcpy(job->outBuf, &job->outBuf[i + 1], 1929144467Sharti max - (i + 1)); 1930144467Sharti job->curPos = max - (i + 1); 1931144467Sharti 1932144467Sharti } else { 1933144467Sharti /* 1934144467Sharti * We have written everything out, so we just 1935144467Sharti * start over from the start of the buffer. 1936144467Sharti * No copying. No nothing. 1937144467Sharti */ 1938144467Sharti job->curPos = 0; 1939144467Sharti } 1940144467Sharti } 1941144467Sharti if (finish) { 1942144467Sharti /* 1943144467Sharti * If the finish flag is true, we must loop until we hit 1944144467Sharti * end-of-file on the pipe. This is guaranteed to happen 1945144467Sharti * eventually since the other end of the pipe is now 1946144467Sharti * closed (we closed it explicitly and the child has 1947144467Sharti * exited). When we do get an EOF, finish will be set 1948144467Sharti * FALSE and we'll fall through and out. 1949144467Sharti */ 1950144467Sharti goto end_loop; 1951144467Sharti } 1952144467Sharti 1953144467Sharti } else { 19541590Srgrimes /* 1955144467Sharti * We've been called to retrieve the output of the job from the 1956144467Sharti * temporary file where it's been squirreled away. This consists 1957144467Sharti * of opening the file, reading the output line by line, being 1958144467Sharti * sure not to print the noPrint line for the shell we used, 1959144467Sharti * then close and remove the temporary file. Very simple. 1960144467Sharti * 1961144467Sharti * Change to read in blocks and do FindSubString type things 1962144467Sharti * as for pipes? That would allow for "@echo -n..." 19631590Srgrimes */ 1964144467Sharti oFILE = fopen(job->outFile, "r"); 1965144467Sharti if (oFILE != NULL) { 1966144467Sharti fprintf(stdout, "Results of making %s:\n", 1967144467Sharti job->node->name); 1968144467Sharti fflush(stdout); 1969144467Sharti 1970144467Sharti while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { 1971144467Sharti char *cp, *endp, *oendp; 1972144467Sharti 1973144467Sharti cp = inLine; 1974144467Sharti oendp = endp = inLine + strlen(inLine); 1975144467Sharti if (endp[-1] == '\n') { 1976144467Sharti *--endp = '\0'; 1977144467Sharti } 1978144467Sharti cp = JobOutput(job, inLine, endp, FALSE); 1979144467Sharti 1980144467Sharti /* 1981144467Sharti * There's still more in that buffer. This time, 1982144467Sharti * though, we know there's no newline at the 1983144467Sharti * end, so we add one of our own free will. 1984144467Sharti */ 1985144467Sharti fprintf(stdout, "%s", cp); 1986144467Sharti fflush(stdout); 1987144467Sharti if (endp != oendp) { 1988144467Sharti fprintf(stdout, "\n"); 1989144467Sharti fflush(stdout); 1990144467Sharti } 1991144467Sharti } 1992144467Sharti fclose(oFILE); 1993144467Sharti eunlink(job->outFile); 19941590Srgrimes } 19951590Srgrimes } 19961590Srgrimes} 19971590Srgrimes 1998144467Sharti/** 1999144467Sharti * Job_CatchChildren 20001590Srgrimes * Handle the exit of a child. Called from Make_Make. 20011590Srgrimes * 20021590Srgrimes * Side Effects: 20031590Srgrimes * The job descriptor is removed from the list of children. 20041590Srgrimes * 20051590Srgrimes * Notes: 20061590Srgrimes * We do waits, blocking or not, according to the wisdom of our 20071590Srgrimes * caller, until there are no more children to report. For each 20081590Srgrimes * job, call JobFinish to finish things off. This will take care of 20091590Srgrimes * putting jobs on the stoppedJobs queue. 20101590Srgrimes */ 20111590Srgrimesvoid 2012104696SjmallettJob_CatchChildren(Boolean block) 20131590Srgrimes{ 2014144665Sharti pid_t pid; /* pid of dead child */ 2015144467Sharti Job *job; /* job descriptor for dead child */ 2016144467Sharti int status; /* Exit/termination status */ 20171590Srgrimes 2018144467Sharti /* 2019144467Sharti * Don't even bother if we know there's no one around. 2020144467Sharti */ 2021144467Sharti if (nJobs == 0) { 2022144467Sharti return; 2023144467Sharti } 20248874Srgrimes 2025144467Sharti for (;;) { 2026144467Sharti pid = waitpid((pid_t)-1, &status, 2027144467Sharti (block ? 0 : WNOHANG) | WUNTRACED); 2028144467Sharti if (pid <= 0) 2029144467Sharti break; 20301590Srgrimes 2031144665Sharti DEBUGF(JOB, ("Process %jd exited or stopped.\n", 2032144665Sharti (intmax_t)pid)); 20331590Srgrimes 2034144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2035144494Sharti if (job->pid == pid) 2036144467Sharti break; 2037143810Sharti } 2038144467Sharti 2039144494Sharti if (job == NULL) { 2040144467Sharti if (WIFSIGNALED(status) && 2041144467Sharti (WTERMSIG(status) == SIGCONT)) { 2042144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2043144494Sharti if (job->pid == pid) 2044144467Sharti break; 2045144467Sharti } 2046144494Sharti if (job == NULL) { 2047144665Sharti Error("Resumed child (%jd) " 2048144665Sharti "not in table", (intmax_t)pid); 2049144467Sharti continue; 2050144467Sharti } 2051144494Sharti TAILQ_REMOVE(&stoppedJobs, job, link); 2052144467Sharti } else { 2053144665Sharti Error("Child (%jd) not in table?", 2054144665Sharti (intmax_t)pid); 2055144467Sharti continue; 2056144467Sharti } 2057144467Sharti } else { 2058144494Sharti TAILQ_REMOVE(&jobs, job, link); 2059144467Sharti nJobs -= 1; 2060144467Sharti if (fifoFd >= 0 && maxJobs > 1) { 2061144467Sharti write(fifoFd, "+", 1); 2062144467Sharti maxJobs--; 2063144467Sharti if (nJobs >= maxJobs) 2064144467Sharti jobFull = TRUE; 2065144467Sharti else 2066144467Sharti jobFull = FALSE; 2067144467Sharti } else { 2068144467Sharti DEBUGF(JOB, ("Job queue is no longer full.\n")); 2069144467Sharti jobFull = FALSE; 2070144467Sharti } 20711590Srgrimes } 2072144467Sharti 2073144467Sharti JobFinish(job, &status); 20741590Srgrimes } 2075144467Sharti if (interrupted) 2076144467Sharti JobPassSig(interrupted); 20771590Srgrimes} 20781590Srgrimes 2079144467Sharti/** 2080144467Sharti * Job_CatchOutput 20811590Srgrimes * Catch the output from our children, if we're using 20821590Srgrimes * pipes do so. Otherwise just block time until we get a 2083138232Sharti * signal(most likely a SIGCHLD) since there's no point in 20841590Srgrimes * just spinning when there's nothing to do and the reaping 20858874Srgrimes * of a child can wait for a while. 20861590Srgrimes * 20871590Srgrimes * Side Effects: 20881590Srgrimes * Output is read from pipes if we're piping. 20891590Srgrimes * ----------------------------------------------------------------------- 20901590Srgrimes */ 20911590Srgrimesvoid 2092139064Sharti#ifdef USE_KQUEUE 2093139064ShartiJob_CatchOutput(int flag __unused) 2094139064Sharti#else 2095137606SphkJob_CatchOutput(int flag) 2096139064Sharti#endif 20971590Srgrimes{ 2098144467Sharti int nfds; 2099104475Sphk#ifdef USE_KQUEUE 2100104475Sphk#define KEV_SIZE 4 2101144467Sharti struct kevent kev[KEV_SIZE]; 2102144467Sharti int i; 2103104475Sphk#else 2104144467Sharti struct timeval timeout; 2105144467Sharti fd_set readfds; 2106144467Sharti Job *job; 2107104475Sphk#endif 21081590Srgrimes 2109144467Sharti fflush(stdout); 21101590Srgrimes 2111144467Sharti if (usePipes) { 2112104475Sphk#ifdef USE_KQUEUE 2113144467Sharti if ((nfds = kevent(kqfd, NULL, 0, kev, KEV_SIZE, NULL)) == -1) { 2114144467Sharti if (errno != EINTR) 2115144467Sharti Punt("kevent: %s", strerror(errno)); 2116144467Sharti if (interrupted) 2117144467Sharti JobPassSig(interrupted); 2118144467Sharti } else { 2119144467Sharti for (i = 0; i < nfds; i++) { 2120144467Sharti if (kev[i].flags & EV_ERROR) { 2121144467Sharti warnc(kev[i].data, "kevent"); 2122144467Sharti continue; 2123144467Sharti } 2124144467Sharti switch (kev[i].filter) { 2125144467Sharti case EVFILT_READ: 2126144467Sharti JobDoOutput(kev[i].udata, FALSE); 2127144467Sharti break; 2128144467Sharti case EVFILT_PROC: 2129144467Sharti /* 2130144467Sharti * Just wake up and let 2131144467Sharti * Job_CatchChildren() collect the 2132144467Sharti * terminated job. 2133144467Sharti */ 2134144467Sharti break; 2135144467Sharti } 2136144467Sharti } 2137104475Sphk } 2138104475Sphk#else 2139144467Sharti readfds = outputs; 2140144467Sharti timeout.tv_sec = SEL_SEC; 2141144467Sharti timeout.tv_usec = SEL_USEC; 2142144467Sharti if (flag && jobFull && fifoFd >= 0) 2143144467Sharti FD_SET(fifoFd, &readfds); 21441590Srgrimes 2145144467Sharti nfds = select(FD_SETSIZE, &readfds, (fd_set *)NULL, 2146144467Sharti (fd_set *)NULL, &timeout); 2147144467Sharti if (nfds <= 0) { 2148144467Sharti if (interrupted) 2149144467Sharti JobPassSig(interrupted); 2150144467Sharti return; 2151144467Sharti } 2152144467Sharti if (fifoFd >= 0 && FD_ISSET(fifoFd, &readfds)) { 2153144467Sharti if (--nfds <= 0) 2154144467Sharti return; 2155144467Sharti } 2156144494Sharti job = TAILQ_FIRST(&jobs); 2157144494Sharti while (nfds != 0 && job != NULL) { 2158144467Sharti if (FD_ISSET(job->inPipe, &readfds)) { 2159144467Sharti JobDoOutput(job, FALSE); 2160144494Sharti nfds--; 2161144467Sharti } 2162144494Sharti job = TAILQ_NEXT(job, link); 2163144467Sharti } 2164144467Sharti#endif /* !USE_KQUEUE */ 2165137606Sphk } 21661590Srgrimes} 21671590Srgrimes 2168144467Sharti/** 2169144467Sharti * Job_Make 21701590Srgrimes * Start the creation of a target. Basically a front-end for 21711590Srgrimes * JobStart used by the Make module. 21721590Srgrimes * 21731590Srgrimes * Side Effects: 21741590Srgrimes * Another job is started. 21751590Srgrimes */ 21761590Srgrimesvoid 2177104696SjmallettJob_Make(GNode *gn) 21781590Srgrimes{ 2179138232Sharti 2180144467Sharti JobStart(gn, 0, NULL); 21811590Srgrimes} 21821590Srgrimes 2183144467Sharti/** 2184144467Sharti * JobCopyShell 2185144467Sharti * Make a new copy of the shell structure including a copy of the strings 2186144467Sharti * in it. This also defaults some fields in case they are NULL. 2187138079Sharti * 2188144467Sharti * Returns: 2189144467Sharti * The function returns a pointer to the new shell structure. 2190138079Sharti */ 2191144483Shartistatic struct Shell * 2192144483ShartiJobCopyShell(const struct Shell *osh) 2193138079Sharti{ 2194144483Sharti struct Shell *nsh; 2195138079Sharti 2196138079Sharti nsh = emalloc(sizeof(*nsh)); 2197138079Sharti nsh->name = estrdup(osh->name); 2198138079Sharti 2199138079Sharti if (osh->echoOff != NULL) 2200138079Sharti nsh->echoOff = estrdup(osh->echoOff); 2201138079Sharti else 2202138079Sharti nsh->echoOff = NULL; 2203138079Sharti if (osh->echoOn != NULL) 2204138079Sharti nsh->echoOn = estrdup(osh->echoOn); 2205138079Sharti else 2206138079Sharti nsh->echoOn = NULL; 2207138079Sharti nsh->hasEchoCtl = osh->hasEchoCtl; 2208138079Sharti 2209138079Sharti if (osh->noPrint != NULL) 2210138079Sharti nsh->noPrint = estrdup(osh->noPrint); 2211138079Sharti else 2212138079Sharti nsh->noPrint = NULL; 2213138079Sharti 2214138079Sharti nsh->hasErrCtl = osh->hasErrCtl; 2215138079Sharti if (osh->errCheck == NULL) 2216138079Sharti nsh->errCheck = estrdup(""); 2217138079Sharti else 2218138079Sharti nsh->errCheck = estrdup(osh->errCheck); 2219138079Sharti if (osh->ignErr == NULL) 2220138079Sharti nsh->ignErr = estrdup("%s"); 2221138079Sharti else 2222138079Sharti nsh->ignErr = estrdup(osh->ignErr); 2223138079Sharti 2224138079Sharti if (osh->echo == NULL) 2225138079Sharti nsh->echo = estrdup(""); 2226138079Sharti else 2227138079Sharti nsh->echo = estrdup(osh->echo); 2228138079Sharti 2229138079Sharti if (osh->exit == NULL) 2230138079Sharti nsh->exit = estrdup(""); 2231138079Sharti else 2232138079Sharti nsh->exit = estrdup(osh->exit); 2233138079Sharti 2234138079Sharti return (nsh); 2235138079Sharti} 2236138079Sharti 2237144467Sharti/** 2238144467Sharti * JobFreeShell 2239144467Sharti * Free a shell structure and all associated strings. 2240138079Sharti */ 2241138079Shartistatic void 2242144483ShartiJobFreeShell(struct Shell *sh) 2243138079Sharti{ 2244138079Sharti 2245138079Sharti if (sh != NULL) { 2246138079Sharti free(sh->name); 2247138079Sharti free(sh->echoOff); 2248138079Sharti free(sh->echoOn); 2249138079Sharti free(sh->noPrint); 2250138079Sharti free(sh->errCheck); 2251138079Sharti free(sh->ignErr); 2252138079Sharti free(sh->echo); 2253138079Sharti free(sh->exit); 2254138079Sharti free(sh); 2255138079Sharti } 2256138079Sharti} 2257138079Sharti 2258136840Sruvoid 2259136840SruShell_Init(void) 2260136840Sru{ 2261138079Sharti 2262144467Sharti if (commandShell == NULL) 2263144467Sharti commandShell = JobMatchShell(shells[DEFSHELL].name); 2264138079Sharti 2265144467Sharti if (shellPath == NULL) { 2266144467Sharti /* 2267144467Sharti * The user didn't specify a shell to use, so we are using the 2268144467Sharti * default one... Both the absolute path and the last component 2269144467Sharti * must be set. The last component is taken from the 'name' 2270144467Sharti * field of the default shell description pointed-to by 2271144467Sharti * commandShell. All default shells are located in 2272144467Sharti * PATH_DEFSHELLDIR. 2273144467Sharti */ 2274144467Sharti shellName = commandShell->name; 2275144467Sharti shellPath = str_concat(PATH_DEFSHELLDIR, shellName, 2276144467Sharti STR_ADDSLASH); 2277144467Sharti } 2278136840Sru} 2279136840Sru 2280144467Sharti/** 2281144467Sharti * Job_Init 2282137572Sphk * Initialize the process module, given a maximum number of jobs. 22831590Srgrimes * 22841590Srgrimes * Side Effects: 22851590Srgrimes * lists and counters are initialized 22861590Srgrimes */ 22871590Srgrimesvoid 2288137572SphkJob_Init(int maxproc) 22891590Srgrimes{ 2290144467Sharti GNode *begin; /* node for commands to do at the very start */ 2291144467Sharti const char *env; 2292144467Sharti struct sigaction sa; 22931590Srgrimes 2294144467Sharti fifoFd = -1; 2295144467Sharti env = getenv("MAKE_JOBS_FIFO"); 2296137606Sphk 2297144467Sharti if (env == NULL && maxproc > 1) { 2298144467Sharti /* 2299144467Sharti * We did not find the environment variable so we are the 2300144467Sharti * leader. Create the fifo, open it, write one char per 2301144467Sharti * allowed job into the pipe. 2302144467Sharti */ 2303144467Sharti mktemp(fifoName); 2304144467Sharti if (!mkfifo(fifoName, 0600)) { 2305144467Sharti fifoFd = open(fifoName, O_RDWR | O_NONBLOCK, 0); 2306144467Sharti if (fifoFd >= 0) { 2307144467Sharti fifoMaster = 1; 2308144467Sharti fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2309144467Sharti env = fifoName; 2310144467Sharti setenv("MAKE_JOBS_FIFO", env, 1); 2311144467Sharti while (maxproc-- > 0) { 2312144467Sharti write(fifoFd, "+", 1); 2313144467Sharti } 2314144467Sharti /* The master make does not get a magic token */ 2315144467Sharti jobFull = TRUE; 2316144467Sharti maxJobs = 0; 2317144467Sharti } else { 2318144467Sharti unlink(fifoName); 2319144467Sharti env = NULL; 2320144467Sharti } 2321137606Sphk } 2322144467Sharti 2323144467Sharti } else if (env != NULL) { 2324144467Sharti /* 2325144467Sharti * We had the environment variable so we are a slave. 2326144467Sharti * Open fifo and give ourselves a magic token which represents 2327144467Sharti * the token our parent make has grabbed to start his make 2328144467Sharti * process. Otherwise the sub-makes would gobble up tokens and 2329144467Sharti * the proper number of tokens to specify to -j would depend 2330144467Sharti * on the depth of the tree and the order of execution. 2331144467Sharti */ 2332144467Sharti fifoFd = open(env, O_RDWR, 0); 2333144467Sharti if (fifoFd >= 0) { 2334144467Sharti fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2335144467Sharti maxJobs = 1; 2336144467Sharti jobFull = FALSE; 2337144467Sharti } 2338137606Sphk } 2339144467Sharti if (fifoFd <= 0) { 2340144467Sharti maxJobs = maxproc; 2341144467Sharti jobFull = FALSE; 2342144467Sharti } else { 2343137606Sphk } 2344144467Sharti nJobs = 0; 23451590Srgrimes 2346144467Sharti aborting = 0; 2347144467Sharti errors = 0; 23481590Srgrimes 2349144467Sharti lastNode = NULL; 23501590Srgrimes 2351144467Sharti if ((maxJobs == 1 && fifoFd < 0) || beVerbose == 0) { 2352144467Sharti /* 2353144467Sharti * If only one job can run at a time, there's no need for a 2354144467Sharti * banner, no is there? 2355144467Sharti */ 2356144467Sharti targFmt = ""; 2357144467Sharti } else { 2358144467Sharti targFmt = TARG_FMT; 2359144467Sharti } 2360144467Sharti 2361144467Sharti Shell_Init(); 2362144467Sharti 23631590Srgrimes /* 2364144467Sharti * Catch the four signals that POSIX specifies if they aren't ignored. 2365144467Sharti * JobCatchSignal will just set global variables and hope someone 2366144467Sharti * else is going to handle the interrupt. 23671590Srgrimes */ 2368144467Sharti sa.sa_handler = JobCatchSig; 2369144467Sharti sigemptyset(&sa.sa_mask); 2370144467Sharti sa.sa_flags = 0; 23718874Srgrimes 2372144467Sharti if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 2373144467Sharti sigaction(SIGINT, &sa, NULL); 2374144467Sharti } 2375144467Sharti if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { 2376144467Sharti sigaction(SIGHUP, &sa, NULL); 2377144467Sharti } 2378144467Sharti if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { 2379144467Sharti sigaction(SIGQUIT, &sa, NULL); 2380144467Sharti } 2381144467Sharti if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { 2382144467Sharti sigaction(SIGTERM, &sa, NULL); 2383144467Sharti } 2384144467Sharti /* 2385144467Sharti * There are additional signals that need to be caught and passed if 2386144467Sharti * either the export system wants to be told directly of signals or if 2387144467Sharti * we're giving each job its own process group (since then it won't get 2388144467Sharti * signals from the terminal driver as we own the terminal) 2389144467Sharti */ 2390137202Sharti#if defined(USE_PGRP) 2391144467Sharti if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { 2392144467Sharti sigaction(SIGTSTP, &sa, NULL); 2393144467Sharti } 2394144467Sharti if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) { 2395144467Sharti sigaction(SIGTTOU, &sa, NULL); 2396144467Sharti } 2397144467Sharti if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) { 2398144467Sharti sigaction(SIGTTIN, &sa, NULL); 2399144467Sharti } 2400144467Sharti if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) { 2401144467Sharti sigaction(SIGWINCH, &sa, NULL); 2402144467Sharti } 24031590Srgrimes#endif 24048874Srgrimes 2405104475Sphk#ifdef USE_KQUEUE 2406144467Sharti if ((kqfd = kqueue()) == -1) { 2407144467Sharti Punt("kqueue: %s", strerror(errno)); 2408144467Sharti } 2409104475Sphk#endif 2410104475Sphk 2411144467Sharti begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); 24121590Srgrimes 2413144467Sharti if (begin != NULL) { 2414144467Sharti JobStart(begin, JOB_SPECIAL, (Job *)NULL); 2415144467Sharti while (nJobs) { 2416144467Sharti Job_CatchOutput(0); 2417144467Sharti Job_CatchChildren(!usePipes); 2418144467Sharti } 24191590Srgrimes } 2420144467Sharti postCommands = Targ_FindNode(".END", TARG_CREATE); 24211590Srgrimes} 24221590Srgrimes 2423144467Sharti/** 2424144467Sharti * Job_Full 24251590Srgrimes * See if the job table is full. It is considered full if it is OR 24261590Srgrimes * if we are in the process of aborting OR if we have 24271590Srgrimes * reached/exceeded our local quota. This prevents any more jobs 24281590Srgrimes * from starting up. 24291590Srgrimes * 24301590Srgrimes * Results: 24311590Srgrimes * TRUE if the job table is full, FALSE otherwise 24321590Srgrimes */ 24331590SrgrimesBoolean 2434104696SjmallettJob_Full(void) 24351590Srgrimes{ 2436144467Sharti char c; 2437144467Sharti int i; 2438137606Sphk 2439144467Sharti if (aborting) 2440144467Sharti return (aborting); 2441144467Sharti if (fifoFd >= 0 && jobFull) { 2442144467Sharti i = read(fifoFd, &c, 1); 2443144467Sharti if (i > 0) { 2444144467Sharti maxJobs++; 2445144467Sharti jobFull = FALSE; 2446144467Sharti } 2447137606Sphk } 2448144467Sharti return (jobFull); 24491590Srgrimes} 24501590Srgrimes 2451144467Sharti/** 2452144467Sharti * Job_Empty 24531590Srgrimes * See if the job table is empty. Because the local concurrency may 24541590Srgrimes * be set to 0, it is possible for the job table to become empty, 24551590Srgrimes * while the list of stoppedJobs remains non-empty. In such a case, 24561590Srgrimes * we want to restart as many jobs as we can. 24571590Srgrimes * 24581590Srgrimes * Results: 24591590Srgrimes * TRUE if it is. FALSE if it ain't. 24601590Srgrimes */ 24611590SrgrimesBoolean 2462104696SjmallettJob_Empty(void) 24631590Srgrimes{ 2464144467Sharti if (nJobs == 0) { 2465144494Sharti if (!TAILQ_EMPTY(&stoppedJobs) && !aborting) { 2466144467Sharti /* 2467144467Sharti * The job table is obviously not full if it has no 2468144467Sharti * jobs in it...Try and restart the stopped jobs. 2469144467Sharti */ 2470144467Sharti jobFull = FALSE; 2471144467Sharti JobRestartJobs(); 2472144467Sharti return (FALSE); 2473144467Sharti } else { 2474144467Sharti return (TRUE); 2475144467Sharti } 24761590Srgrimes } else { 2477144467Sharti return (FALSE); 24781590Srgrimes } 24791590Srgrimes} 24801590Srgrimes 2481144467Sharti/** 2482144467Sharti * JobMatchShell 24831590Srgrimes * Find a matching shell in 'shells' given its final component. 24841590Srgrimes * 24851590Srgrimes * Results: 2486138334Sharti * A pointer to a freshly allocated Shell structure with a copy 2487138228Sharti * of the static structure or NULL if no shell with the given name 2488138228Sharti * is found. 24891590Srgrimes */ 2490144483Shartistatic struct Shell * 2491138228ShartiJobMatchShell(const char *name) 24921590Srgrimes{ 2493144467Sharti const struct CShell *sh; /* Pointer into shells table */ 2494144483Sharti struct Shell *nsh; 24951590Srgrimes 2496144467Sharti for (sh = shells; sh < shells + sizeof(shells)/sizeof(shells[0]); sh++) 2497144467Sharti if (strcmp(sh->name, name) == 0) 2498144467Sharti break; 24991590Srgrimes 2500144467Sharti if (sh == shells + sizeof(shells)/sizeof(shells[0])) 2501144467Sharti return (NULL); 2502138228Sharti 2503144467Sharti /* make a copy */ 2504144467Sharti nsh = emalloc(sizeof(*nsh)); 2505138228Sharti 2506144467Sharti nsh->name = estrdup(sh->name); 2507144467Sharti nsh->echoOff = estrdup(sh->echoOff); 2508144467Sharti nsh->echoOn = estrdup(sh->echoOn); 2509144467Sharti nsh->hasEchoCtl = sh->hasEchoCtl; 2510144467Sharti nsh->noPrint = estrdup(sh->noPrint); 2511144467Sharti nsh->hasErrCtl = sh->hasErrCtl; 2512144467Sharti nsh->errCheck = estrdup(sh->errCheck); 2513144467Sharti nsh->ignErr = estrdup(sh->ignErr); 2514144467Sharti nsh->echo = estrdup(sh->echo); 2515144467Sharti nsh->exit = estrdup(sh->exit); 2516138228Sharti 2517144467Sharti return (nsh); 25181590Srgrimes} 25191590Srgrimes 2520144467Sharti/** 2521144467Sharti * Job_ParseShell 25221590Srgrimes * Parse a shell specification and set up commandShell, shellPath 25231590Srgrimes * and shellName appropriately. 25241590Srgrimes * 25251590Srgrimes * Results: 25261590Srgrimes * FAILURE if the specification was incorrect. 25271590Srgrimes * 25281590Srgrimes * Side Effects: 25291590Srgrimes * commandShell points to a Shell structure (either predefined or 25301590Srgrimes * created from the shell spec), shellPath is the full path of the 25311590Srgrimes * shell described by commandShell, while shellName is just the 25321590Srgrimes * final component of shellPath. 25331590Srgrimes * 25341590Srgrimes * Notes: 25351590Srgrimes * A shell specification consists of a .SHELL target, with dependency 25361590Srgrimes * operator, followed by a series of blank-separated words. Double 25371590Srgrimes * quotes can be used to use blanks in words. A backslash escapes 25381590Srgrimes * anything (most notably a double-quote and a space) and 25391590Srgrimes * provides the functionality it does in C. Each word consists of 25401590Srgrimes * keyword and value separated by an equal sign. There should be no 25411590Srgrimes * unnecessary spaces in the word. The keywords are as follows: 2542146061Sharti * name Name of shell. 2543146061Sharti * path Location of shell. Overrides "name" if given 2544146061Sharti * quiet Command to turn off echoing. 2545146061Sharti * echo Command to turn echoing on 25461590Srgrimes * filter Result of turning off echoing that shouldn't be 2547146061Sharti * printed. 25481590Srgrimes * echoFlag Flag to turn echoing on at the start 25491590Srgrimes * errFlag Flag to turn error checking on at the start 25501590Srgrimes * hasErrCtl True if shell has error checking control 2551146061Sharti * check Command to turn on error checking if hasErrCtl 2552146061Sharti * is TRUE or template of command to echo a command 2553146061Sharti * for which error checking is off if hasErrCtl is 2554146061Sharti * FALSE. 25551590Srgrimes * ignore Command to turn off error checking if hasErrCtl 2556146061Sharti * is TRUE or template of command to execute a 2557146061Sharti * command so as to ignore any errors it returns if 2558146061Sharti * hasErrCtl is FALSE. 25591590Srgrimes */ 25601590SrgrimesReturnStatus 2561104696SjmallettJob_ParseShell(char *line) 25621590Srgrimes{ 2563144467Sharti char **words; 2564144467Sharti int wordCount; 2565144467Sharti char **argv; 2566144467Sharti int argc; 2567144467Sharti char *path; 2568144741Sharti char *eq; 2569144467Sharti Boolean fullSpec = FALSE; 2570144483Sharti struct Shell newShell; 2571144483Sharti struct Shell *sh; 25721590Srgrimes 2573144467Sharti while (isspace((unsigned char)*line)) { 2574144467Sharti line++; 2575144467Sharti } 2576144467Sharti words = brk_string(line, &wordCount, TRUE); 25771590Srgrimes 2578144467Sharti memset(&newShell, 0, sizeof(newShell)); 2579144741Sharti path = NULL; 25808874Srgrimes 25811590Srgrimes /* 2582144741Sharti * Parse the specification by keyword but skip the first word - it 2583144741Sharti * is not set by brk_string. 25841590Srgrimes */ 2585144741Sharti wordCount--; 2586144741Sharti words++; 2587144741Sharti 2588144741Sharti for (argc = wordCount, argv = words; argc != 0; argc--, argv++) { 2589144741Sharti /* 2590144741Sharti * Split keyword and value 2591144741Sharti */ 2592144741Sharti if ((eq = strchr(*argv, '=')) == NULL) { 2593144741Sharti Parse_Error(PARSE_FATAL, "missing '=' in shell " 2594144741Sharti "specification keyword '%s'", *argv); 2595144741Sharti return (FAILURE); 2596144741Sharti } 2597144741Sharti *eq++ = '\0'; 2598144741Sharti 2599144741Sharti if (strcmp(*argv, "path") == 0) { 2600144741Sharti path = eq; 2601144741Sharti } else if (strcmp(*argv, "name") == 0) { 2602144741Sharti newShell.name = eq; 2603144741Sharti } else if (strcmp(*argv, "quiet") == 0) { 2604144741Sharti newShell.echoOff = eq; 2605144741Sharti fullSpec = TRUE; 2606144741Sharti } else if (strcmp(*argv, "echo") == 0) { 2607144741Sharti newShell.echoOn = eq; 2608144741Sharti fullSpec = TRUE; 2609144741Sharti } else if (strcmp(*argv, "filter") == 0) { 2610144741Sharti newShell.noPrint = eq; 2611144741Sharti fullSpec = TRUE; 2612144741Sharti } else if (strcmp(*argv, "echoFlag") == 0) { 2613144741Sharti newShell.echo = eq; 2614144741Sharti fullSpec = TRUE; 2615144741Sharti } else if (strcmp(*argv, "errFlag") == 0) { 2616144741Sharti newShell.exit = eq; 2617144741Sharti fullSpec = TRUE; 2618144741Sharti } else if (strcmp(*argv, "hasErrCtl") == 0) { 2619144741Sharti newShell.hasErrCtl = (*eq == 'Y' || *eq == 'y' || 2620144741Sharti *eq == 'T' || *eq == 't'); 2621144741Sharti fullSpec = TRUE; 2622144741Sharti } else if (strcmp(*argv, "check") == 0) { 2623144741Sharti newShell.errCheck = eq; 2624144741Sharti fullSpec = TRUE; 2625144741Sharti } else if (strcmp(*argv, "ignore") == 0) { 2626144741Sharti newShell.ignErr = eq; 2627144741Sharti fullSpec = TRUE; 2628144467Sharti } else { 2629144741Sharti Parse_Error(PARSE_FATAL, "unknown keyword in shell " 2630144741Sharti "specification '%s'", *argv); 2631144741Sharti return (FAILURE); 2632144467Sharti } 26331590Srgrimes } 2634138079Sharti 26351590Srgrimes /* 2636144467Sharti * Some checks (could be more) 26371590Srgrimes */ 2638144467Sharti if (fullSpec) { 2639144467Sharti if ((newShell.echoOn != NULL) ^ (newShell.echoOff != NULL)) 2640144467Sharti Parse_Error(PARSE_FATAL, "Shell must have either both " 2641144467Sharti "echoOff and echoOn or none of them"); 2642144467Sharti 2643144467Sharti if (newShell.echoOn != NULL && newShell.echoOff) 2644144467Sharti newShell.hasEchoCtl = TRUE; 26451590Srgrimes } 2646138079Sharti 2647144467Sharti if (path == NULL) { 2648144467Sharti /* 2649144467Sharti * If no path was given, the user wants one of the pre-defined 2650144467Sharti * shells, yes? So we find the one s/he wants with the help of 2651144467Sharti * JobMatchShell and set things up the right way. shellPath 2652144467Sharti * will be set up by Job_Init. 2653144467Sharti */ 2654144467Sharti if (newShell.name == NULL) { 2655144467Sharti Parse_Error(PARSE_FATAL, 2656144467Sharti "Neither path nor name specified"); 2657144467Sharti return (FAILURE); 2658144467Sharti } 2659144467Sharti if ((sh = JobMatchShell(newShell.name)) == NULL) { 2660144467Sharti Parse_Error(PARSE_FATAL, "%s: no matching shell", 2661144467Sharti newShell.name); 2662144467Sharti return (FAILURE); 2663144467Sharti } 2664144467Sharti 26651590Srgrimes } else { 2666144467Sharti /* 2667144467Sharti * The user provided a path. If s/he gave nothing else 2668144467Sharti * (fullSpec is FALSE), try and find a matching shell in the 2669144467Sharti * ones we know of. Else we just take the specification at its 2670144467Sharti * word and copy it to a new location. In either case, we need 2671144467Sharti * to record the path the user gave for the shell. 2672144467Sharti */ 2673144467Sharti free(shellPath); 2674144467Sharti shellPath = estrdup(path); 2675144467Sharti if (newShell.name == NULL) { 2676144467Sharti /* get the base name as the name */ 2677144467Sharti path = strrchr(path, '/'); 2678144467Sharti if (path == NULL) { 2679144467Sharti path = shellPath; 2680144467Sharti } else { 2681144467Sharti path += 1; 2682144467Sharti } 2683144467Sharti newShell.name = path; 2684144467Sharti } 2685144467Sharti 2686144467Sharti if (!fullSpec) { 2687144467Sharti if ((sh = JobMatchShell(newShell.name)) == NULL) { 2688144467Sharti Parse_Error(PARSE_FATAL, 2689144467Sharti "%s: no matching shell", newShell.name); 2690144467Sharti return (FAILURE); 2691144467Sharti } 2692144467Sharti } else { 2693144467Sharti sh = JobCopyShell(&newShell); 2694144467Sharti } 26951590Srgrimes } 26961590Srgrimes 2697144467Sharti /* set the new shell */ 2698144467Sharti JobFreeShell(commandShell); 2699144467Sharti commandShell = sh; 27008874Srgrimes 2701144467Sharti shellName = commandShell->name; 27028874Srgrimes 2703144467Sharti return (SUCCESS); 27041590Srgrimes} 27051590Srgrimes 2706144467Sharti/** 2707144467Sharti * JobInterrupt 27081590Srgrimes * Handle the receipt of an interrupt. 27091590Srgrimes * 27101590Srgrimes * Side Effects: 27111590Srgrimes * All children are killed. Another job will be started if the 27121590Srgrimes * .INTERRUPT target was given. 27131590Srgrimes */ 27141590Srgrimesstatic void 2715104696SjmallettJobInterrupt(int runINTERRUPT, int signo) 27161590Srgrimes{ 2717144467Sharti Job *job; /* job descriptor in that element */ 2718144467Sharti GNode *interrupt; /* the node describing the .INTERRUPT target */ 27198874Srgrimes 2720144467Sharti aborting = ABORT_INTERRUPT; 27211590Srgrimes 2722144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2723144467Sharti if (!Targ_Precious(job->node)) { 2724144467Sharti char *file = (job->node->path == NULL ? 2725144467Sharti job->node->name : job->node->path); 2726144467Sharti 2727144467Sharti if (!noExecute && eunlink(file) != -1) { 2728144467Sharti Error("*** %s removed", file); 2729144467Sharti } 2730144467Sharti } 2731144467Sharti if (job->pid) { 2732144467Sharti DEBUGF(JOB, ("JobInterrupt passing signal to child " 2733144665Sharti "%jd.\n", (intmax_t)job->pid)); 2734144467Sharti KILL(job->pid, signo); 2735144467Sharti } 27361590Srgrimes } 273718730Ssteve 2738144467Sharti if (runINTERRUPT && !touchFlag) { 2739144467Sharti /* 2740144467Sharti * clear the interrupted flag because we would get an 2741144467Sharti * infinite loop otherwise. 2742144467Sharti */ 2743144467Sharti interrupted = 0; 2744137605Sharti 2745144467Sharti interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 2746144467Sharti if (interrupt != NULL) { 2747144467Sharti ignoreErrors = FALSE; 27481590Srgrimes 2749144467Sharti JobStart(interrupt, JOB_IGNDOTS, (Job *)NULL); 2750144467Sharti while (nJobs) { 2751144467Sharti Job_CatchOutput(0); 2752144467Sharti Job_CatchChildren(!usePipes); 2753144467Sharti } 2754144467Sharti } 27551590Srgrimes } 27561590Srgrimes} 27571590Srgrimes 2758144467Sharti/** 2759144467Sharti * Job_Finish 27601590Srgrimes * Do final processing such as the running of the commands 27618874Srgrimes * attached to the .END target. 27621590Srgrimes * 27631590Srgrimes * Results: 27641590Srgrimes * Number of errors reported. 27651590Srgrimes */ 27661590Srgrimesint 2767104696SjmallettJob_Finish(void) 27681590Srgrimes{ 2769138232Sharti 2770144467Sharti if (postCommands != NULL && !Lst_IsEmpty(&postCommands->commands)) { 2771144467Sharti if (errors) { 2772144467Sharti Error("Errors reported so .END ignored"); 2773144467Sharti } else { 2774144467Sharti JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL); 27751590Srgrimes 2776144467Sharti while (nJobs) { 2777144467Sharti Job_CatchOutput(0); 2778144467Sharti Job_CatchChildren(!usePipes); 2779144467Sharti } 2780144467Sharti } 27811590Srgrimes } 2782144467Sharti if (fifoFd >= 0) { 2783144467Sharti close(fifoFd); 2784144467Sharti fifoFd = -1; 2785144467Sharti if (fifoMaster) 2786144467Sharti unlink(fifoName); 2787144467Sharti } 2788144467Sharti return (errors); 27891590Srgrimes} 27901590Srgrimes 2791144467Sharti/** 2792144467Sharti * Job_Wait 27931590Srgrimes * Waits for all running jobs to finish and returns. Sets 'aborting' 27941590Srgrimes * to ABORT_WAIT to prevent other jobs from starting. 27951590Srgrimes * 27961590Srgrimes * Side Effects: 27971590Srgrimes * Currently running jobs finish. 27981590Srgrimes */ 27991590Srgrimesvoid 2800104696SjmallettJob_Wait(void) 28011590Srgrimes{ 2802138232Sharti 2803144467Sharti aborting = ABORT_WAIT; 2804144467Sharti while (nJobs != 0) { 2805144467Sharti Job_CatchOutput(0); 2806144467Sharti Job_CatchChildren(!usePipes); 2807144467Sharti } 2808144467Sharti aborting = 0; 28091590Srgrimes} 28101590Srgrimes 2811144467Sharti/** 2812144467Sharti * Job_AbortAll 28131590Srgrimes * Abort all currently running jobs without handling output or anything. 28141590Srgrimes * This function is to be called only in the event of a major 28151590Srgrimes * error. Most definitely NOT to be called from JobInterrupt. 28161590Srgrimes * 28171590Srgrimes * Side Effects: 28181590Srgrimes * All children are killed, not just the firstborn 28191590Srgrimes */ 28201590Srgrimesvoid 2821104696SjmallettJob_AbortAll(void) 28221590Srgrimes{ 2823144467Sharti Job *job; /* the job descriptor in that element */ 2824144467Sharti int foo; 28258874Srgrimes 2826144467Sharti aborting = ABORT_ERROR; 28278874Srgrimes 2828144467Sharti if (nJobs) { 2829144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2830144467Sharti /* 2831144467Sharti * kill the child process with increasingly drastic 2832144467Sharti * signals to make darn sure it's dead. 2833144467Sharti */ 2834144467Sharti KILL(job->pid, SIGINT); 2835144467Sharti KILL(job->pid, SIGKILL); 2836144467Sharti } 28371590Srgrimes } 28388874Srgrimes 2839144467Sharti /* 2840144467Sharti * Catch as many children as want to report in at first, then give up 2841144467Sharti */ 2842144467Sharti while (waitpid((pid_t)-1, &foo, WNOHANG) > 0) 2843144665Sharti ; 28441590Srgrimes} 284518730Ssteve 2846144467Sharti/** 2847144467Sharti * JobRestartJobs 284818730Ssteve * Tries to restart stopped jobs if there are slots available. 284918730Ssteve * Note that this tries to restart them regardless of pending errors. 285018730Ssteve * It's not good to leave stopped jobs lying around! 285118730Ssteve * 285218730Ssteve * Side Effects: 285318730Ssteve * Resumes(and possibly migrates) jobs. 285418730Ssteve */ 285518730Sstevestatic void 2856104696SjmallettJobRestartJobs(void) 285718730Ssteve{ 2858144494Sharti Job *job; 2859144494Sharti 2860144494Sharti while (!jobFull && (job = TAILQ_FIRST(&stoppedJobs)) != NULL) { 2861144467Sharti DEBUGF(JOB, ("Job queue is not full. " 2862144467Sharti "Restarting a stopped job.\n")); 2863144494Sharti TAILQ_REMOVE(&stoppedJobs, job, link); 2864144494Sharti JobRestart(job); 2865144467Sharti } 286618730Ssteve} 2867146054Sharti 2868146054Sharti/** 2869146054Sharti * Cmd_Exec 2870146054Sharti * Execute the command in cmd, and return the output of that command 2871146054Sharti * in a string. 2872146054Sharti * 2873146054Sharti * Results: 2874146054Sharti * A string containing the output of the command, or the empty string 2875146054Sharti * If error is not NULL, it contains the reason for the command failure 2876146054Sharti * 2877146054Sharti * Side Effects: 2878146054Sharti * The string must be freed by the caller. 2879146054Sharti */ 2880146054ShartiBuffer * 2881146054ShartiCmd_Exec(const char *cmd, const char **error) 2882146054Sharti{ 2883146054Sharti int fds[2]; /* Pipe streams */ 2884146054Sharti int cpid; /* Child PID */ 2885146054Sharti int pid; /* PID from wait() */ 2886146054Sharti int status; /* command exit status */ 2887146054Sharti Buffer *buf; /* buffer to store the result */ 2888146054Sharti ssize_t rcnt; 2889146054Sharti 2890146054Sharti *error = NULL; 2891146054Sharti buf = Buf_Init(0); 2892146054Sharti 2893146054Sharti if (shellPath == NULL) 2894146054Sharti Shell_Init(); 2895146054Sharti /* 2896146054Sharti * Open a pipe for fetching its output 2897146054Sharti */ 2898146054Sharti if (pipe(fds) == -1) { 2899146054Sharti *error = "Couldn't create pipe for \"%s\""; 2900146054Sharti return (buf); 2901146054Sharti } 2902146054Sharti 2903146054Sharti /* 2904146054Sharti * Fork 2905146054Sharti */ 2906146058Sharti if ((cpid = vfork()) == -1) { 2907146058Sharti *error = "Couldn't exec \"%s\""; 2908146058Sharti return (buf); 2909146058Sharti } 2910146058Sharti 2911146058Sharti if (cpid == 0) { 2912146058Sharti char *args[4]; 2913146054Sharti /* 2914146054Sharti * Close input side of pipe 2915146054Sharti */ 2916146054Sharti close(fds[0]); 2917146054Sharti 2918146054Sharti /* 2919146054Sharti * Duplicate the output stream to the shell's output, then 2920146054Sharti * shut the extra thing down. Note we don't fetch the error 2921146054Sharti * stream...why not? Why? 2922146054Sharti */ 2923146054Sharti dup2(fds[1], 1); 2924146054Sharti close(fds[1]); 2925146054Sharti 2926146054Sharti 2927146058Sharti /* Set up arguments for shell */ 2928146058Sharti args[0] = shellName; 2929146058Sharti args[1] = "-c"; 2930146058Sharti args[2] = cmd; 2931146058Sharti args[3] = NULL; 2932146054Sharti 2933146058Sharti execv(shellPath, args); 2934146058Sharti _exit(1); 2935146058Sharti /* NOTREACHED */ 2936146054Sharti 2937146058Sharti } 2938146058Sharti /* 2939146058Sharti * No need for the writing half 2940146058Sharti */ 2941146058Sharti close(fds[1]); 2942146054Sharti 2943146058Sharti do { 2944146058Sharti char result[BUFSIZ]; 2945146054Sharti 2946146058Sharti rcnt = read(fds[0], result, sizeof(result)); 2947146058Sharti if (rcnt != -1) 2948146058Sharti Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result); 2949146058Sharti } while (rcnt > 0 || (rcnt == -1 && errno == EINTR)); 2950146054Sharti 2951146058Sharti if (rcnt == -1) 2952146058Sharti *error = "Error reading shell's output for \"%s\""; 2953146054Sharti 2954146058Sharti /* 2955146058Sharti * Close the input side of the pipe. 2956146058Sharti */ 2957146058Sharti close(fds[0]); 2958146054Sharti 2959146058Sharti /* 2960146058Sharti * Wait for the process to exit. 2961146058Sharti */ 2962146058Sharti while (((pid = wait(&status)) != cpid) && (pid >= 0)) 2963146058Sharti continue; 2964146054Sharti 2965146058Sharti if (status) 2966146058Sharti *error = "\"%s\" returned non-zero status"; 2967146054Sharti 2968146058Sharti Buf_StripNewlines(buf); 2969146054Sharti 2970146054Sharti return (buf); 2971146054Sharti} 2972146054Sharti 2973146056Sharti 2974146056Sharti/*- 2975146056Sharti * compat.c -- 2976146056Sharti * The routines in this file implement the full-compatibility 2977146056Sharti * mode of PMake. Most of the special functionality of PMake 2978146056Sharti * is available in this mode. Things not supported: 2979146056Sharti * - different shells. 2980146056Sharti * - friendly variable substitution. 2981146056Sharti * 2982146056Sharti * Interface: 2983146056Sharti * Compat_Run Initialize things for this module and recreate 2984146061Sharti * thems as need creatin' 2985146056Sharti */ 2986146056Sharti 2987146056Sharti/* 2988146056Sharti * The following array is used to make a fast determination of which 2989146056Sharti * characters are interpreted specially by the shell. If a command 2990146056Sharti * contains any of these characters, it is executed by the shell, not 2991146056Sharti * directly by us. 2992146056Sharti */ 2993146056Shartistatic const char *sh_builtin[] = { 2994146056Sharti "alias", "cd", "eval", "exec", 2995146056Sharti "exit", "read", "set", "ulimit", 2996146056Sharti "unalias", "umask", "unset", "wait", 2997146056Sharti ":", NULL 2998146056Sharti}; 2999146056Sharti 3000146061Shartistatic char meta[256]; 3001146056Sharti 3002146056Shartistatic GNode *curTarg = NULL; 3003146056Shartistatic GNode *ENDNode; 3004146056Sharti 3005146056Shartistatic void 3006146056ShartiCompatInit(void) 3007146056Sharti{ 3008146056Sharti const char *cp; /* Pointer to string of shell meta-characters */ 3009146056Sharti 3010146056Sharti for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) { 3011146056Sharti meta[(unsigned char)*cp] = 1; 3012146056Sharti } 3013146056Sharti /* 3014146056Sharti * The null character serves as a sentinel in the string. 3015146056Sharti */ 3016146056Sharti meta[0] = 1; 3017146056Sharti} 3018146056Sharti 3019146056Sharti/* 3020146056Sharti * Interrupt handler - set flag and defer handling to the main code 3021146056Sharti */ 3022146056Shartistatic void 3023146056ShartiCompatCatchSig(int signo) 3024146056Sharti{ 3025146056Sharti 3026146056Sharti interrupted = signo; 3027146056Sharti} 3028146056Sharti 3029146056Sharti/*- 3030146056Sharti *----------------------------------------------------------------------- 3031146056Sharti * CompatInterrupt -- 3032146056Sharti * Interrupt the creation of the current target and remove it if 3033146056Sharti * it ain't precious. 3034146056Sharti * 3035146056Sharti * Results: 3036146056Sharti * None. 3037146056Sharti * 3038146056Sharti * Side Effects: 3039146056Sharti * The target is removed and the process exits. If .INTERRUPT exists, 3040146056Sharti * its commands are run first WITH INTERRUPTS IGNORED.. 3041146056Sharti * 3042146056Sharti *----------------------------------------------------------------------- 3043146056Sharti */ 3044146056Shartistatic void 3045146056ShartiCompatInterrupt(int signo) 3046146056Sharti{ 3047146056Sharti GNode *gn; 3048146056Sharti sigset_t nmask, omask; 3049146056Sharti LstNode *ln; 3050146056Sharti 3051146056Sharti sigemptyset(&nmask); 3052146056Sharti sigaddset(&nmask, SIGINT); 3053146056Sharti sigaddset(&nmask, SIGTERM); 3054146056Sharti sigaddset(&nmask, SIGHUP); 3055146056Sharti sigaddset(&nmask, SIGQUIT); 3056146056Sharti sigprocmask(SIG_SETMASK, &nmask, &omask); 3057146056Sharti 3058146056Sharti /* prevent recursion in evaluation of .INTERRUPT */ 3059146056Sharti interrupted = 0; 3060146056Sharti 3061146056Sharti if (curTarg != NULL && !Targ_Precious(curTarg)) { 3062146056Sharti char *p1; 3063146061Sharti char *file = Var_Value(TARGET, curTarg, &p1); 3064146056Sharti 3065146056Sharti if (!noExecute && eunlink(file) != -1) { 3066146056Sharti printf("*** %s removed\n", file); 3067146056Sharti } 3068146056Sharti free(p1); 3069146056Sharti } 3070146056Sharti 3071146056Sharti /* 3072146056Sharti * Run .INTERRUPT only if hit with interrupt signal 3073146056Sharti */ 3074146056Sharti if (signo == SIGINT) { 3075146056Sharti gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 3076146056Sharti if (gn != NULL) { 3077146056Sharti LST_FOREACH(ln, &gn->commands) { 3078146056Sharti if (Compat_RunCommand(Lst_Datum(ln), gn)) 3079146056Sharti break; 3080146056Sharti } 3081146056Sharti } 3082146056Sharti } 3083146056Sharti 3084146056Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 3085146056Sharti 3086146056Sharti if (signo == SIGQUIT) 3087146056Sharti exit(signo); 3088146056Sharti signal(signo, SIG_DFL); 3089146056Sharti kill(getpid(), signo); 3090146056Sharti} 3091146056Sharti 3092146056Sharti/*- 3093146056Sharti *----------------------------------------------------------------------- 3094146056Sharti * shellneed -- 3095146056Sharti * 3096146056Sharti * Results: 3097146056Sharti * Returns 1 if a specified line must be executed by the shell, 3098146056Sharti * and 0 if it can be run via execve. 3099146056Sharti * 3100146056Sharti * Side Effects: 3101146056Sharti * Uses brk_string so destroys the contents of argv. 3102146056Sharti * 3103146056Sharti *----------------------------------------------------------------------- 3104146056Sharti */ 3105146056Shartistatic int 3106146056Shartishellneed(char *cmd) 3107146056Sharti{ 3108146056Sharti char **av; 3109146056Sharti const char **p; 3110146056Sharti 3111146056Sharti av = brk_string(cmd, NULL, TRUE); 3112146056Sharti for (p = sh_builtin; *p != 0; p++) 3113146056Sharti if (strcmp(av[1], *p) == 0) 3114146056Sharti return (1); 3115146056Sharti return (0); 3116146056Sharti} 3117146056Sharti 3118146056Sharti/*- 3119146056Sharti *----------------------------------------------------------------------- 3120146056Sharti * Compat_RunCommand -- 3121146056Sharti * Execute the next command for a target. If the command returns an 3122146056Sharti * error, the node's made field is set to ERROR and creation stops. 3123146056Sharti * The node from which the command came is also given. 3124146056Sharti * 3125146056Sharti * Results: 3126146056Sharti * 0 if the command succeeded, 1 if an error occurred. 3127146056Sharti * 3128146056Sharti * Side Effects: 3129146056Sharti * The node's 'made' field may be set to ERROR. 3130146056Sharti * 3131146056Sharti *----------------------------------------------------------------------- 3132146056Sharti */ 3133146056Shartiint 3134146056ShartiCompat_RunCommand(char *cmd, GNode *gn) 3135146056Sharti{ 3136146056Sharti char *cmdStart; /* Start of expanded command */ 3137146056Sharti char *cp; 3138146056Sharti Boolean silent; /* Don't print command */ 3139146056Sharti Boolean doit; /* Execute even in -n */ 3140146056Sharti Boolean errCheck; /* Check errors */ 3141146056Sharti int reason; /* Reason for child's death */ 3142146056Sharti int status; /* Description of child's death */ 3143146056Sharti int cpid; /* Child actually found */ 3144146056Sharti ReturnStatus rstat; /* Status of fork */ 3145146056Sharti LstNode *cmdNode; /* Node where current command is located */ 3146146056Sharti char **av; /* Argument vector for thing to exec */ 3147146056Sharti char *cmd_save; /* saved cmd */ 3148146056Sharti 3149146056Sharti /* 3150146056Sharti * Avoid clobbered variable warnings by forcing the compiler 3151146056Sharti * to ``unregister'' variables 3152146056Sharti */ 3153146056Sharti#if __GNUC__ 3154146056Sharti (void)&av; 3155146056Sharti (void)&errCheck; 3156146056Sharti#endif 3157146056Sharti silent = gn->type & OP_SILENT; 3158146056Sharti errCheck = !(gn->type & OP_IGNORE); 3159146056Sharti doit = FALSE; 3160146056Sharti 3161146056Sharti cmdNode = Lst_Member(&gn->commands, cmd); 3162146056Sharti cmdStart = Buf_Peel(Var_Subst(cmd, gn, FALSE)); 3163146056Sharti 3164146056Sharti /* 3165146056Sharti * brk_string will return an argv with a NULL in av[0], thus causing 3166146056Sharti * execvp to choke and die horribly. Besides, how can we execute a null 3167146056Sharti * command? In any case, we warn the user that the command expanded to 3168146056Sharti * nothing (is this the right thing to do?). 3169146056Sharti */ 3170146056Sharti if (*cmdStart == '\0') { 3171146056Sharti free(cmdStart); 3172146056Sharti Error("%s expands to empty string", cmd); 3173146056Sharti return (0); 3174146056Sharti } else { 3175146056Sharti cmd = cmdStart; 3176146056Sharti } 3177146056Sharti Lst_Replace(cmdNode, cmdStart); 3178146056Sharti 3179146056Sharti if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) { 3180146056Sharti Lst_AtEnd(&ENDNode->commands, cmdStart); 3181146056Sharti return (0); 3182146056Sharti } else if (strcmp(cmdStart, "...") == 0) { 3183146056Sharti gn->type |= OP_SAVE_CMDS; 3184146056Sharti return (0); 3185146056Sharti } 3186146056Sharti 3187146056Sharti while (*cmd == '@' || *cmd == '-' || *cmd == '+') { 3188146056Sharti switch (*cmd) { 3189146056Sharti 3190146056Sharti case '@': 3191146056Sharti silent = DEBUG(LOUD) ? FALSE : TRUE; 3192146056Sharti break; 3193146056Sharti 3194146056Sharti case '-': 3195146056Sharti errCheck = FALSE; 3196146056Sharti break; 3197146056Sharti 3198146056Sharti case '+': 3199146056Sharti doit = TRUE; 3200146056Sharti if (!meta[0]) /* we came here from jobs */ 3201146056Sharti CompatInit(); 3202146056Sharti break; 3203146056Sharti } 3204146056Sharti cmd++; 3205146056Sharti } 3206146056Sharti 3207146056Sharti while (isspace((unsigned char)*cmd)) 3208146056Sharti cmd++; 3209146056Sharti 3210146056Sharti /* 3211146056Sharti * Search for meta characters in the command. If there are no meta 3212146056Sharti * characters, there's no need to execute a shell to execute the 3213146056Sharti * command. 3214146056Sharti */ 3215146056Sharti for (cp = cmd; !meta[(unsigned char)*cp]; cp++) 3216146056Sharti continue; 3217146056Sharti 3218146056Sharti /* 3219146056Sharti * Print the command before echoing if we're not supposed to be quiet 3220146056Sharti * for this one. We also print the command if -n given, but not if '+'. 3221146056Sharti */ 3222146056Sharti if (!silent || (noExecute && !doit)) { 3223146056Sharti printf("%s\n", cmd); 3224146056Sharti fflush(stdout); 3225146056Sharti } 3226146056Sharti 3227146056Sharti /* 3228146056Sharti * If we're not supposed to execute any commands, this is as far as 3229146056Sharti * we go... 3230146056Sharti */ 3231146056Sharti if (!doit && noExecute) { 3232146056Sharti return (0); 3233146056Sharti } 3234146056Sharti 3235146056Sharti if (*cp != '\0') { 3236146056Sharti /* 3237146056Sharti * If *cp isn't the null character, we hit a "meta" character 3238146056Sharti * and need to pass the command off to the shell. We give the 3239146056Sharti * shell the -e flag as well as -c if it's supposed to exit 3240146056Sharti * when it hits an error. 3241146056Sharti */ 3242146056Sharti static char *shargv[4]; 3243146056Sharti 3244146056Sharti shargv[0] = shellPath; 3245146056Sharti shargv[1] = (errCheck ? "-ec" : "-c"); 3246146056Sharti shargv[2] = cmd; 3247146056Sharti shargv[3] = NULL; 3248146056Sharti av = shargv; 3249146056Sharti 3250146056Sharti } else if (shellneed(cmd)) { 3251146056Sharti /* 3252146056Sharti * This command must be passed by the shell for other reasons.. 3253146056Sharti * or.. possibly not at all. 3254146056Sharti */ 3255146056Sharti static char *shargv[4]; 3256146056Sharti 3257146056Sharti shargv[0] = shellPath; 3258146056Sharti shargv[1] = (errCheck ? "-ec" : "-c"); 3259146056Sharti shargv[2] = cmd; 3260146056Sharti shargv[3] = NULL; 3261146056Sharti av = shargv; 3262146056Sharti 3263146056Sharti } else { 3264146056Sharti /* 3265146056Sharti * No meta-characters, so no need to exec a shell. Break the 3266146056Sharti * command into words to form an argument vector we can execute. 3267146056Sharti * brk_string sticks our name in av[0], so we have to 3268146056Sharti * skip over it... 3269146056Sharti */ 3270146056Sharti av = brk_string(cmd, NULL, TRUE); 3271146056Sharti av += 1; 3272146056Sharti } 3273146056Sharti 3274146056Sharti /* 3275146056Sharti * Fork and execute the single command. If the fork fails, we abort. 3276146056Sharti */ 3277146058Sharti if ((cpid = vfork()) == -1) { 3278146056Sharti Fatal("Could not fork"); 3279146056Sharti } 3280146058Sharti 3281146056Sharti if (cpid == 0) { 3282146056Sharti execvp(av[0], av); 3283146056Sharti write(STDERR_FILENO, av[0], strlen(av[0])); 3284146056Sharti write(STDERR_FILENO, ":", 1); 3285146056Sharti write(STDERR_FILENO, strerror(errno), strlen(strerror(errno))); 3286146056Sharti write(STDERR_FILENO, "\n", 1); 3287146056Sharti _exit(1); 3288146056Sharti } 3289146056Sharti /* 3290146058Sharti * we need to print out the command associated with this 3291146058Sharti * Gnode in Targ_PrintCmd from Targ_PrintGraph when debugging 3292146058Sharti * at level g2, in main(), Fatal() and DieHorribly(), 3293146058Sharti * therefore do not free it when debugging. 3294146056Sharti */ 3295146056Sharti if (!DEBUG(GRAPH2)) { 3296146056Sharti free(cmdStart); 3297146056Sharti Lst_Replace(cmdNode, cmd_save); 3298146056Sharti } 3299146056Sharti /* 3300146056Sharti * The child is off and running. Now all we can do is wait... 3301146056Sharti */ 3302146056Sharti while (1) { 3303146056Sharti while ((rstat = wait(&reason)) != cpid) { 3304146056Sharti if (interrupted || (rstat == -1 && errno != EINTR)) { 3305146056Sharti break; 3306146056Sharti } 3307146056Sharti } 3308146056Sharti if (interrupted) 3309146056Sharti CompatInterrupt(interrupted); 3310146056Sharti 3311146056Sharti if (rstat > -1) { 3312146056Sharti if (WIFSTOPPED(reason)) { 3313146058Sharti /* stopped */ 3314146058Sharti status = WSTOPSIG(reason); 3315146056Sharti } else if (WIFEXITED(reason)) { 3316146058Sharti /* exited */ 3317146058Sharti status = WEXITSTATUS(reason); 3318146056Sharti if (status != 0) { 3319146058Sharti printf("*** Error code %d", 3320146058Sharti status); 3321146056Sharti } 3322146056Sharti } else { 3323146058Sharti /* signaled */ 3324146058Sharti status = WTERMSIG(reason); 3325146056Sharti printf("*** Signal %d", status); 3326146056Sharti } 3327146056Sharti 3328146056Sharti if (!WIFEXITED(reason) || status != 0) { 3329146056Sharti if (errCheck) { 3330146056Sharti gn->made = ERROR; 3331146056Sharti if (keepgoing) { 3332146056Sharti /* 3333146058Sharti * Abort the current 3334146058Sharti * target, but let 3335146058Sharti * others continue. 3336146056Sharti */ 3337146056Sharti printf(" (continuing)\n"); 3338146056Sharti } 3339146056Sharti } else { 3340146056Sharti /* 3341146058Sharti * Continue executing 3342146058Sharti * commands for this target. 3343146058Sharti * If we return 0, this will 3344146056Sharti * happen... 3345146056Sharti */ 3346146056Sharti printf(" (ignored)\n"); 3347146056Sharti status = 0; 3348146056Sharti } 3349146056Sharti } 3350146056Sharti break; 3351146056Sharti } else { 3352146056Sharti Fatal("error in wait: %d", rstat); 3353146058Sharti /* NOTREACHED */ 3354146056Sharti } 3355146056Sharti } 3356146056Sharti 3357146056Sharti return (status); 3358146056Sharti} 3359146056Sharti 3360146056Sharti/*- 3361146056Sharti *----------------------------------------------------------------------- 3362146056Sharti * CompatMake -- 3363146056Sharti * Make a target, given the parent, to abort if necessary. 3364146056Sharti * 3365146056Sharti * Side Effects: 3366146056Sharti * If an error is detected and not being ignored, the process exits. 3367146056Sharti * 3368146056Sharti *----------------------------------------------------------------------- 3369146056Sharti */ 3370146056Shartistatic int 3371146056ShartiCompatMake(GNode *gn, GNode *pgn) 3372146056Sharti{ 3373146056Sharti LstNode *ln; 3374146056Sharti 3375146056Sharti if (gn->type & OP_USE) { 3376146056Sharti Make_HandleUse(gn, pgn); 3377146056Sharti 3378146056Sharti } else if (gn->made == UNMADE) { 3379146056Sharti /* 3380146056Sharti * First mark ourselves to be made, then apply whatever 3381146056Sharti * transformations the suffix module thinks are necessary. 3382146056Sharti * Once that's done, we can descend and make all our children. 3383146056Sharti * If any of them has an error but the -k flag was given, our 3384146056Sharti * 'make' field will be set FALSE again. This is our signal to 3385146056Sharti * not attempt to do anything but abort our parent as well. 3386146056Sharti */ 3387146056Sharti gn->make = TRUE; 3388146056Sharti gn->made = BEINGMADE; 3389146056Sharti Suff_FindDeps(gn); 3390146056Sharti LST_FOREACH(ln, &gn->children) 3391146056Sharti CompatMake(Lst_Datum(ln), gn); 3392146056Sharti if (!gn->make) { 3393146056Sharti gn->made = ABORTED; 3394146056Sharti pgn->make = FALSE; 3395146056Sharti return (0); 3396146056Sharti } 3397146056Sharti 3398146056Sharti if (Lst_Member(&gn->iParents, pgn) != NULL) { 3399146056Sharti char *p1; 3400146056Sharti Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn); 3401146056Sharti free(p1); 3402146056Sharti } 3403146056Sharti 3404146056Sharti /* 3405146056Sharti * All the children were made ok. Now cmtime contains the 3406146056Sharti * modification time of the newest child, we need to find out 3407146056Sharti * if we exist and when we were modified last. The criteria for 3408146056Sharti * datedness are defined by the Make_OODate function. 3409146056Sharti */ 3410146056Sharti DEBUGF(MAKE, ("Examining %s...", gn->name)); 3411146056Sharti if (!Make_OODate(gn)) { 3412146056Sharti gn->made = UPTODATE; 3413146056Sharti DEBUGF(MAKE, ("up-to-date.\n")); 3414146056Sharti return (0); 3415146056Sharti } else { 3416146056Sharti DEBUGF(MAKE, ("out-of-date.\n")); 3417146056Sharti } 3418146056Sharti 3419146056Sharti /* 3420146056Sharti * If the user is just seeing if something is out-of-date, 3421146056Sharti * exit now to tell him/her "yes". 3422146056Sharti */ 3423146056Sharti if (queryFlag) { 3424146056Sharti exit(1); 3425146056Sharti } 3426146056Sharti 3427146056Sharti /* 3428146056Sharti * We need to be re-made. We also have to make sure we've got 3429146056Sharti * a $? variable. To be nice, we also define the $> variable 3430146056Sharti * using Make_DoAllVar(). 3431146056Sharti */ 3432146056Sharti Make_DoAllVar(gn); 3433146056Sharti 3434146056Sharti /* 3435146056Sharti * Alter our type to tell if errors should be ignored or things 3436146056Sharti * should not be printed so Compat_RunCommand knows what to do. 3437146056Sharti */ 3438146056Sharti if (Targ_Ignore(gn)) { 3439146056Sharti gn->type |= OP_IGNORE; 3440146056Sharti } 3441146056Sharti if (Targ_Silent(gn)) { 3442146056Sharti gn->type |= OP_SILENT; 3443146056Sharti } 3444146056Sharti 3445146056Sharti if (Job_CheckCommands(gn, Fatal)) { 3446146056Sharti /* 3447146056Sharti * Our commands are ok, but we still have to worry 3448146056Sharti * about the -t flag... 3449146056Sharti */ 3450146056Sharti if (!touchFlag) { 3451146056Sharti curTarg = gn; 3452146056Sharti LST_FOREACH(ln, &gn->commands) { 3453146056Sharti if (Compat_RunCommand(Lst_Datum(ln), 3454146056Sharti gn)) 3455146056Sharti break; 3456146056Sharti } 3457146056Sharti curTarg = NULL; 3458146056Sharti } else { 3459146056Sharti Job_Touch(gn, gn->type & OP_SILENT); 3460146056Sharti } 3461146056Sharti } else { 3462146056Sharti gn->made = ERROR; 3463146056Sharti } 3464146056Sharti 3465146056Sharti if (gn->made != ERROR) { 3466146056Sharti /* 3467146056Sharti * If the node was made successfully, mark it so, update 3468146056Sharti * its modification time and timestamp all its parents. 3469146056Sharti * Note that for .ZEROTIME targets, the timestamping 3470146056Sharti * isn't done. This is to keep its state from affecting 3471146056Sharti * that of its parent. 3472146056Sharti */ 3473146056Sharti gn->made = MADE; 3474146056Sharti#ifndef RECHECK 3475146056Sharti /* 3476146056Sharti * We can't re-stat the thing, but we can at least take 3477146056Sharti * care of rules where a target depends on a source that 3478146056Sharti * actually creates the target, but only if it has 3479146056Sharti * changed, e.g. 3480146056Sharti * 3481146056Sharti * parse.h : parse.o 3482146056Sharti * 3483146056Sharti * parse.o : parse.y 3484146061Sharti * yacc -d parse.y 3485146061Sharti * cc -c y.tab.c 3486146061Sharti * mv y.tab.o parse.o 3487146061Sharti * cmp -s y.tab.h parse.h || mv y.tab.h parse.h 3488146056Sharti * 3489146056Sharti * In this case, if the definitions produced by yacc 3490146056Sharti * haven't changed from before, parse.h won't have been 3491146056Sharti * updated and gn->mtime will reflect the current 3492146056Sharti * modification time for parse.h. This is something of a 3493146056Sharti * kludge, I admit, but it's a useful one.. 3494146056Sharti * 3495146056Sharti * XXX: People like to use a rule like 3496146056Sharti * 3497146056Sharti * FRC: 3498146056Sharti * 3499146056Sharti * To force things that depend on FRC to be made, so we 3500146056Sharti * have to check for gn->children being empty as well... 3501146056Sharti */ 3502146056Sharti if (!Lst_IsEmpty(&gn->commands) || 3503146056Sharti Lst_IsEmpty(&gn->children)) { 3504146056Sharti gn->mtime = now; 3505146056Sharti } 3506146056Sharti#else 3507146056Sharti /* 3508146056Sharti * This is what Make does and it's actually a good 3509146056Sharti * thing, as it allows rules like 3510146056Sharti * 3511146056Sharti * cmp -s y.tab.h parse.h || cp y.tab.h parse.h 3512146056Sharti * 3513146056Sharti * to function as intended. Unfortunately, thanks to 3514146056Sharti * the stateless nature of NFS (and the speed of this 3515146056Sharti * program), there are times when the modification time 3516146056Sharti * of a file created on a remote machine will not be 3517146056Sharti * modified before the stat() implied by the Dir_MTime 3518146056Sharti * occurs, thus leading us to believe that the file 3519146056Sharti * is unchanged, wreaking havoc with files that depend 3520146056Sharti * on this one. 3521146056Sharti * 3522146056Sharti * I have decided it is better to make too much than to 3523146056Sharti * make too little, so this stuff is commented out 3524146056Sharti * unless you're sure it's ok. 3525146056Sharti * -- ardeb 1/12/88 3526146056Sharti */ 3527146056Sharti if (noExecute || Dir_MTime(gn) == 0) { 3528146056Sharti gn->mtime = now; 3529146056Sharti } 3530146056Sharti if (gn->cmtime > gn->mtime) 3531146056Sharti gn->mtime = gn->cmtime; 3532146056Sharti DEBUGF(MAKE, ("update time: %s\n", 3533146056Sharti Targ_FmtTime(gn->mtime))); 3534146056Sharti#endif 3535146056Sharti if (!(gn->type & OP_EXEC)) { 3536146056Sharti pgn->childMade = TRUE; 3537146056Sharti Make_TimeStamp(pgn, gn); 3538146056Sharti } 3539146056Sharti 3540146056Sharti } else if (keepgoing) { 3541146056Sharti pgn->make = FALSE; 3542146056Sharti 3543146056Sharti } else { 3544146056Sharti char *p1; 3545146056Sharti 3546146056Sharti printf("\n\nStop in %s.\n", 3547146056Sharti Var_Value(".CURDIR", gn, &p1)); 3548146056Sharti free(p1); 3549146056Sharti exit(1); 3550146056Sharti } 3551146056Sharti } else if (gn->made == ERROR) { 3552146056Sharti /* 3553146056Sharti * Already had an error when making this beastie. Tell the 3554146056Sharti * parent to abort. 3555146056Sharti */ 3556146056Sharti pgn->make = FALSE; 3557146056Sharti } else { 3558146056Sharti if (Lst_Member(&gn->iParents, pgn) != NULL) { 3559146056Sharti char *p1; 3560146056Sharti Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn); 3561146056Sharti free(p1); 3562146056Sharti } 3563146056Sharti switch(gn->made) { 3564146056Sharti case BEINGMADE: 3565146056Sharti Error("Graph cycles through %s\n", gn->name); 3566146056Sharti gn->made = ERROR; 3567146056Sharti pgn->make = FALSE; 3568146056Sharti break; 3569146056Sharti case MADE: 3570146056Sharti if ((gn->type & OP_EXEC) == 0) { 3571146056Sharti pgn->childMade = TRUE; 3572146056Sharti Make_TimeStamp(pgn, gn); 3573146056Sharti } 3574146056Sharti break; 3575146056Sharti case UPTODATE: 3576146056Sharti if ((gn->type & OP_EXEC) == 0) { 3577146056Sharti Make_TimeStamp(pgn, gn); 3578146056Sharti } 3579146056Sharti break; 3580146056Sharti default: 3581146056Sharti break; 3582146056Sharti } 3583146056Sharti } 3584146056Sharti 3585146056Sharti return (0); 3586146056Sharti} 3587146056Sharti 3588146056Sharti/*- 3589146056Sharti *----------------------------------------------------------------------- 3590146056Sharti * Compat_Run -- 3591146056Sharti * Start making again, given a list of target nodes. 3592146056Sharti * 3593146056Sharti * Results: 3594146056Sharti * None. 3595146056Sharti * 3596146056Sharti * Side Effects: 3597146056Sharti * Guess what? 3598146056Sharti * 3599146056Sharti *----------------------------------------------------------------------- 3600146056Sharti */ 3601146056Shartivoid 3602146056ShartiCompat_Run(Lst *targs) 3603146056Sharti{ 3604146056Sharti GNode *gn = NULL; /* Current root target */ 3605146056Sharti int error_cnt; /* Number of targets not remade due to errors */ 3606146056Sharti LstNode *ln; 3607146056Sharti 3608146056Sharti CompatInit(); 3609146056Sharti Shell_Init(); /* Set up shell. */ 3610146056Sharti 3611146056Sharti if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 3612146056Sharti signal(SIGINT, CompatCatchSig); 3613146056Sharti } 3614146056Sharti if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { 3615146056Sharti signal(SIGTERM, CompatCatchSig); 3616146056Sharti } 3617146056Sharti if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { 3618146056Sharti signal(SIGHUP, CompatCatchSig); 3619146056Sharti } 3620146056Sharti if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { 3621146056Sharti signal(SIGQUIT, CompatCatchSig); 3622146056Sharti } 3623146056Sharti 3624146056Sharti ENDNode = Targ_FindNode(".END", TARG_CREATE); 3625146056Sharti /* 3626146056Sharti * If the user has defined a .BEGIN target, execute the commands 3627146056Sharti * attached to it. 3628146056Sharti */ 3629146056Sharti if (!queryFlag) { 3630146056Sharti gn = Targ_FindNode(".BEGIN", TARG_NOCREATE); 3631146056Sharti if (gn != NULL) { 3632146056Sharti LST_FOREACH(ln, &gn->commands) { 3633146056Sharti if (Compat_RunCommand(Lst_Datum(ln), gn)) 3634146056Sharti break; 3635146056Sharti } 3636146056Sharti if (gn->made == ERROR) { 3637146056Sharti printf("\n\nStop.\n"); 3638146056Sharti exit(1); 3639146056Sharti } 3640146056Sharti } 3641146056Sharti } 3642146056Sharti 3643146056Sharti /* 3644146056Sharti * For each entry in the list of targets to create, call CompatMake on 3645146056Sharti * it to create the thing. CompatMake will leave the 'made' field of gn 3646146056Sharti * in one of several states: 3647146056Sharti * UPTODATE gn was already up-to-date 3648146056Sharti * MADE gn was recreated successfully 3649146056Sharti * ERROR An error occurred while gn was being created 3650146056Sharti * ABORTED gn was not remade because one of its inferiors 3651146056Sharti * could not be made due to errors. 3652146056Sharti */ 3653146056Sharti error_cnt = 0; 3654146056Sharti while (!Lst_IsEmpty(targs)) { 3655146056Sharti gn = Lst_DeQueue(targs); 3656146056Sharti CompatMake(gn, gn); 3657146056Sharti 3658146056Sharti if (gn->made == UPTODATE) { 3659146056Sharti printf("`%s' is up to date.\n", gn->name); 3660146056Sharti } else if (gn->made == ABORTED) { 3661146056Sharti printf("`%s' not remade because of errors.\n", 3662146056Sharti gn->name); 3663146056Sharti error_cnt += 1; 3664146056Sharti } 3665146056Sharti } 3666146056Sharti 3667146056Sharti /* 3668146056Sharti * If the user has defined a .END target, run its commands. 3669146056Sharti */ 3670146056Sharti if (error_cnt == 0) { 3671146056Sharti LST_FOREACH(ln, &ENDNode->commands) { 3672146056Sharti if (Compat_RunCommand(Lst_Datum(ln), gn)) 3673146056Sharti break; 3674146056Sharti } 3675146056Sharti } 3676146056Sharti} 3677