job.c revision 146574
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 146574 2005-05-24 15:41:34Z 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_Finish Perform any final processing which needs doing. This 80144467Sharti * includes the execution of any commands which have 81144467Sharti * been/were attached to the .END target. It should only 82144467Sharti * be called when the job table is empty. 831590Srgrimes * 84144467Sharti * Job_AbortAll Abort all currently running jobs. It doesn't handle 85144467Sharti * output or do anything for the jobs, just kills them. 86144467Sharti * It should only be called in an emergency, as it were. 871590Srgrimes * 88144467Sharti * Job_CheckCommands 89144467Sharti * Verify that the commands for a target are ok. Provide 90144467Sharti * them if necessary and possible. 911590Srgrimes * 92144467Sharti * Job_Touch Update a target without really updating it. 931590Srgrimes * 94144467Sharti * Job_Wait Wait for all currently-running jobs to finish. 95146132Sharti * 96146132Sharti * compat.c -- 97146132Sharti * The routines in this file implement the full-compatibility 98146132Sharti * mode of PMake. Most of the special functionality of PMake 99146132Sharti * is available in this mode. Things not supported: 100146132Sharti * - different shells. 101146132Sharti * - friendly variable substitution. 102146132Sharti * 103146132Sharti * Interface: 104146132Sharti * Compat_Run Initialize things for this module and recreate 105146132Sharti * thems as need creatin' 1061590Srgrimes */ 1071590Srgrimes 108144494Sharti#include <sys/queue.h> 1091590Srgrimes#include <sys/types.h> 110141104Sharti#include <sys/select.h> 1111590Srgrimes#include <sys/stat.h> 112107447Sru#ifdef USE_KQUEUE 113104475Sphk#include <sys/event.h> 114107447Sru#endif 1151590Srgrimes#include <sys/wait.h> 116141104Sharti#include <ctype.h> 117146160Sjmallett#include <err.h> 11894506Scharnier#include <errno.h> 1195814Sjkh#include <fcntl.h> 120144665Sharti#include <inttypes.h> 1211590Srgrimes#include <string.h> 1225814Sjkh#include <signal.h> 123141104Sharti#include <stdlib.h> 12480381Ssheldonh#include <unistd.h> 12594506Scharnier#include <utime.h> 126141104Sharti 127141104Sharti#include "arch.h" 128142457Sharti#include "buf.h" 129146056Sharti#include "config.h" 1301590Srgrimes#include "dir.h" 131141104Sharti#include "globals.h" 132141104Sharti#include "GNode.h" 1331590Srgrimes#include "job.h" 134141104Sharti#include "make.h" 135141104Sharti#include "parse.h" 136146574Sharti#include "proc.h" 137146572Sharti#include "shell.h" 138141104Sharti#include "str.h" 139146056Sharti#include "suff.h" 140141104Sharti#include "targ.h" 141141104Sharti#include "util.h" 142141104Sharti#include "var.h" 1431590Srgrimes 144146057Sharti#define TMPPAT "/tmp/makeXXXXXXXXXX" 145146057Sharti 146146057Sharti#ifndef USE_KQUEUE 1471590Srgrimes/* 148146057Sharti * The SEL_ constants determine the maximum amount of time spent in select 149146057Sharti * before coming out to see if a child has finished. SEL_SEC is the number of 150146057Sharti * seconds and SEL_USEC is the number of micro-seconds 151146057Sharti */ 152146057Sharti#define SEL_SEC 2 153146057Sharti#define SEL_USEC 0 154146057Sharti#endif /* !USE_KQUEUE */ 155146057Sharti 156146057Sharti/* 157144483Sharti * Job Table definitions. 158144483Sharti * 159144483Sharti * The job "table" is kept as a linked Lst in 'jobs', with the number of 160144483Sharti * active jobs maintained in the 'nJobs' variable. At no time will this 161144483Sharti * exceed the value of 'maxJobs', initialized by the Job_Init function. 162144483Sharti * 163144483Sharti * When a job is finished, the Make_Update function is called on each of the 164144483Sharti * parents of the node which was just remade. This takes care of the upward 165144483Sharti * traversal of the dependency graph. 166144483Sharti */ 167144483Sharti#define JOB_BUFSIZE 1024 168144483Shartitypedef struct Job { 169144665Sharti pid_t pid; /* The child's process ID */ 170144483Sharti 171144483Sharti struct GNode *node; /* The target the child is making */ 172144483Sharti 173144483Sharti /* 174144483Sharti * A LstNode for the first command to be saved after the job completes. 175144483Sharti * This is NULL if there was no "..." in the job's commands. 176144483Sharti */ 177144483Sharti LstNode *tailCmds; 178144483Sharti 179144483Sharti /* 180144483Sharti * An FILE* for writing out the commands. This is only 181144483Sharti * used before the job is actually started. 182144483Sharti */ 183144483Sharti FILE *cmdFILE; 184144483Sharti 185144483Sharti /* 186144483Sharti * A word of flags which determine how the module handles errors, 187144483Sharti * echoing, etc. for the job 188144483Sharti */ 189144483Sharti short flags; /* Flags to control treatment of job */ 190144483Sharti#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ 191144483Sharti#define JOB_SILENT 0x002 /* no output */ 192144483Sharti#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally 193144483Sharti * if we can't export it and maxLocal is 0 */ 194146061Sharti#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing 195144483Sharti * commands */ 196144483Sharti#define JOB_FIRST 0x020 /* Job is first job for the node */ 197144483Sharti#define JOB_RESTART 0x080 /* Job needs to be completely restarted */ 198144483Sharti#define JOB_RESUME 0x100 /* Job needs to be resumed b/c it stopped, 199144483Sharti * for some reason */ 200144483Sharti#define JOB_CONTINUING 0x200 /* We are in the process of resuming this job. 201144483Sharti * Used to avoid infinite recursion between 202144483Sharti * JobFinish and JobRestart */ 203144483Sharti 204144483Sharti /* union for handling shell's output */ 205144483Sharti union { 206144483Sharti /* 207144483Sharti * This part is used when usePipes is true. 208146061Sharti * The output is being caught via a pipe and the descriptors 209144483Sharti * of our pipe, an array in which output is line buffered and 210144483Sharti * the current position in that buffer are all maintained for 211144483Sharti * each job. 212144483Sharti */ 213144483Sharti struct { 214144483Sharti /* 215144483Sharti * Input side of pipe associated with 216144483Sharti * job's output channel 217144483Sharti */ 218144483Sharti int op_inPipe; 219144483Sharti 220144483Sharti /* 221144483Sharti * Output side of pipe associated with job's 222144483Sharti * output channel 223144483Sharti */ 224144483Sharti int op_outPipe; 225144483Sharti 226144483Sharti /* 227144483Sharti * Buffer for storing the output of the 228144483Sharti * job, line by line 229144483Sharti */ 230144483Sharti char op_outBuf[JOB_BUFSIZE + 1]; 231144483Sharti 232144483Sharti /* Current position in op_outBuf */ 233144483Sharti int op_curPos; 234144483Sharti } o_pipe; 235144483Sharti 236144483Sharti /* 237144483Sharti * If usePipes is false the output is routed to a temporary 238144483Sharti * file and all that is kept is the name of the file and the 239144483Sharti * descriptor open to the file. 240144483Sharti */ 241144483Sharti struct { 242144483Sharti /* Name of file to which shell output was rerouted */ 243144483Sharti char of_outFile[sizeof(TMPPAT)]; 244144483Sharti 245144483Sharti /* 246144483Sharti * Stream open to the output file. Used to funnel all 247144483Sharti * from a single job to one file while still allowing 248144483Sharti * multiple shell invocations 249144483Sharti */ 250144483Sharti int of_outFd; 251144483Sharti } o_file; 252144483Sharti 253144483Sharti } output; /* Data for tracking a shell's output */ 254144494Sharti 255144494Sharti TAILQ_ENTRY(Job) link; /* list link */ 256144483Sharti} Job; 257144483Sharti 258146061Sharti#define outPipe output.o_pipe.op_outPipe 259146061Sharti#define inPipe output.o_pipe.op_inPipe 260144483Sharti#define outBuf output.o_pipe.op_outBuf 261144483Sharti#define curPos output.o_pipe.op_curPos 262144483Sharti#define outFile output.o_file.of_outFile 263146061Sharti#define outFd output.o_file.of_outFd 264144483Sharti 265144494ShartiTAILQ_HEAD(JobList, Job); 266144494Sharti 267144483Sharti/* 2688874Srgrimes * error handling variables 2691590Srgrimes */ 270144467Shartistatic int errors = 0; /* number of errors reported */ 271144467Shartistatic int aborting = 0; /* why is the make aborting? */ 272144467Sharti#define ABORT_ERROR 1 /* Because of an error */ 273144467Sharti#define ABORT_INTERRUPT 2 /* Because it was interrupted */ 274144467Sharti#define ABORT_WAIT 3 /* Waiting for jobs to finish */ 2751590Srgrimes 27618730Ssteve/* 27718730Ssteve * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file 27818730Ssteve * is a char! So when we go above 127 we turn negative! 27918730Ssteve */ 280138232Sharti#define FILENO(a) ((unsigned)fileno(a)) 2811590Srgrimes 2821590Srgrimes/* 2831590Srgrimes * post-make command processing. The node postCommands is really just the 2841590Srgrimes * .END target but we keep it around to avoid having to search for it 2851590Srgrimes * all the time. 2861590Srgrimes */ 287144467Shartistatic GNode *postCommands; 2881590Srgrimes 2891590Srgrimes/* 290144467Sharti * The number of commands actually printed for a target. Should this 291144467Sharti * number be 0, no shell will be executed. 292144467Sharti */ 293144467Shartistatic int numCommands; 294144467Sharti 295144467Sharti/* 2961590Srgrimes * Return values from JobStart. 2971590Srgrimes */ 298144467Sharti#define JOB_RUNNING 0 /* Job is running */ 299146061Sharti#define JOB_ERROR 1 /* Error in starting the job */ 300144467Sharti#define JOB_FINISHED 2 /* The job is already finished */ 301144467Sharti#define JOB_STOPPED 3 /* The job is stopped */ 3021590Srgrimes 3031590Srgrimes/* 304146140Sharti * The maximum number of jobs that may run. This is initialize from the 305146140Sharti * -j argument for the leading make and from the FIFO for sub-makes. 306146140Sharti */ 307146140Shartistatic int maxJobs; 308146140Sharti 309144656Shartistatic int nJobs; /* The number of children currently running */ 310138916Sharti 311138916Sharti/* The structures that describe them */ 312144494Shartistatic struct JobList jobs = TAILQ_HEAD_INITIALIZER(jobs); 313138916Sharti 314146061Shartistatic Boolean jobFull; /* Flag to tell when the job table is full. It 3151590Srgrimes * is set TRUE when (1) the total number of 316137572Sphk * running jobs equals the maximum allowed */ 317104475Sphk#ifdef USE_KQUEUE 318104475Sphkstatic int kqfd; /* File descriptor obtained by kqueue() */ 319104475Sphk#else 320146061Shartistatic fd_set outputs; /* Set of descriptors of pipes connected to 3211590Srgrimes * the output channels of children */ 3221590Srgrimes#endif 3231590Srgrimes 324146061Shartistatic GNode *lastNode; /* The node for which output was most recently 3251590Srgrimes * produced. */ 326146061Shartistatic const char *targFmt; /* Format string to use to head output from a 3271590Srgrimes * job when it's not the most-recent job heard 3281590Srgrimes * from */ 3291590Srgrimes 330137202Sharti#define TARG_FMT "--- %s ---\n" /* Default format */ 331137202Sharti#define MESSAGE(fp, gn) \ 332138232Sharti fprintf(fp, targFmt, gn->name); 33318730Ssteve 3341590Srgrimes/* 335137252Sharti * When JobStart attempts to run a job but isn't allowed to 336137252Sharti * or when Job_CatchChildren detects a job that has 337137252Sharti * been stopped somehow, the job is placed on the stoppedJobs queue to be run 3388874Srgrimes * when the next job finishes. 339138916Sharti * 340138916Sharti * Lst of Job structures describing jobs that were stopped due to 341138916Sharti * concurrency limits or externally 3421590Srgrimes */ 343144494Shartistatic struct JobList stoppedJobs = TAILQ_HEAD_INITIALIZER(stoppedJobs); 3441590Srgrimes 345144656Shartistatic int fifoFd; /* Fd of our job fifo */ 346144656Shartistatic char fifoName[] = "/tmp/make_fifo_XXXXXXXXX"; 347144656Shartistatic int fifoMaster; 3481590Srgrimes 349137605Shartistatic sig_atomic_t interrupted; 350137605Sharti 351137605Sharti 3521590Srgrimes#if defined(USE_PGRP) && defined(SYSV) 35318730Ssteve# define KILL(pid, sig) killpg(-(pid), (sig)) 3541590Srgrimes#else 3551590Srgrimes# if defined(USE_PGRP) 35618730Ssteve# define KILL(pid, sig) killpg((pid), (sig)) 3571590Srgrimes# else 35818730Ssteve# define KILL(pid, sig) kill((pid), (sig)) 3591590Srgrimes# endif 3601590Srgrimes#endif 3611590Srgrimes 36218730Ssteve/* 36318730Ssteve * Grmpf... There is no way to set bits of the wait structure 36418730Ssteve * anymore with the stupid W*() macros. I liked the union wait 36518730Ssteve * stuff much more. So, we devise our own macros... This is 36618730Ssteve * really ugly, use dramamine sparingly. You have been warned. 36718730Ssteve */ 368103503Sjmallett#define W_SETMASKED(st, val, fun) \ 36918730Ssteve { \ 370138232Sharti int sh = (int)~0; \ 37118730Ssteve int mask = fun(sh); \ 37218730Ssteve \ 37318730Ssteve for (sh = 0; ((mask >> sh) & 1) == 0; sh++) \ 37418730Ssteve continue; \ 37518730Ssteve *(st) = (*(st) & ~mask) | ((val) << sh); \ 37618730Ssteve } 37718730Ssteve 378103503Sjmallett#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG) 379103503Sjmallett#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) 38018730Ssteve 38192921Simpstatic void JobRestart(Job *); 38292921Simpstatic int JobStart(GNode *, int, Job *); 38392921Simpstatic void JobDoOutput(Job *, Boolean); 38492921Simpstatic void JobInterrupt(int, int); 38592921Simpstatic void JobRestartJobs(void); 386146142Shartistatic int Compat_RunCommand(char *, struct GNode *); 3871590Srgrimes 388146132Shartistatic GNode *curTarg = NULL; 389146132Shartistatic GNode *ENDNode; 390146132Sharti 391146155Sharti/** 392146155Sharti * Create a fifo file with a uniq filename, and returns a file 393146155Sharti * descriptor to that fifo. 394146155Sharti */ 395146155Shartistatic int 396146155Shartimkfifotemp(char *template) 397146155Sharti{ 398146155Sharti char *start; 399146155Sharti char *pathend; 400146155Sharti char *ptr; 401146155Sharti const unsigned char padchar[] = 402146155Sharti "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 403146155Sharti 404146155Sharti if (template[0] == '\0') { 405146155Sharti errno = EINVAL; /* bad input string */ 406146155Sharti return (-1); 407146155Sharti } 408146155Sharti 409146155Sharti /* Find end of template string. */ 410146155Sharti pathend = strchr(template, '\0'); 411146155Sharti ptr = pathend - 1; 412146155Sharti 413146155Sharti /* 414146155Sharti * Starting from the end of the template replace spaces with 'X' in 415146155Sharti * them with random characters until there are no more 'X'. 416146155Sharti */ 417146155Sharti while (ptr >= template && *ptr == 'X') { 418146155Sharti uint32_t rand_num = arc4random() % (sizeof(padchar) - 1); 419146155Sharti *ptr-- = padchar[rand_num]; 420146155Sharti } 421146155Sharti start = ptr + 1; 422146155Sharti 423146155Sharti /* Check the target directory. */ 424146155Sharti for (; ptr > template; --ptr) { 425146155Sharti if (*ptr == '/') { 426146155Sharti struct stat sbuf; 427146155Sharti 428146155Sharti *ptr = '\0'; 429146155Sharti if (stat(template, &sbuf) != 0) 430146155Sharti return (-1); 431146155Sharti 432146155Sharti if (!S_ISDIR(sbuf.st_mode)) { 433146155Sharti errno = ENOTDIR; 434146155Sharti return (-1); 435146155Sharti } 436146155Sharti *ptr = '/'; 437146155Sharti break; 438146155Sharti } 439146155Sharti } 440146155Sharti 441146155Sharti for (;;) { 442146155Sharti if (mkfifo(template, 0600) == 0) { 443146155Sharti int fd; 444146155Sharti 445146155Sharti if ((fd = open(template, O_RDWR, 0600)) < 0) { 446146155Sharti unlink(template); 447146155Sharti return (-1); 448146155Sharti } else { 449146155Sharti return (fd); 450146155Sharti } 451146155Sharti } else { 452146155Sharti if (errno != EEXIST) { 453146155Sharti return (-1); 454146155Sharti } 455146155Sharti } 456146155Sharti 457146155Sharti /* 458146155Sharti * If we have a collision, cycle through the space of 459146155Sharti * filenames. 460146155Sharti */ 461146155Sharti for (ptr = start;;) { 462146155Sharti char *pad; 463146155Sharti 464146155Sharti if (*ptr == '\0' || ptr == pathend) 465146155Sharti return (-1); 466146155Sharti 467146155Sharti pad = strchr(padchar, *ptr); 468146155Sharti if (pad == NULL || *++pad == '\0') { 469146155Sharti *ptr++ = padchar[0]; 470146155Sharti } else { 471146155Sharti *ptr++ = *pad; 472146155Sharti break; 473146155Sharti } 474146155Sharti } 475146155Sharti } 476146155Sharti /*NOTREACHED*/ 477146155Sharti} 478146155Sharti 479146144Shartistatic void 480146144Sharticatch_child(int sig __unused) 481146144Sharti{ 482146144Sharti} 483146144Sharti 484144467Sharti/** 485146144Sharti */ 486146144Shartivoid 487146144ShartiProc_Init() 488146144Sharti{ 489146144Sharti /* 490146144Sharti * Catch SIGCHLD so that we get kicked out of select() when we 491146144Sharti * need to look at a child. This is only known to matter for the 492146144Sharti * -j case (perhaps without -P). 493146144Sharti * 494146144Sharti * XXX this is intentionally misplaced. 495146144Sharti */ 496146144Sharti struct sigaction sa; 497146144Sharti 498146144Sharti sigemptyset(&sa.sa_mask); 499146144Sharti sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; 500146144Sharti sa.sa_handler = catch_child; 501146144Sharti sigaction(SIGCHLD, &sa, NULL); 502146144Sharti} 503146144Sharti 504146144Sharti/** 505146131Sharti * Wait for child process to terminate. 506146130Sharti */ 507146130Shartistatic int 508146130ShartiProcWait(ProcStuff *ps) 509146130Sharti{ 510146130Sharti pid_t pid; 511146130Sharti int status; 512146130Sharti 513146130Sharti /* 514146130Sharti * Wait for the process to exit. 515146130Sharti */ 516146131Sharti for (;;) { 517146131Sharti pid = wait(&status); 518146131Sharti if (pid == -1 && errno != EINTR) { 519146131Sharti Fatal("error in wait: %d", pid); 520146131Sharti /* NOTREACHED */ 521146131Sharti } 522146131Sharti if (pid == ps->child_pid) { 523146131Sharti break; 524146131Sharti } 525146131Sharti if (interrupted) { 526146131Sharti break; 527146131Sharti } 528146130Sharti } 529146130Sharti 530146130Sharti return (status); 531146130Sharti} 532146130Sharti 533146130Sharti/** 534137605Sharti * JobCatchSignal 535144467Sharti * Got a signal. Set global variables and hope that someone will 536144467Sharti * handle it. 537137605Sharti */ 538137605Shartistatic void 539137605ShartiJobCatchSig(int signo) 540137605Sharti{ 541137605Sharti 542137605Sharti interrupted = signo; 543137605Sharti} 544137605Sharti 545144467Sharti/** 5461590Srgrimes * JobPassSig -- 547137252Sharti * Pass a signal on to all local jobs if 5481590Srgrimes * USE_PGRP is defined, then die ourselves. 5491590Srgrimes * 5501590Srgrimes * Side Effects: 5511590Srgrimes * We die by the same signal. 5521590Srgrimes */ 5531590Srgrimesstatic void 554104696SjmallettJobPassSig(int signo) 5551590Srgrimes{ 556144741Sharti Job *job; 557144467Sharti sigset_t nmask, omask; 558144467Sharti struct sigaction act; 5598874Srgrimes 560144467Sharti sigemptyset(&nmask); 561144467Sharti sigaddset(&nmask, signo); 562144467Sharti sigprocmask(SIG_SETMASK, &nmask, &omask); 563137605Sharti 564144467Sharti DEBUGF(JOB, ("JobPassSig(%d) called.\n", signo)); 565144741Sharti TAILQ_FOREACH(job, &jobs, link) { 566144741Sharti DEBUGF(JOB, ("JobPassSig passing signal %d to child %jd.\n", 567144741Sharti signo, (intmax_t)job->pid)); 568144741Sharti KILL(job->pid, signo); 569144741Sharti } 5701590Srgrimes 571144467Sharti /* 572144467Sharti * Deal with proper cleanup based on the signal received. We only run 573144467Sharti * the .INTERRUPT target if the signal was in fact an interrupt. 574144467Sharti * The other three termination signals are more of a "get out *now*" 575144467Sharti * command. 576144467Sharti */ 577144467Sharti if (signo == SIGINT) { 578144467Sharti JobInterrupt(TRUE, signo); 579144657Sharti } else if (signo == SIGHUP || signo == SIGTERM || signo == SIGQUIT) { 580144467Sharti JobInterrupt(FALSE, signo); 581144467Sharti } 5828874Srgrimes 583144467Sharti /* 584144467Sharti * Leave gracefully if SIGQUIT, rather than core dumping. 585144467Sharti */ 586144467Sharti if (signo == SIGQUIT) { 587144467Sharti signo = SIGINT; 588144467Sharti } 5898874Srgrimes 590144467Sharti /* 591144467Sharti * Send ourselves the signal now we've given the message to everyone 592144467Sharti * else. Note we block everything else possible while we're getting 593144467Sharti * the signal. This ensures that all our jobs get continued when we 594144467Sharti * wake up before we take any other signal. 595144467Sharti * XXX this comment seems wrong. 596144467Sharti */ 597144467Sharti act.sa_handler = SIG_DFL; 598144467Sharti sigemptyset(&act.sa_mask); 599144467Sharti act.sa_flags = 0; 600144467Sharti sigaction(signo, &act, NULL); 6011590Srgrimes 602144467Sharti DEBUGF(JOB, ("JobPassSig passing signal to self, mask = %x.\n", 603144467Sharti ~0 & ~(1 << (signo - 1)))); 604144467Sharti signal(signo, SIG_DFL); 6051590Srgrimes 606144467Sharti KILL(getpid(), signo); 60718730Ssteve 608144467Sharti signo = SIGCONT; 609144741Sharti TAILQ_FOREACH(job, &jobs, link) { 610144741Sharti DEBUGF(JOB, ("JobPassSig passing signal %d to child %jd.\n", 611144741Sharti signo, (intmax_t)job->pid)); 612144741Sharti KILL(job->pid, signo); 613144741Sharti } 6141590Srgrimes 615144467Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 616144467Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 617144467Sharti act.sa_handler = JobPassSig; 618144467Sharti sigaction(signo, &act, NULL); 6191590Srgrimes} 6201590Srgrimes 621144467Sharti/** 6221590Srgrimes * JobPrintCommand -- 6231590Srgrimes * Put out another command for the given job. If the command starts 6241590Srgrimes * with an @ or a - we process it specially. In the former case, 6251590Srgrimes * so long as the -s and -n flags weren't given to make, we stick 6261590Srgrimes * a shell-specific echoOff command in the script. In the latter, 6271590Srgrimes * we ignore errors for the entire job, unless the shell has error 6281590Srgrimes * control. 6291590Srgrimes * If the command is just "..." we take all future commands for this 6301590Srgrimes * job to be commands to be executed once the entire graph has been 6311590Srgrimes * made and return non-zero to signal that the end of the commands 6321590Srgrimes * was reached. These commands are later attached to the postCommands 63394594Sobrien * node and executed by Job_Finish when all things are done. 634142993Sharti * This function is called from JobStart via LST_FOREACH. 6351590Srgrimes * 6361590Srgrimes * Results: 6371590Srgrimes * Always 0, unless the command was "..." 6381590Srgrimes * 6391590Srgrimes * Side Effects: 6401590Srgrimes * If the command begins with a '-' and the shell has no error control, 6411590Srgrimes * the JOB_IGNERR flag is set in the job descriptor. 6421590Srgrimes * If the command is "..." and we're not ignoring such things, 6431590Srgrimes * tailCmds is set to the successor node of the cmd. 6441590Srgrimes * numCommands is incremented if the command is actually printed. 6451590Srgrimes */ 6461590Srgrimesstatic int 647144741ShartiJobPrintCommand(char *cmd, Job *job) 6481590Srgrimes{ 649144467Sharti Boolean noSpecials; /* true if we shouldn't worry about 650141258Sharti * inserting special commands into 651141258Sharti * the input stream. */ 652144467Sharti Boolean shutUp = FALSE; /* true if we put a no echo command 653141258Sharti * into the command file */ 654144467Sharti Boolean errOff = FALSE; /* true if we turned error checking 655141258Sharti * off before printing the command 656141258Sharti * and need to turn it back on */ 657144467Sharti const char *cmdTemplate;/* Template to use when printing the command */ 658144467Sharti char *cmdStart; /* Start of expanded command */ 659144467Sharti LstNode *cmdNode; /* Node for replacing the command */ 6601590Srgrimes 661144467Sharti noSpecials = (noExecute && !(job->node->type & OP_MAKE)); 6621590Srgrimes 663144467Sharti if (strcmp(cmd, "...") == 0) { 664144467Sharti job->node->type |= OP_SAVE_CMDS; 665144467Sharti if ((job->flags & JOB_IGNDOTS) == 0) { 666144467Sharti job->tailCmds = 667144467Sharti Lst_Succ(Lst_Member(&job->node->commands, cmd)); 668144467Sharti return (1); 669144467Sharti } 670144467Sharti return (0); 6711590Srgrimes } 6721590Srgrimes 673144467Sharti#define DBPRINTF(fmt, arg) \ 674144467Sharti DEBUGF(JOB, (fmt, arg)); \ 675144467Sharti fprintf(job->cmdFILE, fmt, arg); \ 676144467Sharti fflush(job->cmdFILE); 6771590Srgrimes 678144467Sharti numCommands += 1; 6791590Srgrimes 680144467Sharti /* 681144467Sharti * For debugging, we replace each command with the result of expanding 682144467Sharti * the variables in the command. 683144467Sharti */ 684144467Sharti cmdNode = Lst_Member(&job->node->commands, cmd); 685142457Sharti 686146027Sharti cmd = Buf_Peel(Var_Subst(cmd, job->node, FALSE)); 687144467Sharti cmdStart = cmd; 688142457Sharti 689144467Sharti Lst_Replace(cmdNode, cmdStart); 6901590Srgrimes 691144467Sharti cmdTemplate = "%s\n"; 6921590Srgrimes 693144467Sharti /* 694144467Sharti * Check for leading @', -' or +'s to control echoing, error checking, 695144467Sharti * and execution on -n. 696144467Sharti */ 697144467Sharti while (*cmd == '@' || *cmd == '-' || *cmd == '+') { 698144467Sharti switch (*cmd) { 699132839Sharti 700144467Sharti case '@': 701144467Sharti shutUp = DEBUG(LOUD) ? FALSE : TRUE; 702144467Sharti break; 703132839Sharti 704144467Sharti case '-': 705144467Sharti errOff = TRUE; 706144467Sharti break; 707132839Sharti 708144467Sharti case '+': 709144467Sharti if (noSpecials) { 710144467Sharti /* 711144467Sharti * We're not actually exececuting anything... 712144467Sharti * but this one needs to be - use compat mode 713144467Sharti * just for it. 714144467Sharti */ 715144741Sharti Compat_RunCommand(cmd, job->node); 716144467Sharti return (0); 717144467Sharti } 718144467Sharti break; 719144467Sharti } 720144467Sharti cmd++; 7211590Srgrimes } 7221590Srgrimes 723144467Sharti while (isspace((unsigned char)*cmd)) 724144467Sharti cmd++; 7251590Srgrimes 726144467Sharti if (shutUp) { 727144467Sharti if (!(job->flags & JOB_SILENT) && !noSpecials && 7281590Srgrimes commandShell->hasEchoCtl) { 72918730Ssteve DBPRINTF("%s\n", commandShell->echoOff); 7301590Srgrimes } else { 731144467Sharti shutUp = FALSE; 7321590Srgrimes } 733144467Sharti } 734144467Sharti 735144467Sharti if (errOff) { 736144467Sharti if (!(job->flags & JOB_IGNERR) && !noSpecials) { 737144467Sharti if (commandShell->hasErrCtl) { 738144467Sharti /* 739144467Sharti * We don't want the error-control commands 740144467Sharti * showing up either, so we turn off echoing 741144467Sharti * while executing them. We could put another 742144467Sharti * field in the shell structure to tell 743144467Sharti * JobDoOutput to look for this string too, 744144467Sharti * but why make it any more complex than 745144467Sharti * it already is? 746144467Sharti */ 747144467Sharti if (!(job->flags & JOB_SILENT) && !shutUp && 748144467Sharti commandShell->hasEchoCtl) { 749144467Sharti DBPRINTF("%s\n", commandShell->echoOff); 750144467Sharti DBPRINTF("%s\n", commandShell->ignErr); 751144467Sharti DBPRINTF("%s\n", commandShell->echoOn); 752144467Sharti } else { 753144467Sharti DBPRINTF("%s\n", commandShell->ignErr); 754144467Sharti } 755144467Sharti } else if (commandShell->ignErr && 756144657Sharti *commandShell->ignErr != '\0') { 757144467Sharti /* 758144467Sharti * The shell has no error control, so we need to 759144467Sharti * be weird to get it to ignore any errors from 760144467Sharti * the command. If echoing is turned on, we turn 761144467Sharti * it off and use the errCheck template to echo 762144467Sharti * the command. Leave echoing off so the user 763144467Sharti * doesn't see the weirdness we go through to 764144467Sharti * ignore errors. Set cmdTemplate to use the 765144467Sharti * weirdness instead of the simple "%s\n" 766144467Sharti * template. 767144467Sharti */ 768144467Sharti if (!(job->flags & JOB_SILENT) && !shutUp && 769144467Sharti commandShell->hasEchoCtl) { 770144467Sharti DBPRINTF("%s\n", commandShell->echoOff); 771144467Sharti DBPRINTF(commandShell->errCheck, cmd); 772144467Sharti shutUp = TRUE; 773144467Sharti } 774144467Sharti cmdTemplate = commandShell->ignErr; 775144467Sharti /* 776144467Sharti * The error ignoration (hee hee) is already 777144467Sharti * taken care of by the ignErr template, so 778144467Sharti * pretend error checking is still on. 779144467Sharti */ 780144467Sharti errOff = FALSE; 781144467Sharti } else { 782144467Sharti errOff = FALSE; 783144467Sharti } 784144467Sharti } else { 785144467Sharti errOff = FALSE; 786144467Sharti } 787144467Sharti } 788144467Sharti 789144467Sharti DBPRINTF(cmdTemplate, cmd); 790144467Sharti 791144467Sharti if (errOff) { 7921590Srgrimes /* 793144467Sharti * If echoing is already off, there's no point in issuing the 794144467Sharti * echoOff command. Otherwise we issue it and pretend it was on 795144467Sharti * for the whole command... 7961590Srgrimes */ 797144467Sharti if (!shutUp && !(job->flags & JOB_SILENT) && 7981590Srgrimes commandShell->hasEchoCtl) { 79918730Ssteve DBPRINTF("%s\n", commandShell->echoOff); 8001590Srgrimes shutUp = TRUE; 8011590Srgrimes } 802144467Sharti DBPRINTF("%s\n", commandShell->errCheck); 8031590Srgrimes } 804144467Sharti if (shutUp) { 805144467Sharti DBPRINTF("%s\n", commandShell->echoOn); 8061590Srgrimes } 807144467Sharti return (0); 8081590Srgrimes} 8091590Srgrimes 810144467Sharti/** 81118730Ssteve * JobClose -- 81218730Ssteve * Called to close both input and output pipes when a job is finished. 81318730Ssteve * 81418730Ssteve * Side Effects: 81518730Ssteve * The file descriptors associated with the job are closed. 81618730Ssteve */ 81718730Sstevestatic void 818104696SjmallettJobClose(Job *job) 81918730Ssteve{ 820138232Sharti 821144467Sharti if (usePipes) { 822137202Sharti#if !defined(USE_KQUEUE) 823144467Sharti FD_CLR(job->inPipe, &outputs); 82418730Ssteve#endif 825144467Sharti if (job->outPipe != job->inPipe) { 826144467Sharti close(job->outPipe); 827144467Sharti } 828144467Sharti JobDoOutput(job, TRUE); 829144467Sharti close(job->inPipe); 830144467Sharti } else { 831144467Sharti close(job->outFd); 832144467Sharti JobDoOutput(job, TRUE); 83318730Ssteve } 83418730Ssteve} 83518730Ssteve 836144467Sharti/** 8371590Srgrimes * JobFinish -- 8381590Srgrimes * Do final processing for the given job including updating 8391590Srgrimes * parents and starting new jobs as available/necessary. Note 8401590Srgrimes * that we pay no attention to the JOB_IGNERR flag here. 8411590Srgrimes * This is because when we're called because of a noexecute flag 8421590Srgrimes * or something, jstat.w_status is 0 and when called from 8431590Srgrimes * Job_CatchChildren, the status is zeroed if it s/b ignored. 8441590Srgrimes * 8451590Srgrimes * Side Effects: 8461590Srgrimes * Some nodes may be put on the toBeMade queue. 8471590Srgrimes * Final commands for the job are placed on postCommands. 8481590Srgrimes * 8491590Srgrimes * If we got an error and are aborting (aborting == ABORT_ERROR) and 8501590Srgrimes * the job list is now empty, we are done for the day. 8511590Srgrimes * If we recognized an error (errors !=0), we set the aborting flag 8521590Srgrimes * to ABORT_ERROR so no more jobs will be started. 8531590Srgrimes */ 8541590Srgrimesstatic void 855104696SjmallettJobFinish(Job *job, int *status) 8561590Srgrimes{ 857144467Sharti Boolean done; 858144467Sharti LstNode *ln; 8591590Srgrimes 860146133Sharti if (WIFEXITED(*status)) { 861146133Sharti int job_status = WEXITSTATUS(*status); 862146133Sharti 863144467Sharti JobClose(job); 864144467Sharti /* 865146133Sharti * Deal with ignored errors in -B mode. We need to 866146133Sharti * print a message telling of the ignored error as 867146133Sharti * well as setting status.w_status to 0 so the next 868146133Sharti * command gets run. To do this, we set done to be 869146133Sharti * TRUE if in -B mode and the job exited non-zero. 870144467Sharti */ 871146133Sharti if (job_status == 0) { 872146133Sharti done = FALSE; 873146133Sharti } else { 874146133Sharti if (job->flags & JOB_IGNERR) { 875146133Sharti done = TRUE; 876146133Sharti } else { 877146133Sharti /* 878146133Sharti * If it exited non-zero and either we're 879146133Sharti * doing things our way or we're not ignoring 880146133Sharti * errors, the job is finished. Similarly, if 881146133Sharti * the shell died because of a signal the job 882146133Sharti * is also finished. In these cases, finish 883146133Sharti * out the job's output before printing the 884146133Sharti * exit status... 885146133Sharti */ 886146133Sharti done = TRUE; 887146133Sharti if (job->cmdFILE != NULL && 888146133Sharti job->cmdFILE != stdout) { 889146133Sharti fclose(job->cmdFILE); 890146133Sharti } 8918874Srgrimes 892146133Sharti } 893146133Sharti } 894146133Sharti } else if (WIFSIGNALED(*status)) { 895146133Sharti if (WTERMSIG(*status) == SIGCONT) { 896146133Sharti /* 897146133Sharti * No need to close things down or anything. 898146133Sharti */ 899146133Sharti done = FALSE; 900146133Sharti } else { 901146133Sharti /* 902146133Sharti * If it exited non-zero and either we're 903146133Sharti * doing things our way or we're not ignoring 904146133Sharti * errors, the job is finished. Similarly, if 905146133Sharti * the shell died because of a signal the job 906146133Sharti * is also finished. In these cases, finish 907146133Sharti * out the job's output before printing the 908146133Sharti * exit status... 909146133Sharti */ 910146133Sharti JobClose(job); 911146133Sharti if (job->cmdFILE != NULL && 912146133Sharti job->cmdFILE != stdout) { 913146133Sharti fclose(job->cmdFILE); 914146133Sharti } 915146133Sharti done = TRUE; 916146133Sharti } 9171590Srgrimes } else { 918144467Sharti /* 919144467Sharti * No need to close things down or anything. 920144467Sharti */ 921144467Sharti done = FALSE; 9221590Srgrimes } 9231590Srgrimes 924146133Sharti if (WIFEXITED(*status)) { 925146133Sharti if (done || DEBUG(JOB)) { 926146133Sharti FILE *out; 927144467Sharti 928146133Sharti if (compatMake && 929146133Sharti !usePipes && 930146133Sharti (job->flags & JOB_IGNERR)) { 931146133Sharti /* 932146133Sharti * If output is going to a file and this job 933146133Sharti * is ignoring errors, arrange to have the 934146133Sharti * exit status sent to the output file as 935146133Sharti * well. 936146133Sharti */ 937146133Sharti out = fdopen(job->outFd, "w"); 938146133Sharti if (out == NULL) 939146133Sharti Punt("Cannot fdopen"); 940146133Sharti } else { 941146133Sharti out = stdout; 942146133Sharti } 9431590Srgrimes 944144665Sharti DEBUGF(JOB, ("Process %jd exited.\n", 945144665Sharti (intmax_t)job->pid)); 946146133Sharti 947146133Sharti if (WEXITSTATUS(*status) == 0) { 948146133Sharti if (DEBUG(JOB)) { 949146133Sharti if (usePipes && job->node != lastNode) { 950146133Sharti MESSAGE(out, job->node); 951146133Sharti lastNode = job->node; 952146133Sharti } 953146133Sharti fprintf(out, 954146133Sharti "*** Completed successfully\n"); 955146133Sharti } 956146133Sharti } else { 957144467Sharti if (usePipes && job->node != lastNode) { 958144467Sharti MESSAGE(out, job->node); 959144467Sharti lastNode = job->node; 960144467Sharti } 961144467Sharti fprintf(out, "*** Error code %d%s\n", 962146133Sharti WEXITSTATUS(*status), 963146133Sharti (job->flags & JOB_IGNERR) ? 964146133Sharti "(ignored)" : ""); 965144467Sharti 966144467Sharti if (job->flags & JOB_IGNERR) { 967144467Sharti *status = 0; 968144467Sharti } 969144467Sharti } 970144467Sharti 971144467Sharti fflush(out); 972146133Sharti } 973146133Sharti } else if (WIFSIGNALED(*status)) { 974146133Sharti if (done || DEBUG(JOB) || (WTERMSIG(*status) == SIGCONT)) { 975146133Sharti FILE *out; 976144467Sharti 977146133Sharti if (compatMake && 978146133Sharti !usePipes && 979146133Sharti (job->flags & JOB_IGNERR)) { 980146133Sharti /* 981146133Sharti * If output is going to a file and this job 982146133Sharti * is ignoring errors, arrange to have the 983146133Sharti * exit status sent to the output file as 984146133Sharti * well. 985146133Sharti */ 986146133Sharti out = fdopen(job->outFd, "w"); 987146133Sharti if (out == NULL) 988146133Sharti Punt("Cannot fdopen"); 989146133Sharti } else { 990146133Sharti out = stdout; 991146133Sharti } 992146133Sharti 993146133Sharti if (WTERMSIG(*status) == SIGCONT) { 994146133Sharti /* 995146133Sharti * If the beastie has continued, shift the 996146133Sharti * Job from the stopped list to the running 997146133Sharti * one (or re-stop it if concurrency is 998146133Sharti * exceeded) and go and get another child. 999146133Sharti */ 1000146133Sharti if (job->flags & (JOB_RESUME | JOB_RESTART)) { 1001146133Sharti if (usePipes && job->node != lastNode) { 1002146133Sharti MESSAGE(out, job->node); 1003146133Sharti lastNode = job->node; 1004146133Sharti } 1005146133Sharti fprintf(out, "*** Continued\n"); 1006146133Sharti } 1007146133Sharti if (!(job->flags & JOB_CONTINUING)) { 1008146133Sharti DEBUGF(JOB, ("Warning: process %jd was not " 1009146133Sharti "continuing.\n", (intmax_t) job->pid)); 1010146133Sharti#ifdef notdef 1011146133Sharti /* 1012146133Sharti * We don't really want to restart a 1013146133Sharti * job from scratch just because it 1014146133Sharti * continued, especially not without 1015146133Sharti * killing the continuing process! 1016146133Sharti * That's why this is ifdef'ed out. 1017146133Sharti * FD - 9/17/90 1018146133Sharti */ 1019146133Sharti JobRestart(job); 1020146133Sharti#endif 1021146133Sharti } 1022146133Sharti job->flags &= ~JOB_CONTINUING; 1023146133Sharti TAILQ_INSERT_TAIL(&jobs, job, link); 1024146133Sharti nJobs += 1; 1025146133Sharti DEBUGF(JOB, ("Process %jd is continuing locally.\n", 1026146133Sharti (intmax_t) job->pid)); 1027146133Sharti if (nJobs == maxJobs) { 1028146133Sharti jobFull = TRUE; 1029146133Sharti DEBUGF(JOB, ("Job queue is full.\n")); 1030146133Sharti } 1031146133Sharti fflush(out); 1032146133Sharti return; 1033146133Sharti 1034146133Sharti } else { 1035144467Sharti if (usePipes && job->node != lastNode) { 1036144467Sharti MESSAGE(out, job->node); 1037144467Sharti lastNode = job->node; 1038144467Sharti } 1039146133Sharti fprintf(out, 1040146133Sharti "*** Signal %d\n", WTERMSIG(*status)); 1041146133Sharti fflush(out); 1042144467Sharti } 1043146133Sharti } 1044146133Sharti } else { 1045146133Sharti /* STOPPED */ 1046146133Sharti FILE *out; 10471590Srgrimes 1048146133Sharti if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) { 1049146133Sharti /* 1050146133Sharti * If output is going to a file and this job 1051146133Sharti * is ignoring errors, arrange to have the 1052146133Sharti * exit status sent to the output file as 1053146133Sharti * well. 1054146133Sharti */ 1055146133Sharti out = fdopen(job->outFd, "w"); 1056146133Sharti if (out == NULL) 1057146133Sharti Punt("Cannot fdopen"); 1058144467Sharti } else { 1059146133Sharti out = stdout; 1060144467Sharti } 10611590Srgrimes 1062146133Sharti DEBUGF(JOB, ("Process %jd stopped.\n", (intmax_t) job->pid)); 1063146133Sharti if (usePipes && job->node != lastNode) { 1064146133Sharti MESSAGE(out, job->node); 1065146133Sharti lastNode = job->node; 1066146133Sharti } 1067146133Sharti fprintf(out, "*** Stopped -- signal %d\n", WSTOPSIG(*status)); 1068146133Sharti job->flags |= JOB_RESUME; 1069146133Sharti TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 1070144467Sharti fflush(out); 1071146133Sharti return; 10721590Srgrimes } 10731590Srgrimes 10741590Srgrimes /* 1075144467Sharti * Now handle the -B-mode stuff. If the beast still isn't finished, 1076144467Sharti * try and restart the job on the next command. If JobStart says it's 1077144467Sharti * ok, it's ok. If there's an error, this puppy is done. 10781590Srgrimes */ 1079144467Sharti if (compatMake && WIFEXITED(*status) && 1080144467Sharti Lst_Succ(job->node->compat_command) != NULL) { 1081144467Sharti switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) { 1082144467Sharti case JOB_RUNNING: 1083144467Sharti done = FALSE; 1084144467Sharti break; 1085144467Sharti case JOB_ERROR: 1086144467Sharti done = TRUE; 1087144467Sharti W_SETEXITSTATUS(status, 1); 1088144467Sharti break; 1089144467Sharti case JOB_FINISHED: 1090144467Sharti /* 1091144467Sharti * If we got back a JOB_FINISHED code, JobStart has 1092144467Sharti * already called Make_Update and freed the job 1093144467Sharti * descriptor. We set done to false here to avoid fake 1094144467Sharti * cycles and double frees. JobStart needs to do the 1095144467Sharti * update so we can proceed up the graph when given 1096144467Sharti * the -n flag.. 1097144467Sharti */ 1098144467Sharti done = FALSE; 1099144467Sharti break; 1100144467Sharti default: 1101144467Sharti break; 1102144467Sharti } 1103144467Sharti } else { 1104144467Sharti done = TRUE; 11051590Srgrimes } 1106143703Sharti 1107144657Sharti if (done && aborting != ABORT_ERROR && 1108144657Sharti aborting != ABORT_INTERRUPT && *status == 0) { 1109144467Sharti /* 1110144467Sharti * As long as we aren't aborting and the job didn't return a 1111144467Sharti * non-zero status that we shouldn't ignore, we call 1112144467Sharti * Make_Update to update the parents. In addition, any saved 1113144467Sharti * commands for the node are placed on the .END target. 1114144467Sharti */ 1115144467Sharti for (ln = job->tailCmds; ln != NULL; ln = LST_NEXT(ln)) { 1116144467Sharti Lst_AtEnd(&postCommands->commands, 1117146027Sharti Buf_Peel( 1118146027Sharti Var_Subst(Lst_Datum(ln), job->node, FALSE))); 1119144467Sharti } 11201590Srgrimes 1121144467Sharti job->node->made = MADE; 1122144467Sharti Make_Update(job->node); 1123144467Sharti free(job); 11241590Srgrimes 1125144467Sharti } else if (*status != 0) { 1126144467Sharti errors += 1; 1127144467Sharti free(job); 1128144467Sharti } 1129144467Sharti 1130144467Sharti JobRestartJobs(); 1131144467Sharti 11321590Srgrimes /* 1133144467Sharti * Set aborting if any error. 11341590Srgrimes */ 1135144657Sharti if (errors && !keepgoing && aborting != ABORT_INTERRUPT) { 1136144467Sharti /* 1137144467Sharti * If we found any errors in this batch of children and the -k 1138144467Sharti * flag wasn't given, we set the aborting flag so no more jobs 1139144467Sharti * get started. 1140144467Sharti */ 1141144467Sharti aborting = ABORT_ERROR; 1142144467Sharti } 11438874Srgrimes 1144144657Sharti if (aborting == ABORT_ERROR && Job_Empty()) { 1145144467Sharti /* 1146144467Sharti * If we are aborting and the job table is now empty, we finish. 1147144467Sharti */ 1148144467Sharti Finish(errors); 1149144467Sharti } 11501590Srgrimes} 11511590Srgrimes 1152144467Sharti/** 1153144467Sharti * Job_Touch 11541590Srgrimes * Touch the given target. Called by JobStart when the -t flag was 1155104696Sjmallett * given. Prints messages unless told to be silent. 11561590Srgrimes * 11571590Srgrimes * Side Effects: 11581590Srgrimes * The data modification of the file is changed. In addition, if the 11591590Srgrimes * file did not exist, it is created. 11601590Srgrimes */ 11611590Srgrimesvoid 1162104696SjmallettJob_Touch(GNode *gn, Boolean silent) 11631590Srgrimes{ 1164144467Sharti int streamID; /* ID of stream opened to do the touch */ 1165144467Sharti struct utimbuf times; /* Times for utime() call */ 11661590Srgrimes 1167144467Sharti if (gn->type & (OP_JOIN | OP_USE | OP_EXEC | OP_OPTIONAL)) { 1168144467Sharti /* 1169144467Sharti * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" 1170144467Sharti * targets and, as such, shouldn't really be created. 1171144467Sharti */ 1172144467Sharti return; 1173144467Sharti } 11748874Srgrimes 1175144467Sharti if (!silent) { 1176144467Sharti fprintf(stdout, "touch %s\n", gn->name); 1177144467Sharti fflush(stdout); 1178144467Sharti } 11791590Srgrimes 1180144467Sharti if (noExecute) { 1181144467Sharti return; 1182144467Sharti } 11831590Srgrimes 1184144467Sharti if (gn->type & OP_ARCHV) { 1185144467Sharti Arch_Touch(gn); 1186144467Sharti } else if (gn->type & OP_LIB) { 1187144467Sharti Arch_TouchLib(gn); 1188144467Sharti } else { 1189144467Sharti char *file = gn->path ? gn->path : gn->name; 11901590Srgrimes 1191144467Sharti times.actime = times.modtime = now; 1192144467Sharti if (utime(file, ×) < 0) { 1193144467Sharti streamID = open(file, O_RDWR | O_CREAT, 0666); 11941590Srgrimes 1195144467Sharti if (streamID >= 0) { 1196144467Sharti char c; 11971590Srgrimes 1198144467Sharti /* 1199144467Sharti * Read and write a byte to the file to change 1200144467Sharti * the modification time, then close the file. 1201144467Sharti */ 1202144467Sharti if (read(streamID, &c, 1) == 1) { 1203144467Sharti lseek(streamID, (off_t)0, SEEK_SET); 1204144467Sharti write(streamID, &c, 1); 1205144467Sharti } 1206144467Sharti 1207144467Sharti close(streamID); 1208144467Sharti } else { 1209144467Sharti fprintf(stdout, "*** couldn't touch %s: %s", 1210144467Sharti file, strerror(errno)); 1211144467Sharti fflush(stdout); 1212144467Sharti } 12131590Srgrimes } 12141590Srgrimes } 12151590Srgrimes} 12161590Srgrimes 1217144467Sharti/** 1218144467Sharti * Job_CheckCommands 12198874Srgrimes * Make sure the given node has all the commands it needs. 12201590Srgrimes * 12211590Srgrimes * Results: 12221590Srgrimes * TRUE if the commands list is/was ok. 12231590Srgrimes * 12241590Srgrimes * Side Effects: 12251590Srgrimes * The node will have commands from the .DEFAULT rule added to it 12261590Srgrimes * if it needs them. 12271590Srgrimes */ 12281590SrgrimesBoolean 1229104696SjmallettJob_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...)) 12301590Srgrimes{ 1231138232Sharti 1232144467Sharti if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) && 1233144467Sharti (gn->type & OP_LIB) == 0) { 1234144467Sharti /* 1235144467Sharti * No commands. Look for .DEFAULT rule from which we might infer 1236144467Sharti * commands. 1237144467Sharti */ 1238144657Sharti if (DEFAULT != NULL && !Lst_IsEmpty(&DEFAULT->commands)) { 1239144467Sharti char *p1; 1240144467Sharti /* 1241144467Sharti * Make only looks for a .DEFAULT if the node was 1242144467Sharti * never the target of an operator, so that's what we 1243144467Sharti * do too. If a .DEFAULT was given, we substitute its 1244144467Sharti * commands for gn's commands and set the IMPSRC 1245144467Sharti * variable to be the target's name The DEFAULT node 1246144467Sharti * acts like a transformation rule, in that gn also 1247144467Sharti * inherits any attributes or sources attached to 1248144467Sharti * .DEFAULT itself. 1249144467Sharti */ 1250144467Sharti Make_HandleUse(DEFAULT, gn); 1251144467Sharti Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn); 1252144467Sharti free(p1); 125318730Ssteve 1254144467Sharti } else if (Dir_MTime(gn) == 0) { 1255144467Sharti /* 1256144467Sharti * The node wasn't the target of an operator we have 1257144467Sharti * no .DEFAULT rule to go on and the target doesn't 1258144467Sharti * already exist. There's nothing more we can do for 1259144467Sharti * this branch. If the -k flag wasn't given, we stop 1260144467Sharti * in our tracks, otherwise we just don't update 1261144467Sharti * this node's parents so they never get examined. 1262144467Sharti */ 1263144467Sharti static const char msg[] = 1264144467Sharti "make: don't know how to make"; 1265144467Sharti 1266144467Sharti if (gn->type & OP_OPTIONAL) { 1267144467Sharti fprintf(stdout, "%s %s(ignored)\n", 1268144467Sharti msg, gn->name); 1269144467Sharti fflush(stdout); 1270144467Sharti } else if (keepgoing) { 1271144467Sharti fprintf(stdout, "%s %s(continuing)\n", 1272144467Sharti msg, gn->name); 1273144467Sharti fflush(stdout); 1274144467Sharti return (FALSE); 1275144467Sharti } else { 127635483Simp#if OLD_JOKE 1277144467Sharti if (strcmp(gn->name,"love") == 0) 1278144467Sharti (*abortProc)("Not war."); 1279144467Sharti else 128035483Simp#endif 1281144467Sharti (*abortProc)("%s %s. Stop", 1282144467Sharti msg, gn->name); 1283144467Sharti return (FALSE); 1284144467Sharti } 1285144467Sharti } 12861590Srgrimes } 1287144467Sharti return (TRUE); 12881590Srgrimes} 12891590Srgrimes 1290144467Sharti/** 1291144467Sharti * JobExec 12921590Srgrimes * Execute the shell for the given job. Called from JobStart and 12931590Srgrimes * JobRestart. 12941590Srgrimes * 12951590Srgrimes * Side Effects: 12961590Srgrimes * A shell is executed, outputs is altered and the Job structure added 12971590Srgrimes * to the job table. 12981590Srgrimes */ 12991590Srgrimesstatic void 1300104696SjmallettJobExec(Job *job, char **argv) 13011590Srgrimes{ 1302146129Sharti ProcStuff ps; 13038874Srgrimes 1304144467Sharti if (DEBUG(JOB)) { 1305146061Sharti int i; 13068874Srgrimes 1307144467Sharti DEBUGF(JOB, ("Running %s\n", job->node->name)); 1308144467Sharti DEBUGF(JOB, ("\tCommand: ")); 1309144467Sharti for (i = 0; argv[i] != NULL; i++) { 1310144467Sharti DEBUGF(JOB, ("%s ", argv[i])); 1311144467Sharti } 1312144467Sharti DEBUGF(JOB, ("\n")); 13131590Srgrimes } 13148874Srgrimes 13151590Srgrimes /* 1316144467Sharti * Some jobs produce no output and it's disconcerting to have 1317144467Sharti * no feedback of their running (since they produce no output, the 1318144467Sharti * banner with their name in it never appears). This is an attempt to 1319144467Sharti * provide that feedback, even if nothing follows it. 13201590Srgrimes */ 1321144657Sharti if (lastNode != job->node && (job->flags & JOB_FIRST) && 1322144467Sharti !(job->flags & JOB_SILENT)) { 1323144467Sharti MESSAGE(stdout, job->node); 1324144467Sharti lastNode = job->node; 13251590Srgrimes } 13261590Srgrimes 1327146129Sharti ps.in = FILENO(job->cmdFILE); 1328146129Sharti if (usePipes) { 1329146129Sharti /* 1330146129Sharti * Set up the child's output to be routed through the 1331146129Sharti * pipe we've created for it. 1332146129Sharti */ 1333146129Sharti ps.out = job->outPipe; 1334146129Sharti } else { 1335146129Sharti /* 1336146129Sharti * We're capturing output in a file, so we duplicate 1337146129Sharti * the descriptor to the temporary file into the 1338146129Sharti * standard output. 1339146129Sharti */ 1340146129Sharti ps.out = job->outFd; 1341146129Sharti } 1342146129Sharti ps.err = STDERR_FILENO; 1343146129Sharti 1344146129Sharti ps.merge_errors = 1; 1345146129Sharti ps.pgroup = 1; 1346146129Sharti ps.searchpath = 0; 1347146129Sharti 1348146129Sharti ps.argv = argv; 1349146156Sharti ps.argv_free = 0; 1350146129Sharti 1351146129Sharti /* 1352146129Sharti * Fork. Warning since we are doing vfork() instead of fork(), 1353146129Sharti * do not allocate memory in the child process! 1354146129Sharti */ 1355146130Sharti if ((ps.child_pid = vfork()) == -1) { 1356144467Sharti Punt("Cannot fork"); 1357144467Sharti 1358146130Sharti 1359146130Sharti } else if (ps.child_pid == 0) { 1360144665Sharti /* 1361144665Sharti * Child 1362144665Sharti */ 1363144467Sharti if (fifoFd >= 0) 1364144467Sharti close(fifoFd); 1365144467Sharti 1366146574Sharti Proc_Exec(&ps); 1367146129Sharti /* NOTREACHED */ 1368144665Sharti } 1369146130Sharti 1370144665Sharti /* 1371144665Sharti * Parent 1372144665Sharti */ 1373146130Sharti job->pid = ps.child_pid; 1374144467Sharti 1375144665Sharti if (usePipes && (job->flags & JOB_FIRST)) { 1376144665Sharti /* 1377144665Sharti * The first time a job is run for a node, we set the 1378144665Sharti * current position in the buffer to the beginning and 1379144665Sharti * mark another stream to watch in the outputs mask. 1380144665Sharti */ 1381104475Sphk#ifdef USE_KQUEUE 1382144665Sharti struct kevent kev[2]; 1383104475Sphk#endif 1384144665Sharti job->curPos = 0; 13858874Srgrimes 1386137202Sharti#if defined(USE_KQUEUE) 1387144665Sharti EV_SET(&kev[0], job->inPipe, EVFILT_READ, EV_ADD, 0, 0, job); 1388144665Sharti EV_SET(&kev[1], job->pid, EVFILT_PROC, 1389144665Sharti EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, NULL); 1390144665Sharti if (kevent(kqfd, kev, 2, NULL, 0, NULL) != 0) { 1391144665Sharti /* 1392144665Sharti * kevent() will fail if the job is already 1393144665Sharti * finished 1394144665Sharti */ 1395144665Sharti if (errno != EINTR && errno != EBADF && errno != ESRCH) 1396144665Sharti Punt("kevent: %s", strerror(errno)); 1397144665Sharti } 13981590Srgrimes#else 1399144665Sharti FD_SET(job->inPipe, &outputs); 1400137202Sharti#endif /* USE_KQUEUE */ 1401144665Sharti } 1402144467Sharti 1403144665Sharti if (job->cmdFILE != NULL && job->cmdFILE != stdout) { 1404144665Sharti fclose(job->cmdFILE); 1405144665Sharti job->cmdFILE = NULL; 14061590Srgrimes } 14071590Srgrimes 1408144467Sharti /* 1409144467Sharti * Now the job is actually running, add it to the table. 1410144467Sharti */ 1411144467Sharti nJobs += 1; 1412144494Sharti TAILQ_INSERT_TAIL(&jobs, job, link); 1413144467Sharti if (nJobs == maxJobs) { 1414144467Sharti jobFull = TRUE; 14151590Srgrimes } 14161590Srgrimes} 14171590Srgrimes 1418144467Sharti/** 1419144467Sharti * JobMakeArgv 14201590Srgrimes * Create the argv needed to execute the shell for a given job. 14211590Srgrimes */ 14221590Srgrimesstatic void 1423104696SjmallettJobMakeArgv(Job *job, char **argv) 14241590Srgrimes{ 1425144467Sharti int argc; 1426144467Sharti static char args[10]; /* For merged arguments */ 14278874Srgrimes 1428146557Sharti argv[0] = commandShell->name; 1429144467Sharti argc = 1; 14301590Srgrimes 1431144657Sharti if ((commandShell->exit && *commandShell->exit != '-') || 1432144657Sharti (commandShell->echo && *commandShell->echo != '-')) { 1433144467Sharti /* 1434144467Sharti * At least one of the flags doesn't have a minus before it, so 1435144467Sharti * merge them together. Have to do this because the *(&(@*#*&#$# 1436144467Sharti * Bourne shell thinks its second argument is a file to source. 1437144467Sharti * Grrrr. Note the ten-character limitation on the combined 1438144467Sharti * arguments. 1439144467Sharti */ 1440144657Sharti sprintf(args, "-%s%s", (job->flags & JOB_IGNERR) ? "" : 1441144657Sharti commandShell->exit ? commandShell->exit : "", 1442144657Sharti (job->flags & JOB_SILENT) ? "" : 1443144657Sharti commandShell->echo ? commandShell->echo : ""); 14441590Srgrimes 1445144467Sharti if (args[1]) { 1446144467Sharti argv[argc] = args; 1447144467Sharti argc++; 1448144467Sharti } 1449144467Sharti } else { 1450144467Sharti if (!(job->flags & JOB_IGNERR) && commandShell->exit) { 1451144467Sharti argv[argc] = commandShell->exit; 1452144467Sharti argc++; 1453144467Sharti } 1454144467Sharti if (!(job->flags & JOB_SILENT) && commandShell->echo) { 1455144467Sharti argv[argc] = commandShell->echo; 1456144467Sharti argc++; 1457144467Sharti } 14581590Srgrimes } 1459144467Sharti argv[argc] = NULL; 14601590Srgrimes} 14611590Srgrimes 1462144467Sharti/** 1463144467Sharti * JobRestart 1464144494Sharti * Restart a job that stopped for some reason. The job must be neither 1465144494Sharti * on the jobs nor on the stoppedJobs list. 14661590Srgrimes * 14671590Srgrimes * Side Effects: 14681590Srgrimes * jobFull will be set if the job couldn't be run. 14691590Srgrimes */ 14701590Srgrimesstatic void 1471104696SjmallettJobRestart(Job *job) 14721590Srgrimes{ 147318730Ssteve 1474144467Sharti if (job->flags & JOB_RESTART) { 1475144467Sharti /* 1476144467Sharti * Set up the control arguments to the shell. This is based on 1477144467Sharti * the flags set earlier for this job. If the JOB_IGNERR flag 1478144467Sharti * is clear, the 'exit' flag of the commandShell is used to 1479144467Sharti * cause it to exit upon receiving an error. If the JOB_SILENT 1480144467Sharti * flag is clear, the 'echo' flag of the commandShell is used 1481144467Sharti * to get it to start echoing as soon as it starts 1482144467Sharti * processing commands. 1483144467Sharti */ 1484144467Sharti char *argv[4]; 14858874Srgrimes 1486144467Sharti JobMakeArgv(job, argv); 14878874Srgrimes 1488144467Sharti DEBUGF(JOB, ("Restarting %s...", job->node->name)); 1489144657Sharti if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) { 1490144467Sharti /* 1491144657Sharti * Not allowed to run -- put it back on the hold 1492144657Sharti * queue and mark the table full 1493144467Sharti */ 1494144467Sharti DEBUGF(JOB, ("holding\n")); 1495144494Sharti TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1496144467Sharti jobFull = TRUE; 1497144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 1498144467Sharti return; 1499144467Sharti } else { 1500144467Sharti /* 1501144467Sharti * Job may be run locally. 1502144467Sharti */ 1503144467Sharti DEBUGF(JOB, ("running locally\n")); 1504144467Sharti } 1505144467Sharti JobExec(job, argv); 1506144467Sharti 1507137202Sharti } else { 15081590Srgrimes /* 1509144467Sharti * The job has stopped and needs to be restarted. 1510144467Sharti * Why it stopped, we don't know... 15111590Srgrimes */ 1512144467Sharti DEBUGF(JOB, ("Resuming %s...", job->node->name)); 1513144657Sharti if ((nJobs < maxJobs || ((job->flags & JOB_SPECIAL) && 1514144657Sharti maxJobs == 0)) && nJobs != maxJobs) { 1515144467Sharti /* 1516144467Sharti * If we haven't reached the concurrency limit already 1517144467Sharti * (or the job must be run and maxJobs is 0), it's ok 1518144467Sharti * to resume it. 1519144467Sharti */ 1520144467Sharti Boolean error; 1521144467Sharti int status; 15228874Srgrimes 1523144467Sharti error = (KILL(job->pid, SIGCONT) != 0); 1524144467Sharti 1525144467Sharti if (!error) { 1526144467Sharti /* 1527144467Sharti * Make sure the user knows we've continued 1528144467Sharti * the beast and actually put the thing in the 1529144467Sharti * job table. 1530144467Sharti */ 1531144467Sharti job->flags |= JOB_CONTINUING; 1532144467Sharti status = 0; 1533144467Sharti W_SETTERMSIG(&status, SIGCONT); 1534144467Sharti JobFinish(job, &status); 1535144467Sharti 1536144467Sharti job->flags &= ~(JOB_RESUME|JOB_CONTINUING); 1537144467Sharti DEBUGF(JOB, ("done\n")); 1538144467Sharti } else { 1539144467Sharti Error("couldn't resume %s: %s", 1540144467Sharti job->node->name, strerror(errno)); 1541144467Sharti status = 0; 1542144467Sharti W_SETEXITSTATUS(&status, 1); 1543144467Sharti JobFinish(job, &status); 1544144467Sharti } 1545144467Sharti } else { 1546144467Sharti /* 1547144467Sharti * Job cannot be restarted. Mark the table as full and 1548144467Sharti * place the job back on the list of stopped jobs. 1549144467Sharti */ 1550144467Sharti DEBUGF(JOB, ("table full\n")); 1551144494Sharti TAILQ_INSERT_HEAD(&stoppedJobs, job, link); 1552144467Sharti jobFull = TRUE; 1553144467Sharti DEBUGF(JOB, ("Job queue is full.\n")); 1554144467Sharti } 15551590Srgrimes } 15561590Srgrimes} 15571590Srgrimes 1558144467Sharti/** 1559144467Sharti * JobStart 15601590Srgrimes * Start a target-creation process going for the target described 15618874Srgrimes * by the graph node gn. 15621590Srgrimes * 15631590Srgrimes * Results: 15641590Srgrimes * JOB_ERROR if there was an error in the commands, JOB_FINISHED 15651590Srgrimes * if there isn't actually anything left to do for the job and 15661590Srgrimes * JOB_RUNNING if the job has been started. 15671590Srgrimes * 15681590Srgrimes * Side Effects: 15691590Srgrimes * A new Job node is created and added to the list of running 15701590Srgrimes * jobs. PMake is forked and a child shell created. 15711590Srgrimes */ 15721590Srgrimesstatic int 1573104696SjmallettJobStart(GNode *gn, int flags, Job *previous) 15741590Srgrimes{ 1575144467Sharti Job *job; /* new job descriptor */ 1576144467Sharti char *argv[4]; /* Argument vector to shell */ 1577144467Sharti Boolean cmdsOK; /* true if the nodes commands were all right */ 1578144467Sharti Boolean noExec; /* Set true if we decide not to run the job */ 1579144467Sharti int tfd; /* File descriptor for temp file */ 1580144467Sharti LstNode *ln; 1581144654Sharti char tfile[sizeof(TMPPAT)]; 15821590Srgrimes 1583144467Sharti if (interrupted) { 1584144467Sharti JobPassSig(interrupted); 1585144467Sharti return (JOB_ERROR); 1586144467Sharti } 1587144467Sharti if (previous != NULL) { 1588144467Sharti previous->flags &= ~(JOB_FIRST | JOB_IGNERR | JOB_SILENT); 1589144467Sharti job = previous; 1590144467Sharti } else { 1591144467Sharti job = emalloc(sizeof(Job)); 1592144467Sharti flags |= JOB_FIRST; 1593144467Sharti } 15941590Srgrimes 1595144467Sharti job->node = gn; 1596144467Sharti job->tailCmds = NULL; 15971590Srgrimes 15981590Srgrimes /* 1599144467Sharti * Set the initial value of the flags for this job based on the global 1600144467Sharti * ones and the node's attributes... Any flags supplied by the caller 1601144467Sharti * are also added to the field. 16021590Srgrimes */ 1603144467Sharti job->flags = 0; 1604144467Sharti if (Targ_Ignore(gn)) { 1605144467Sharti job->flags |= JOB_IGNERR; 16061590Srgrimes } 1607144467Sharti if (Targ_Silent(gn)) { 1608144467Sharti job->flags |= JOB_SILENT; 1609144467Sharti } 1610144467Sharti job->flags |= flags; 16118874Srgrimes 16121590Srgrimes /* 1613144467Sharti * Check the commands now so any attributes from .DEFAULT have a chance 1614144658Sharti * to migrate to the node. 16151590Srgrimes */ 1616144658Sharti if (!compatMake && (job->flags & JOB_FIRST)) { 1617144467Sharti cmdsOK = Job_CheckCommands(gn, Error); 1618144467Sharti } else { 1619144467Sharti cmdsOK = TRUE; 1620144467Sharti } 16211590Srgrimes 16221590Srgrimes /* 1623144467Sharti * If the -n flag wasn't given, we open up OUR (not the child's) 1624144467Sharti * temporary file to stuff commands in it. The thing is rd/wr so we 1625144467Sharti * don't need to reopen it to feed it to the shell. If the -n flag 1626144467Sharti * *was* given, we just set the file to be stdout. Cute, huh? 16271590Srgrimes */ 1628144467Sharti if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) { 1629144467Sharti /* 1630144467Sharti * We're serious here, but if the commands were bogus, we're 1631144467Sharti * also dead... 1632144467Sharti */ 1633144467Sharti if (!cmdsOK) { 1634144467Sharti DieHorribly(); 1635144467Sharti } 16368874Srgrimes 1637144467Sharti strcpy(tfile, TMPPAT); 1638144467Sharti if ((tfd = mkstemp(tfile)) == -1) 1639144467Sharti Punt("Cannot create temp file: %s", strerror(errno)); 1640144467Sharti job->cmdFILE = fdopen(tfd, "w+"); 1641144467Sharti eunlink(tfile); 1642144467Sharti if (job->cmdFILE == NULL) { 1643144467Sharti close(tfd); 1644144467Sharti Punt("Could not open %s", tfile); 1645144467Sharti } 1646144467Sharti fcntl(FILENO(job->cmdFILE), F_SETFD, 1); 1647144467Sharti /* 1648144467Sharti * Send the commands to the command file, flush all its 1649144467Sharti * buffers then rewind and remove the thing. 1650144467Sharti */ 1651144467Sharti noExec = FALSE; 1652138564Sharti 1653138564Sharti /* 1654144467Sharti * Used to be backwards; replace when start doing multiple 1655144467Sharti * commands per shell. 1656138564Sharti */ 1657144467Sharti if (compatMake) { 1658144467Sharti /* 1659144467Sharti * Be compatible: If this is the first time for this 1660144467Sharti * node, verify its commands are ok and open the 1661144467Sharti * commands list for sequential access by later 1662144467Sharti * invocations of JobStart. Once that is done, we take 1663144467Sharti * the next command off the list and print it to the 1664144467Sharti * command file. If the command was an ellipsis, note 1665144467Sharti * that there's nothing more to execute. 1666144467Sharti */ 1667144467Sharti if (job->flags & JOB_FIRST) 1668144467Sharti gn->compat_command = Lst_First(&gn->commands); 1669144467Sharti else 1670144467Sharti gn->compat_command = 1671144467Sharti Lst_Succ(gn->compat_command); 16728874Srgrimes 1673144467Sharti if (gn->compat_command == NULL || 1674144467Sharti JobPrintCommand(Lst_Datum(gn->compat_command), job)) 1675144467Sharti noExec = TRUE; 1676144467Sharti 1677144467Sharti if (noExec && !(job->flags & JOB_FIRST)) { 1678144467Sharti /* 1679144467Sharti * If we're not going to execute anything, the 1680144467Sharti * job is done and we need to close down the 1681144467Sharti * various file descriptors we've opened for 1682144467Sharti * output, then call JobDoOutput to catch the 1683144467Sharti * final characters or send the file to the 1684144467Sharti * screen... Note that the i/o streams are only 1685144467Sharti * open if this isn't the first job. Note also 1686144467Sharti * that this could not be done in 1687144467Sharti * Job_CatchChildren b/c it wasn't clear if 1688144467Sharti * there were more commands to execute or not... 1689144467Sharti */ 1690144467Sharti JobClose(job); 1691144467Sharti } 1692144467Sharti } else { 1693144467Sharti /* 1694144467Sharti * We can do all the commands at once. hooray for sanity 1695144467Sharti */ 1696144467Sharti numCommands = 0; 1697144467Sharti LST_FOREACH(ln, &gn->commands) { 1698144467Sharti if (JobPrintCommand(Lst_Datum(ln), job)) 1699144467Sharti break; 1700144467Sharti } 1701144467Sharti 1702144467Sharti /* 1703144467Sharti * If we didn't print out any commands to the shell 1704144467Sharti * script, there's not much point in executing the 1705144467Sharti * shell, is there? 1706144467Sharti */ 1707144467Sharti if (numCommands == 0) { 1708144467Sharti noExec = TRUE; 1709144467Sharti } 1710144467Sharti } 1711144467Sharti 1712144467Sharti } else if (noExecute) { 1713144467Sharti /* 1714144467Sharti * Not executing anything -- just print all the commands to 1715144467Sharti * stdout in one fell swoop. This will still set up 1716144467Sharti * job->tailCmds correctly. 1717144467Sharti */ 1718144467Sharti if (lastNode != gn) { 1719144467Sharti MESSAGE(stdout, gn); 1720144467Sharti lastNode = gn; 1721144467Sharti } 1722144467Sharti job->cmdFILE = stdout; 1723144467Sharti 1724144467Sharti /* 1725144467Sharti * Only print the commands if they're ok, but don't die if 1726144467Sharti * they're not -- just let the user know they're bad and keep 1727144467Sharti * going. It doesn't do any harm in this case and may do 1728144467Sharti * some good. 1729144467Sharti */ 1730144467Sharti if (cmdsOK) { 1731144467Sharti LST_FOREACH(ln, &gn->commands) { 1732144467Sharti if (JobPrintCommand(Lst_Datum(ln), job)) 1733144467Sharti break; 1734144467Sharti } 1735144467Sharti } 1736144467Sharti /* 1737144467Sharti * Don't execute the shell, thank you. 1738144467Sharti */ 17391590Srgrimes noExec = TRUE; 1740144467Sharti 1741144467Sharti } else { 1742144467Sharti /* 1743144467Sharti * Just touch the target and note that no shell should be 1744144467Sharti * executed. Set cmdFILE to stdout to make life easier. Check 1745144467Sharti * the commands, too, but don't die if they're no good -- it 1746144467Sharti * does no harm to keep working up the graph. 1747144467Sharti */ 1748144467Sharti job->cmdFILE = stdout; 1749144467Sharti Job_Touch(gn, job->flags & JOB_SILENT); 1750144467Sharti noExec = TRUE; 17511590Srgrimes } 1752144467Sharti 17531590Srgrimes /* 1754144467Sharti * If we're not supposed to execute a shell, don't. 17551590Srgrimes */ 1756144467Sharti if (noExec) { 1757144467Sharti /* 1758144467Sharti * Unlink and close the command file if we opened one 1759144467Sharti */ 1760144467Sharti if (job->cmdFILE != stdout) { 1761144467Sharti if (job->cmdFILE != NULL) 1762144467Sharti fclose(job->cmdFILE); 1763144467Sharti } else { 1764144467Sharti fflush(stdout); 1765144467Sharti } 1766144467Sharti 1767144467Sharti /* 1768144467Sharti * We only want to work our way up the graph if we aren't here 1769144467Sharti * because the commands for the job were no good. 1770144467Sharti */ 1771144467Sharti if (cmdsOK) { 1772144467Sharti if (aborting == 0) { 1773144467Sharti for (ln = job->tailCmds; ln != NULL; 1774144467Sharti ln = LST_NEXT(ln)) { 1775144467Sharti Lst_AtEnd(&postCommands->commands, 1776146027Sharti Buf_Peel(Var_Subst(Lst_Datum(ln), 1777146027Sharti job->node, FALSE))); 1778144467Sharti } 1779144467Sharti job->node->made = MADE; 1780144467Sharti Make_Update(job->node); 1781144467Sharti } 1782144467Sharti free(job); 1783144467Sharti return(JOB_FINISHED); 1784144467Sharti } else { 1785144467Sharti free(job); 1786144467Sharti return(JOB_ERROR); 1787144467Sharti } 1788144467Sharti } else { 1789144467Sharti fflush(job->cmdFILE); 17901590Srgrimes } 1791144467Sharti 17921590Srgrimes /* 1793144467Sharti * Set up the control arguments to the shell. This is based on the flags 1794144467Sharti * set earlier for this job. 17951590Srgrimes */ 1796144467Sharti JobMakeArgv(job, argv); 17971590Srgrimes 17981590Srgrimes /* 1799144467Sharti * If we're using pipes to catch output, create the pipe by which we'll 1800144467Sharti * get the shell's output. If we're using files, print out that we're 1801144467Sharti * starting a job and then set up its temporary-file name. 18021590Srgrimes */ 1803144467Sharti if (!compatMake || (job->flags & JOB_FIRST)) { 1804144467Sharti if (usePipes) { 1805144467Sharti int fd[2]; 18061590Srgrimes 1807144467Sharti if (pipe(fd) == -1) 1808144467Sharti Punt("Cannot create pipe: %s", strerror(errno)); 1809144467Sharti job->inPipe = fd[0]; 1810144467Sharti job->outPipe = fd[1]; 1811144467Sharti fcntl(job->inPipe, F_SETFD, 1); 1812144467Sharti fcntl(job->outPipe, F_SETFD, 1); 1813144467Sharti } else { 1814144467Sharti fprintf(stdout, "Remaking `%s'\n", gn->name); 1815144467Sharti fflush(stdout); 1816144467Sharti strcpy(job->outFile, TMPPAT); 1817144467Sharti if ((job->outFd = mkstemp(job->outFile)) == -1) 1818144467Sharti Punt("cannot create temp file: %s", 1819144467Sharti strerror(errno)); 1820144467Sharti fcntl(job->outFd, F_SETFD, 1); 18211590Srgrimes } 18221590Srgrimes } 18231590Srgrimes 1824144657Sharti if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) && maxJobs != 0) { 1825144467Sharti /* 1826144467Sharti * We've hit the limit of concurrency, so put the job on hold 1827144467Sharti * until some other job finishes. Note that the special jobs 1828144467Sharti * (.BEGIN, .INTERRUPT and .END) may be run even when the 1829144467Sharti * limit has been reached (e.g. when maxJobs == 0). 1830144467Sharti */ 1831144467Sharti jobFull = TRUE; 18321590Srgrimes 1833144467Sharti DEBUGF(JOB, ("Can only run job locally.\n")); 1834144467Sharti job->flags |= JOB_RESTART; 1835144494Sharti TAILQ_INSERT_TAIL(&stoppedJobs, job, link); 18361590Srgrimes } else { 1837144467Sharti if (nJobs >= maxJobs) { 1838144467Sharti /* 1839144657Sharti * If we're running this job as a special case 1840144467Sharti * (see above), at least say the table is full. 1841144467Sharti */ 1842144467Sharti jobFull = TRUE; 1843144467Sharti DEBUGF(JOB, ("Local job queue is full.\n")); 1844144467Sharti } 1845144467Sharti JobExec(job, argv); 18461590Srgrimes } 1847144467Sharti return (JOB_RUNNING); 18481590Srgrimes} 18491590Srgrimes 185018730Sstevestatic char * 1851104696SjmallettJobOutput(Job *job, char *cp, char *endp, int msg) 185218730Ssteve{ 1853144467Sharti char *ecp; 185418730Ssteve 1855144467Sharti if (commandShell->noPrint) { 1856144467Sharti ecp = strstr(cp, commandShell->noPrint); 1857144467Sharti while (ecp != NULL) { 1858144467Sharti if (cp != ecp) { 1859144467Sharti *ecp = '\0'; 1860144467Sharti if (msg && job->node != lastNode) { 1861144467Sharti MESSAGE(stdout, job->node); 1862144467Sharti lastNode = job->node; 1863144467Sharti } 1864144467Sharti /* 1865144467Sharti * The only way there wouldn't be a newline 1866144467Sharti * after this line is if it were the last in 1867144467Sharti * the buffer. However, since the non-printable 1868144467Sharti * comes after it, there must be a newline, so 1869144467Sharti * we don't print one. 1870144467Sharti */ 1871144467Sharti fprintf(stdout, "%s", cp); 1872144467Sharti fflush(stdout); 1873144467Sharti } 1874144741Sharti cp = ecp + strlen(commandShell->noPrint); 1875144467Sharti if (cp != endp) { 1876144467Sharti /* 1877144467Sharti * Still more to print, look again after 1878144467Sharti * skipping the whitespace following the 1879144467Sharti * non-printable command.... 1880144467Sharti */ 1881144467Sharti cp++; 1882144467Sharti while (*cp == ' ' || *cp == '\t' || 1883144467Sharti *cp == '\n') { 1884144467Sharti cp++; 1885144467Sharti } 1886144467Sharti ecp = strstr(cp, commandShell->noPrint); 1887144467Sharti } else { 1888144467Sharti return (cp); 1889144467Sharti } 189018730Ssteve } 189118730Ssteve } 1892144467Sharti return (cp); 189318730Ssteve} 189418730Ssteve 1895144467Sharti/** 1896144467Sharti * JobDoOutput 18971590Srgrimes * This function is called at different times depending on 18981590Srgrimes * whether the user has specified that output is to be collected 18991590Srgrimes * via pipes or temporary files. In the former case, we are called 19001590Srgrimes * whenever there is something to read on the pipe. We collect more 19011590Srgrimes * output from the given job and store it in the job's outBuf. If 19021590Srgrimes * this makes up a line, we print it tagged by the job's identifier, 19031590Srgrimes * as necessary. 19041590Srgrimes * If output has been collected in a temporary file, we open the 19051590Srgrimes * file and read it line by line, transfering it to our own 19061590Srgrimes * output channel until the file is empty. At which point we 19071590Srgrimes * remove the temporary file. 19081590Srgrimes * In both cases, however, we keep our figurative eye out for the 19091590Srgrimes * 'noPrint' line for the shell from which the output came. If 19101590Srgrimes * we recognize a line, we don't print it. If the command is not 19111590Srgrimes * alone on the line (the character after it is not \0 or \n), we 19121590Srgrimes * do print whatever follows it. 19131590Srgrimes * 19141590Srgrimes * Side Effects: 19151590Srgrimes * curPos may be shifted as may the contents of outBuf. 19161590Srgrimes */ 1917144656Shartistatic void 1918104696SjmallettJobDoOutput(Job *job, Boolean finish) 19191590Srgrimes{ 1920144467Sharti Boolean gotNL = FALSE; /* true if got a newline */ 1921144467Sharti Boolean fbuf; /* true if our buffer filled up */ 1922144467Sharti int nr; /* number of bytes read */ 1923144467Sharti int i; /* auxiliary index into outBuf */ 1924144467Sharti int max; /* limit for i (end of current data) */ 1925144467Sharti int nRead; /* (Temporary) number of bytes read */ 1926144467Sharti FILE *oFILE; /* Stream pointer to shell's output file */ 1927144467Sharti char inLine[132]; 19281590Srgrimes 1929144467Sharti if (usePipes) { 19301590Srgrimes /* 1931144467Sharti * Read as many bytes as will fit in the buffer. 19321590Srgrimes */ 1933144467Sharti end_loop: 1934144467Sharti gotNL = FALSE; 1935144467Sharti fbuf = FALSE; 19368874Srgrimes 1937144467Sharti nRead = read(job->inPipe, &job->outBuf[job->curPos], 1938144467Sharti JOB_BUFSIZE - job->curPos); 19391590Srgrimes /* 1940144467Sharti * Check for interrupt here too, because the above read may 1941144467Sharti * block when the child process is stopped. In this case the 1942144467Sharti * interrupt will unblock it (we don't use SA_RESTART). 19431590Srgrimes */ 1944144467Sharti if (interrupted) 1945144467Sharti JobPassSig(interrupted); 19461590Srgrimes 1947144467Sharti if (nRead < 0) { 1948144467Sharti DEBUGF(JOB, ("JobDoOutput(piperead)")); 1949144467Sharti nr = 0; 1950144467Sharti } else { 1951144467Sharti nr = nRead; 1952144467Sharti } 19531590Srgrimes 19541590Srgrimes /* 1955144467Sharti * If we hit the end-of-file (the job is dead), we must flush 1956144467Sharti * its remaining output, so pretend we read a newline if 1957144467Sharti * there's any output remaining in the buffer. 1958144467Sharti * Also clear the 'finish' flag so we stop looping. 19591590Srgrimes */ 1960144657Sharti if (nr == 0 && job->curPos != 0) { 1961144467Sharti job->outBuf[job->curPos] = '\n'; 1962144467Sharti nr = 1; 1963144467Sharti finish = FALSE; 1964144467Sharti } else if (nr == 0) { 1965144467Sharti finish = FALSE; 19661590Srgrimes } 19678874Srgrimes 19681590Srgrimes /* 1969144467Sharti * Look for the last newline in the bytes we just got. If there 1970144467Sharti * is one, break out of the loop with 'i' as its index and 1971144467Sharti * gotNL set TRUE. 1972144467Sharti */ 1973144467Sharti max = job->curPos + nr; 1974144467Sharti for (i = job->curPos + nr - 1; i >= job->curPos; i--) { 1975144467Sharti if (job->outBuf[i] == '\n') { 1976144467Sharti gotNL = TRUE; 1977144467Sharti break; 1978144467Sharti } else if (job->outBuf[i] == '\0') { 1979144467Sharti /* 1980144467Sharti * Why? 1981144467Sharti */ 1982144467Sharti job->outBuf[i] = ' '; 1983144467Sharti } 1984144467Sharti } 19851590Srgrimes 1986144467Sharti if (!gotNL) { 1987144467Sharti job->curPos += nr; 1988144467Sharti if (job->curPos == JOB_BUFSIZE) { 1989144467Sharti /* 1990144467Sharti * If we've run out of buffer space, we have 1991144467Sharti * no choice but to print the stuff. sigh. 1992144467Sharti */ 1993144467Sharti fbuf = TRUE; 1994144467Sharti i = job->curPos; 1995144467Sharti } 19961590Srgrimes } 1997144467Sharti if (gotNL || fbuf) { 1998144467Sharti /* 1999144467Sharti * Need to send the output to the screen. Null terminate 2000144467Sharti * it first, overwriting the newline character if there 2001144467Sharti * was one. So long as the line isn't one we should 2002144467Sharti * filter (according to the shell description), we print 2003144467Sharti * the line, preceded by a target banner if this target 2004144467Sharti * isn't the same as the one for which we last printed 2005144467Sharti * something. The rest of the data in the buffer are 2006144467Sharti * then shifted down to the start of the buffer and 2007144467Sharti * curPos is set accordingly. 2008144467Sharti */ 2009144467Sharti job->outBuf[i] = '\0'; 2010144467Sharti if (i >= job->curPos) { 2011144467Sharti char *cp; 20121590Srgrimes 2013144467Sharti cp = JobOutput(job, job->outBuf, 2014144467Sharti &job->outBuf[i], FALSE); 2015144467Sharti 2016144467Sharti /* 2017144467Sharti * There's still more in that buffer. This time, 2018144467Sharti * though, we know there's no newline at the 2019144467Sharti * end, so we add one of our own free will. 2020144467Sharti */ 2021144467Sharti if (*cp != '\0') { 2022144467Sharti if (job->node != lastNode) { 2023144467Sharti MESSAGE(stdout, job->node); 2024144467Sharti lastNode = job->node; 2025144467Sharti } 2026144467Sharti fprintf(stdout, "%s%s", cp, 2027144467Sharti gotNL ? "\n" : ""); 2028144467Sharti fflush(stdout); 2029144467Sharti } 2030144467Sharti } 2031144467Sharti if (i < max - 1) { 2032144467Sharti /* shift the remaining characters down */ 2033144467Sharti memcpy(job->outBuf, &job->outBuf[i + 1], 2034144467Sharti max - (i + 1)); 2035144467Sharti job->curPos = max - (i + 1); 2036144467Sharti 2037144467Sharti } else { 2038144467Sharti /* 2039144467Sharti * We have written everything out, so we just 2040144467Sharti * start over from the start of the buffer. 2041144467Sharti * No copying. No nothing. 2042144467Sharti */ 2043144467Sharti job->curPos = 0; 2044144467Sharti } 2045144467Sharti } 2046144467Sharti if (finish) { 2047144467Sharti /* 2048144467Sharti * If the finish flag is true, we must loop until we hit 2049144467Sharti * end-of-file on the pipe. This is guaranteed to happen 2050144467Sharti * eventually since the other end of the pipe is now 2051144467Sharti * closed (we closed it explicitly and the child has 2052144467Sharti * exited). When we do get an EOF, finish will be set 2053144467Sharti * FALSE and we'll fall through and out. 2054144467Sharti */ 2055144467Sharti goto end_loop; 2056144467Sharti } 2057144467Sharti 2058144467Sharti } else { 20591590Srgrimes /* 2060144467Sharti * We've been called to retrieve the output of the job from the 2061144467Sharti * temporary file where it's been squirreled away. This consists 2062144467Sharti * of opening the file, reading the output line by line, being 2063144467Sharti * sure not to print the noPrint line for the shell we used, 2064144467Sharti * then close and remove the temporary file. Very simple. 2065144467Sharti * 2066144467Sharti * Change to read in blocks and do FindSubString type things 2067144467Sharti * as for pipes? That would allow for "@echo -n..." 20681590Srgrimes */ 2069144467Sharti oFILE = fopen(job->outFile, "r"); 2070144467Sharti if (oFILE != NULL) { 2071144467Sharti fprintf(stdout, "Results of making %s:\n", 2072144467Sharti job->node->name); 2073144467Sharti fflush(stdout); 2074144467Sharti 2075144467Sharti while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { 2076144467Sharti char *cp, *endp, *oendp; 2077144467Sharti 2078144467Sharti cp = inLine; 2079144467Sharti oendp = endp = inLine + strlen(inLine); 2080144467Sharti if (endp[-1] == '\n') { 2081144467Sharti *--endp = '\0'; 2082144467Sharti } 2083144467Sharti cp = JobOutput(job, inLine, endp, FALSE); 2084144467Sharti 2085144467Sharti /* 2086144467Sharti * There's still more in that buffer. This time, 2087144467Sharti * though, we know there's no newline at the 2088144467Sharti * end, so we add one of our own free will. 2089144467Sharti */ 2090144467Sharti fprintf(stdout, "%s", cp); 2091144467Sharti fflush(stdout); 2092144467Sharti if (endp != oendp) { 2093144467Sharti fprintf(stdout, "\n"); 2094144467Sharti fflush(stdout); 2095144467Sharti } 2096144467Sharti } 2097144467Sharti fclose(oFILE); 2098144467Sharti eunlink(job->outFile); 20991590Srgrimes } 21001590Srgrimes } 21011590Srgrimes} 21021590Srgrimes 2103144467Sharti/** 2104144467Sharti * Job_CatchChildren 21051590Srgrimes * Handle the exit of a child. Called from Make_Make. 21061590Srgrimes * 21071590Srgrimes * Side Effects: 21081590Srgrimes * The job descriptor is removed from the list of children. 21091590Srgrimes * 21101590Srgrimes * Notes: 21111590Srgrimes * We do waits, blocking or not, according to the wisdom of our 21121590Srgrimes * caller, until there are no more children to report. For each 21131590Srgrimes * job, call JobFinish to finish things off. This will take care of 21141590Srgrimes * putting jobs on the stoppedJobs queue. 21151590Srgrimes */ 21161590Srgrimesvoid 2117104696SjmallettJob_CatchChildren(Boolean block) 21181590Srgrimes{ 2119144665Sharti pid_t pid; /* pid of dead child */ 2120144467Sharti Job *job; /* job descriptor for dead child */ 2121144467Sharti int status; /* Exit/termination status */ 21221590Srgrimes 2123144467Sharti /* 2124144467Sharti * Don't even bother if we know there's no one around. 2125144467Sharti */ 2126144467Sharti if (nJobs == 0) { 2127144467Sharti return; 2128144467Sharti } 21298874Srgrimes 2130144467Sharti for (;;) { 2131144467Sharti pid = waitpid((pid_t)-1, &status, 2132144467Sharti (block ? 0 : WNOHANG) | WUNTRACED); 2133144467Sharti if (pid <= 0) 2134144467Sharti break; 21351590Srgrimes 2136144665Sharti DEBUGF(JOB, ("Process %jd exited or stopped.\n", 2137144665Sharti (intmax_t)pid)); 21381590Srgrimes 2139144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2140144494Sharti if (job->pid == pid) 2141144467Sharti break; 2142143810Sharti } 2143144467Sharti 2144144494Sharti if (job == NULL) { 2145144467Sharti if (WIFSIGNALED(status) && 2146144467Sharti (WTERMSIG(status) == SIGCONT)) { 2147144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2148144494Sharti if (job->pid == pid) 2149144467Sharti break; 2150144467Sharti } 2151144494Sharti if (job == NULL) { 2152144665Sharti Error("Resumed child (%jd) " 2153144665Sharti "not in table", (intmax_t)pid); 2154144467Sharti continue; 2155144467Sharti } 2156144494Sharti TAILQ_REMOVE(&stoppedJobs, job, link); 2157144467Sharti } else { 2158144665Sharti Error("Child (%jd) not in table?", 2159144665Sharti (intmax_t)pid); 2160144467Sharti continue; 2161144467Sharti } 2162144467Sharti } else { 2163144494Sharti TAILQ_REMOVE(&jobs, job, link); 2164144467Sharti nJobs -= 1; 2165144467Sharti if (fifoFd >= 0 && maxJobs > 1) { 2166144467Sharti write(fifoFd, "+", 1); 2167144467Sharti maxJobs--; 2168144467Sharti if (nJobs >= maxJobs) 2169144467Sharti jobFull = TRUE; 2170144467Sharti else 2171144467Sharti jobFull = FALSE; 2172144467Sharti } else { 2173144467Sharti DEBUGF(JOB, ("Job queue is no longer full.\n")); 2174144467Sharti jobFull = FALSE; 2175144467Sharti } 21761590Srgrimes } 2177144467Sharti 2178144467Sharti JobFinish(job, &status); 21791590Srgrimes } 2180144467Sharti if (interrupted) 2181144467Sharti JobPassSig(interrupted); 21821590Srgrimes} 21831590Srgrimes 2184144467Sharti/** 2185144467Sharti * Job_CatchOutput 21861590Srgrimes * Catch the output from our children, if we're using 21871590Srgrimes * pipes do so. Otherwise just block time until we get a 2188138232Sharti * signal(most likely a SIGCHLD) since there's no point in 21891590Srgrimes * just spinning when there's nothing to do and the reaping 21908874Srgrimes * of a child can wait for a while. 21911590Srgrimes * 21921590Srgrimes * Side Effects: 21931590Srgrimes * Output is read from pipes if we're piping. 21941590Srgrimes * ----------------------------------------------------------------------- 21951590Srgrimes */ 21961590Srgrimesvoid 2197139064Sharti#ifdef USE_KQUEUE 2198139064ShartiJob_CatchOutput(int flag __unused) 2199139064Sharti#else 2200137606SphkJob_CatchOutput(int flag) 2201139064Sharti#endif 22021590Srgrimes{ 2203144467Sharti int nfds; 2204104475Sphk#ifdef USE_KQUEUE 2205104475Sphk#define KEV_SIZE 4 2206144467Sharti struct kevent kev[KEV_SIZE]; 2207144467Sharti int i; 2208104475Sphk#else 2209144467Sharti struct timeval timeout; 2210144467Sharti fd_set readfds; 2211144467Sharti Job *job; 2212104475Sphk#endif 22131590Srgrimes 2214144467Sharti fflush(stdout); 22151590Srgrimes 2216144467Sharti if (usePipes) { 2217104475Sphk#ifdef USE_KQUEUE 2218144467Sharti if ((nfds = kevent(kqfd, NULL, 0, kev, KEV_SIZE, NULL)) == -1) { 2219144467Sharti if (errno != EINTR) 2220144467Sharti Punt("kevent: %s", strerror(errno)); 2221144467Sharti if (interrupted) 2222144467Sharti JobPassSig(interrupted); 2223144467Sharti } else { 2224144467Sharti for (i = 0; i < nfds; i++) { 2225144467Sharti if (kev[i].flags & EV_ERROR) { 2226144467Sharti warnc(kev[i].data, "kevent"); 2227144467Sharti continue; 2228144467Sharti } 2229144467Sharti switch (kev[i].filter) { 2230144467Sharti case EVFILT_READ: 2231144467Sharti JobDoOutput(kev[i].udata, FALSE); 2232144467Sharti break; 2233144467Sharti case EVFILT_PROC: 2234144467Sharti /* 2235144467Sharti * Just wake up and let 2236144467Sharti * Job_CatchChildren() collect the 2237144467Sharti * terminated job. 2238144467Sharti */ 2239144467Sharti break; 2240144467Sharti } 2241144467Sharti } 2242104475Sphk } 2243104475Sphk#else 2244144467Sharti readfds = outputs; 2245144467Sharti timeout.tv_sec = SEL_SEC; 2246144467Sharti timeout.tv_usec = SEL_USEC; 2247144467Sharti if (flag && jobFull && fifoFd >= 0) 2248144467Sharti FD_SET(fifoFd, &readfds); 22491590Srgrimes 2250144467Sharti nfds = select(FD_SETSIZE, &readfds, (fd_set *)NULL, 2251144467Sharti (fd_set *)NULL, &timeout); 2252144467Sharti if (nfds <= 0) { 2253144467Sharti if (interrupted) 2254144467Sharti JobPassSig(interrupted); 2255144467Sharti return; 2256144467Sharti } 2257144467Sharti if (fifoFd >= 0 && FD_ISSET(fifoFd, &readfds)) { 2258144467Sharti if (--nfds <= 0) 2259144467Sharti return; 2260144467Sharti } 2261144494Sharti job = TAILQ_FIRST(&jobs); 2262144494Sharti while (nfds != 0 && job != NULL) { 2263144467Sharti if (FD_ISSET(job->inPipe, &readfds)) { 2264144467Sharti JobDoOutput(job, FALSE); 2265144494Sharti nfds--; 2266144467Sharti } 2267144494Sharti job = TAILQ_NEXT(job, link); 2268144467Sharti } 2269144467Sharti#endif /* !USE_KQUEUE */ 2270137606Sphk } 22711590Srgrimes} 22721590Srgrimes 2273144467Sharti/** 2274144467Sharti * Job_Make 22751590Srgrimes * Start the creation of a target. Basically a front-end for 22761590Srgrimes * JobStart used by the Make module. 22771590Srgrimes * 22781590Srgrimes * Side Effects: 22791590Srgrimes * Another job is started. 22801590Srgrimes */ 22811590Srgrimesvoid 2282104696SjmallettJob_Make(GNode *gn) 22831590Srgrimes{ 2284138232Sharti 2285144467Sharti JobStart(gn, 0, NULL); 22861590Srgrimes} 22871590Srgrimes 2288144467Sharti/** 2289144467Sharti * Job_Init 2290137572Sphk * Initialize the process module, given a maximum number of jobs. 22911590Srgrimes * 22921590Srgrimes * Side Effects: 22931590Srgrimes * lists and counters are initialized 22941590Srgrimes */ 22951590Srgrimesvoid 2296137572SphkJob_Init(int maxproc) 22971590Srgrimes{ 2298144467Sharti GNode *begin; /* node for commands to do at the very start */ 2299144467Sharti const char *env; 2300144467Sharti struct sigaction sa; 23011590Srgrimes 2302144467Sharti fifoFd = -1; 2303144467Sharti env = getenv("MAKE_JOBS_FIFO"); 2304137606Sphk 2305144467Sharti if (env == NULL && maxproc > 1) { 2306144467Sharti /* 2307144467Sharti * We did not find the environment variable so we are the 2308144467Sharti * leader. Create the fifo, open it, write one char per 2309144467Sharti * allowed job into the pipe. 2310144467Sharti */ 2311146155Sharti fifoFd = mkfifotemp(fifoName); 2312146155Sharti if (fifoFd < 0) { 2313146155Sharti env = NULL; 2314146155Sharti } else { 2315146155Sharti fifoMaster = 1; 2316146155Sharti fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2317146155Sharti env = fifoName; 2318146155Sharti setenv("MAKE_JOBS_FIFO", env, 1); 2319146155Sharti while (maxproc-- > 0) { 2320146155Sharti write(fifoFd, "+", 1); 2321144467Sharti } 2322146155Sharti /* The master make does not get a magic token */ 2323146155Sharti jobFull = TRUE; 2324146155Sharti maxJobs = 0; 2325137606Sphk } 2326144467Sharti 2327144467Sharti } else if (env != NULL) { 2328144467Sharti /* 2329144467Sharti * We had the environment variable so we are a slave. 2330144467Sharti * Open fifo and give ourselves a magic token which represents 2331144467Sharti * the token our parent make has grabbed to start his make 2332144467Sharti * process. Otherwise the sub-makes would gobble up tokens and 2333144467Sharti * the proper number of tokens to specify to -j would depend 2334144467Sharti * on the depth of the tree and the order of execution. 2335144467Sharti */ 2336144467Sharti fifoFd = open(env, O_RDWR, 0); 2337144467Sharti if (fifoFd >= 0) { 2338144467Sharti fcntl(fifoFd, F_SETFL, O_NONBLOCK); 2339144467Sharti maxJobs = 1; 2340144467Sharti jobFull = FALSE; 2341144467Sharti } 2342137606Sphk } 2343144467Sharti if (fifoFd <= 0) { 2344144467Sharti maxJobs = maxproc; 2345144467Sharti jobFull = FALSE; 2346144467Sharti } else { 2347137606Sphk } 2348144467Sharti nJobs = 0; 23491590Srgrimes 2350144467Sharti aborting = 0; 2351144467Sharti errors = 0; 23521590Srgrimes 2353144467Sharti lastNode = NULL; 23541590Srgrimes 2355144467Sharti if ((maxJobs == 1 && fifoFd < 0) || beVerbose == 0) { 2356144467Sharti /* 2357144467Sharti * If only one job can run at a time, there's no need for a 2358144467Sharti * banner, no is there? 2359144467Sharti */ 2360144467Sharti targFmt = ""; 2361144467Sharti } else { 2362144467Sharti targFmt = TARG_FMT; 2363144467Sharti } 2364144467Sharti 23651590Srgrimes /* 2366144467Sharti * Catch the four signals that POSIX specifies if they aren't ignored. 2367144467Sharti * JobCatchSignal will just set global variables and hope someone 2368144467Sharti * else is going to handle the interrupt. 23691590Srgrimes */ 2370144467Sharti sa.sa_handler = JobCatchSig; 2371144467Sharti sigemptyset(&sa.sa_mask); 2372144467Sharti sa.sa_flags = 0; 23738874Srgrimes 2374144467Sharti if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 2375144467Sharti sigaction(SIGINT, &sa, NULL); 2376144467Sharti } 2377144467Sharti if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { 2378144467Sharti sigaction(SIGHUP, &sa, NULL); 2379144467Sharti } 2380144467Sharti if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { 2381144467Sharti sigaction(SIGQUIT, &sa, NULL); 2382144467Sharti } 2383144467Sharti if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { 2384144467Sharti sigaction(SIGTERM, &sa, NULL); 2385144467Sharti } 2386144467Sharti /* 2387144467Sharti * There are additional signals that need to be caught and passed if 2388144467Sharti * either the export system wants to be told directly of signals or if 2389144467Sharti * we're giving each job its own process group (since then it won't get 2390144467Sharti * signals from the terminal driver as we own the terminal) 2391144467Sharti */ 2392137202Sharti#if defined(USE_PGRP) 2393144467Sharti if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { 2394144467Sharti sigaction(SIGTSTP, &sa, NULL); 2395144467Sharti } 2396144467Sharti if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) { 2397144467Sharti sigaction(SIGTTOU, &sa, NULL); 2398144467Sharti } 2399144467Sharti if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) { 2400144467Sharti sigaction(SIGTTIN, &sa, NULL); 2401144467Sharti } 2402144467Sharti if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) { 2403144467Sharti sigaction(SIGWINCH, &sa, NULL); 2404144467Sharti } 24051590Srgrimes#endif 24068874Srgrimes 2407104475Sphk#ifdef USE_KQUEUE 2408144467Sharti if ((kqfd = kqueue()) == -1) { 2409144467Sharti Punt("kqueue: %s", strerror(errno)); 2410144467Sharti } 2411104475Sphk#endif 2412104475Sphk 2413144467Sharti begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); 24141590Srgrimes 2415144467Sharti if (begin != NULL) { 2416144467Sharti JobStart(begin, JOB_SPECIAL, (Job *)NULL); 2417144467Sharti while (nJobs) { 2418144467Sharti Job_CatchOutput(0); 2419144467Sharti Job_CatchChildren(!usePipes); 2420144467Sharti } 24211590Srgrimes } 2422144467Sharti postCommands = Targ_FindNode(".END", TARG_CREATE); 24231590Srgrimes} 24241590Srgrimes 2425144467Sharti/** 2426144467Sharti * Job_Full 24271590Srgrimes * See if the job table is full. It is considered full if it is OR 24281590Srgrimes * if we are in the process of aborting OR if we have 24291590Srgrimes * reached/exceeded our local quota. This prevents any more jobs 24301590Srgrimes * from starting up. 24311590Srgrimes * 24321590Srgrimes * Results: 24331590Srgrimes * TRUE if the job table is full, FALSE otherwise 24341590Srgrimes */ 24351590SrgrimesBoolean 2436104696SjmallettJob_Full(void) 24371590Srgrimes{ 2438144467Sharti char c; 2439144467Sharti int i; 2440137606Sphk 2441144467Sharti if (aborting) 2442144467Sharti return (aborting); 2443144467Sharti if (fifoFd >= 0 && jobFull) { 2444144467Sharti i = read(fifoFd, &c, 1); 2445144467Sharti if (i > 0) { 2446144467Sharti maxJobs++; 2447144467Sharti jobFull = FALSE; 2448144467Sharti } 2449137606Sphk } 2450144467Sharti return (jobFull); 24511590Srgrimes} 24521590Srgrimes 2453144467Sharti/** 2454144467Sharti * Job_Empty 24551590Srgrimes * See if the job table is empty. Because the local concurrency may 24561590Srgrimes * be set to 0, it is possible for the job table to become empty, 24571590Srgrimes * while the list of stoppedJobs remains non-empty. In such a case, 24581590Srgrimes * we want to restart as many jobs as we can. 24591590Srgrimes * 24601590Srgrimes * Results: 24611590Srgrimes * TRUE if it is. FALSE if it ain't. 24621590Srgrimes */ 24631590SrgrimesBoolean 2464104696SjmallettJob_Empty(void) 24651590Srgrimes{ 2466144467Sharti if (nJobs == 0) { 2467144494Sharti if (!TAILQ_EMPTY(&stoppedJobs) && !aborting) { 2468144467Sharti /* 2469144467Sharti * The job table is obviously not full if it has no 2470144467Sharti * jobs in it...Try and restart the stopped jobs. 2471144467Sharti */ 2472144467Sharti jobFull = FALSE; 2473144467Sharti JobRestartJobs(); 2474144467Sharti return (FALSE); 2475144467Sharti } else { 2476144467Sharti return (TRUE); 2477144467Sharti } 24781590Srgrimes } else { 2479144467Sharti return (FALSE); 24801590Srgrimes } 24811590Srgrimes} 24821590Srgrimes 2483144467Sharti/** 2484144467Sharti * JobInterrupt 24851590Srgrimes * Handle the receipt of an interrupt. 24861590Srgrimes * 24871590Srgrimes * Side Effects: 24881590Srgrimes * All children are killed. Another job will be started if the 24891590Srgrimes * .INTERRUPT target was given. 24901590Srgrimes */ 24911590Srgrimesstatic void 2492104696SjmallettJobInterrupt(int runINTERRUPT, int signo) 24931590Srgrimes{ 2494144467Sharti Job *job; /* job descriptor in that element */ 2495144467Sharti GNode *interrupt; /* the node describing the .INTERRUPT target */ 24968874Srgrimes 2497144467Sharti aborting = ABORT_INTERRUPT; 24981590Srgrimes 2499144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2500144467Sharti if (!Targ_Precious(job->node)) { 2501144467Sharti char *file = (job->node->path == NULL ? 2502144467Sharti job->node->name : job->node->path); 2503144467Sharti 2504144467Sharti if (!noExecute && eunlink(file) != -1) { 2505144467Sharti Error("*** %s removed", file); 2506144467Sharti } 2507144467Sharti } 2508144467Sharti if (job->pid) { 2509144467Sharti DEBUGF(JOB, ("JobInterrupt passing signal to child " 2510144665Sharti "%jd.\n", (intmax_t)job->pid)); 2511144467Sharti KILL(job->pid, signo); 2512144467Sharti } 25131590Srgrimes } 251418730Ssteve 2515144467Sharti if (runINTERRUPT && !touchFlag) { 2516144467Sharti /* 2517144467Sharti * clear the interrupted flag because we would get an 2518144467Sharti * infinite loop otherwise. 2519144467Sharti */ 2520144467Sharti interrupted = 0; 2521137605Sharti 2522144467Sharti interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 2523144467Sharti if (interrupt != NULL) { 2524144467Sharti ignoreErrors = FALSE; 25251590Srgrimes 2526144467Sharti JobStart(interrupt, JOB_IGNDOTS, (Job *)NULL); 2527144467Sharti while (nJobs) { 2528144467Sharti Job_CatchOutput(0); 2529144467Sharti Job_CatchChildren(!usePipes); 2530144467Sharti } 2531144467Sharti } 25321590Srgrimes } 25331590Srgrimes} 25341590Srgrimes 2535144467Sharti/** 2536144467Sharti * Job_Finish 25371590Srgrimes * Do final processing such as the running of the commands 25388874Srgrimes * attached to the .END target. 25391590Srgrimes * 25401590Srgrimes * Results: 25411590Srgrimes * Number of errors reported. 25421590Srgrimes */ 25431590Srgrimesint 2544104696SjmallettJob_Finish(void) 25451590Srgrimes{ 2546138232Sharti 2547144467Sharti if (postCommands != NULL && !Lst_IsEmpty(&postCommands->commands)) { 2548144467Sharti if (errors) { 2549144467Sharti Error("Errors reported so .END ignored"); 2550144467Sharti } else { 2551144467Sharti JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL); 25521590Srgrimes 2553144467Sharti while (nJobs) { 2554144467Sharti Job_CatchOutput(0); 2555144467Sharti Job_CatchChildren(!usePipes); 2556144467Sharti } 2557144467Sharti } 25581590Srgrimes } 2559144467Sharti if (fifoFd >= 0) { 2560144467Sharti close(fifoFd); 2561144467Sharti fifoFd = -1; 2562144467Sharti if (fifoMaster) 2563144467Sharti unlink(fifoName); 2564144467Sharti } 2565144467Sharti return (errors); 25661590Srgrimes} 25671590Srgrimes 2568144467Sharti/** 2569144467Sharti * Job_Wait 25701590Srgrimes * Waits for all running jobs to finish and returns. Sets 'aborting' 25711590Srgrimes * to ABORT_WAIT to prevent other jobs from starting. 25721590Srgrimes * 25731590Srgrimes * Side Effects: 25741590Srgrimes * Currently running jobs finish. 25751590Srgrimes */ 25761590Srgrimesvoid 2577104696SjmallettJob_Wait(void) 25781590Srgrimes{ 2579138232Sharti 2580144467Sharti aborting = ABORT_WAIT; 2581144467Sharti while (nJobs != 0) { 2582144467Sharti Job_CatchOutput(0); 2583144467Sharti Job_CatchChildren(!usePipes); 2584144467Sharti } 2585144467Sharti aborting = 0; 25861590Srgrimes} 25871590Srgrimes 2588144467Sharti/** 2589144467Sharti * Job_AbortAll 25901590Srgrimes * Abort all currently running jobs without handling output or anything. 25911590Srgrimes * This function is to be called only in the event of a major 25921590Srgrimes * error. Most definitely NOT to be called from JobInterrupt. 25931590Srgrimes * 25941590Srgrimes * Side Effects: 25951590Srgrimes * All children are killed, not just the firstborn 25961590Srgrimes */ 25971590Srgrimesvoid 2598104696SjmallettJob_AbortAll(void) 25991590Srgrimes{ 2600144467Sharti Job *job; /* the job descriptor in that element */ 2601144467Sharti int foo; 26028874Srgrimes 2603144467Sharti aborting = ABORT_ERROR; 26048874Srgrimes 2605144467Sharti if (nJobs) { 2606144494Sharti TAILQ_FOREACH(job, &jobs, link) { 2607144467Sharti /* 2608144467Sharti * kill the child process with increasingly drastic 2609144467Sharti * signals to make darn sure it's dead. 2610144467Sharti */ 2611144467Sharti KILL(job->pid, SIGINT); 2612144467Sharti KILL(job->pid, SIGKILL); 2613144467Sharti } 26141590Srgrimes } 26158874Srgrimes 2616144467Sharti /* 2617144467Sharti * Catch as many children as want to report in at first, then give up 2618144467Sharti */ 2619144467Sharti while (waitpid((pid_t)-1, &foo, WNOHANG) > 0) 2620144665Sharti ; 26211590Srgrimes} 262218730Ssteve 2623144467Sharti/** 2624144467Sharti * JobRestartJobs 262518730Ssteve * Tries to restart stopped jobs if there are slots available. 262618730Ssteve * Note that this tries to restart them regardless of pending errors. 262718730Ssteve * It's not good to leave stopped jobs lying around! 262818730Ssteve * 262918730Ssteve * Side Effects: 263018730Ssteve * Resumes(and possibly migrates) jobs. 263118730Ssteve */ 263218730Sstevestatic void 2633104696SjmallettJobRestartJobs(void) 263418730Ssteve{ 2635144494Sharti Job *job; 2636144494Sharti 2637144494Sharti while (!jobFull && (job = TAILQ_FIRST(&stoppedJobs)) != NULL) { 2638144467Sharti DEBUGF(JOB, ("Job queue is not full. " 2639144467Sharti "Restarting a stopped job.\n")); 2640144494Sharti TAILQ_REMOVE(&stoppedJobs, job, link); 2641144494Sharti JobRestart(job); 2642144467Sharti } 264318730Ssteve} 2644146054Sharti 2645146054Sharti/** 2646146054Sharti * Cmd_Exec 2647146054Sharti * Execute the command in cmd, and return the output of that command 2648146054Sharti * in a string. 2649146054Sharti * 2650146054Sharti * Results: 2651146054Sharti * A string containing the output of the command, or the empty string 2652146054Sharti * If error is not NULL, it contains the reason for the command failure 2653146129Sharti * Any output sent to stderr in the child process is passed to stderr, 2654146129Sharti * and not captured in the string. 2655146054Sharti * 2656146054Sharti * Side Effects: 2657146054Sharti * The string must be freed by the caller. 2658146054Sharti */ 2659146054ShartiBuffer * 2660146054ShartiCmd_Exec(const char *cmd, const char **error) 2661146054Sharti{ 2662146054Sharti int fds[2]; /* Pipe streams */ 2663146054Sharti int status; /* command exit status */ 2664146054Sharti Buffer *buf; /* buffer to store the result */ 2665146054Sharti ssize_t rcnt; 2666146129Sharti ProcStuff ps; 2667146054Sharti 2668146054Sharti *error = NULL; 2669146054Sharti buf = Buf_Init(0); 2670146054Sharti 2671146054Sharti /* 2672146054Sharti * Open a pipe for fetching its output 2673146054Sharti */ 2674146054Sharti if (pipe(fds) == -1) { 2675146054Sharti *error = "Couldn't create pipe for \"%s\""; 2676146054Sharti return (buf); 2677146054Sharti } 2678146054Sharti 2679146129Sharti /* Set close-on-exec on read side of pipe. */ 2680146129Sharti fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC); 2681146129Sharti 2682146129Sharti ps.in = STDIN_FILENO; 2683146129Sharti ps.out = fds[1]; 2684146129Sharti ps.err = STDERR_FILENO; 2685146129Sharti 2686146129Sharti ps.merge_errors = 0; 2687146129Sharti ps.pgroup = 0; 2688146129Sharti ps.searchpath = 0; 2689146129Sharti 2690146129Sharti /* Set up arguments for shell */ 2691146129Sharti ps.argv = emalloc(4 * sizeof(char *)); 2692146557Sharti ps.argv[0] = strdup(commandShell->name); 2693146129Sharti ps.argv[1] = strdup("-c"); 2694146129Sharti ps.argv[2] = strdup(cmd); 2695146129Sharti ps.argv[3] = NULL; 2696146156Sharti ps.argv_free = 1; 2697146129Sharti 2698146054Sharti /* 2699146129Sharti * Fork. Warning since we are doing vfork() instead of fork(), 2700146129Sharti * do not allocate memory in the child process! 2701146054Sharti */ 2702146130Sharti if ((ps.child_pid = vfork()) == -1) { 2703146058Sharti *error = "Couldn't exec \"%s\""; 2704146058Sharti return (buf); 2705146058Sharti 2706146130Sharti } else if (ps.child_pid == 0) { 2707146129Sharti /* 2708146129Sharti * Child 2709146129Sharti */ 2710146574Sharti Proc_Exec(&ps); 2711146129Sharti /* NOTREACHED */ 2712146129Sharti } 2713146054Sharti 2714146129Sharti free(ps.argv[2]); 2715146129Sharti free(ps.argv[1]); 2716146129Sharti free(ps.argv[0]); 2717146129Sharti free(ps.argv); 2718146054Sharti 2719146129Sharti close(fds[1]); /* No need for the writing half of the pipe. */ 2720146054Sharti 2721146058Sharti do { 2722146058Sharti char result[BUFSIZ]; 2723146054Sharti 2724146058Sharti rcnt = read(fds[0], result, sizeof(result)); 2725146058Sharti if (rcnt != -1) 2726146058Sharti Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result); 2727146058Sharti } while (rcnt > 0 || (rcnt == -1 && errno == EINTR)); 2728146054Sharti 2729146058Sharti if (rcnt == -1) 2730146058Sharti *error = "Error reading shell's output for \"%s\""; 2731146054Sharti 2732146058Sharti /* 2733146058Sharti * Close the input side of the pipe. 2734146058Sharti */ 2735146058Sharti close(fds[0]); 2736146054Sharti 2737146130Sharti status = ProcWait(&ps); 2738146054Sharti 2739146058Sharti if (status) 2740146058Sharti *error = "\"%s\" returned non-zero status"; 2741146054Sharti 2742146058Sharti Buf_StripNewlines(buf); 2743146054Sharti 2744146054Sharti return (buf); 2745146054Sharti} 2746146054Sharti 2747146056Sharti 2748146056Sharti/* 2749146056Sharti * Interrupt handler - set flag and defer handling to the main code 2750146056Sharti */ 2751146056Shartistatic void 2752146056ShartiCompatCatchSig(int signo) 2753146056Sharti{ 2754146056Sharti 2755146056Sharti interrupted = signo; 2756146056Sharti} 2757146056Sharti 2758146056Sharti/*- 2759146056Sharti *----------------------------------------------------------------------- 2760146056Sharti * CompatInterrupt -- 2761146056Sharti * Interrupt the creation of the current target and remove it if 2762146056Sharti * it ain't precious. 2763146056Sharti * 2764146056Sharti * Results: 2765146056Sharti * None. 2766146056Sharti * 2767146056Sharti * Side Effects: 2768146056Sharti * The target is removed and the process exits. If .INTERRUPT exists, 2769146056Sharti * its commands are run first WITH INTERRUPTS IGNORED.. 2770146056Sharti * 2771146056Sharti *----------------------------------------------------------------------- 2772146056Sharti */ 2773146056Shartistatic void 2774146056ShartiCompatInterrupt(int signo) 2775146056Sharti{ 2776146056Sharti GNode *gn; 2777146056Sharti sigset_t nmask, omask; 2778146056Sharti LstNode *ln; 2779146056Sharti 2780146056Sharti sigemptyset(&nmask); 2781146056Sharti sigaddset(&nmask, SIGINT); 2782146056Sharti sigaddset(&nmask, SIGTERM); 2783146056Sharti sigaddset(&nmask, SIGHUP); 2784146056Sharti sigaddset(&nmask, SIGQUIT); 2785146056Sharti sigprocmask(SIG_SETMASK, &nmask, &omask); 2786146056Sharti 2787146056Sharti /* prevent recursion in evaluation of .INTERRUPT */ 2788146056Sharti interrupted = 0; 2789146056Sharti 2790146056Sharti if (curTarg != NULL && !Targ_Precious(curTarg)) { 2791146056Sharti char *p1; 2792146061Sharti char *file = Var_Value(TARGET, curTarg, &p1); 2793146056Sharti 2794146056Sharti if (!noExecute && eunlink(file) != -1) { 2795146056Sharti printf("*** %s removed\n", file); 2796146056Sharti } 2797146056Sharti free(p1); 2798146056Sharti } 2799146056Sharti 2800146056Sharti /* 2801146056Sharti * Run .INTERRUPT only if hit with interrupt signal 2802146056Sharti */ 2803146056Sharti if (signo == SIGINT) { 2804146056Sharti gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); 2805146056Sharti if (gn != NULL) { 2806146056Sharti LST_FOREACH(ln, &gn->commands) { 2807146056Sharti if (Compat_RunCommand(Lst_Datum(ln), gn)) 2808146056Sharti break; 2809146056Sharti } 2810146056Sharti } 2811146056Sharti } 2812146056Sharti 2813146056Sharti sigprocmask(SIG_SETMASK, &omask, NULL); 2814146056Sharti 2815146056Sharti if (signo == SIGQUIT) 2816146056Sharti exit(signo); 2817146056Sharti signal(signo, SIG_DFL); 2818146056Sharti kill(getpid(), signo); 2819146056Sharti} 2820146056Sharti 2821146129Sharti/** 2822146129Sharti * shellneed 2823146056Sharti * 2824146056Sharti * Results: 2825146129Sharti * Returns NULL if a specified line must be executed by the shell, 2826146129Sharti * and an argument vector if it can be run via execvp(). 2827146056Sharti * 2828146056Sharti * Side Effects: 2829146056Sharti * Uses brk_string so destroys the contents of argv. 2830146056Sharti */ 2831146129Shartistatic char ** 2832146345Shartishellneed(ArgArray *aa, char *cmd) 2833146056Sharti{ 2834146557Sharti char **p; 2835146557Sharti int ret; 2836146056Sharti 2837146557Sharti if (commandShell->meta == NULL || commandShell->builtins.argc <= 1) 2838146557Sharti /* use shell */ 2839146129Sharti return (NULL); 2840146129Sharti 2841146557Sharti if (strpbrk(cmd, commandShell->meta) != NULL) 2842146557Sharti return (NULL); 2843146557Sharti 2844146147Sharti /* 2845146147Sharti * Break the command into words to form an argument 2846146345Sharti * vector we can execute. 2847146147Sharti */ 2848146345Sharti brk_string(aa, cmd, TRUE); 2849146557Sharti for (p = commandShell->builtins.argv + 1; *p != 0; p++) { 2850146557Sharti if ((ret = strcmp(aa->argv[1], *p)) == 0) { 2851146557Sharti /* found - use shell */ 2852146345Sharti ArgArray_Done(aa); 2853146129Sharti return (NULL); 2854146345Sharti } 2855146557Sharti if (ret < 0) { 2856146557Sharti /* not found */ 2857146557Sharti break; 2858146557Sharti } 2859146345Sharti } 2860146345Sharti return (aa->argv + 1); 2861146056Sharti} 2862146056Sharti 2863146557Sharti/** 2864146557Sharti * Execute the next command for a target. If the command returns an 2865146557Sharti * error, the node's made field is set to ERROR and creation stops. 2866146557Sharti * The node from which the command came is also given. This is used 2867146557Sharti * to execute the commands in compat mode and when executing commands 2868146557Sharti * with the '+' flag in non-compat mode. In these modes each command 2869146557Sharti * line should be executed by its own shell. We do some optimisation here: 2870146557Sharti * if the shell description defines both a string of meta characters and 2871146557Sharti * a list of builtins and the command line neither contains a meta character 2872146557Sharti * nor starts with one of the builtins then we execute the command directly 2873146557Sharti * without invoking a shell. 2874146056Sharti * 2875146056Sharti * Results: 2876146056Sharti * 0 if the command succeeded, 1 if an error occurred. 2877146056Sharti * 2878146056Sharti * Side Effects: 2879146056Sharti * The node's 'made' field may be set to ERROR. 2880146056Sharti */ 2881146142Shartistatic int 2882146056ShartiCompat_RunCommand(char *cmd, GNode *gn) 2883146056Sharti{ 2884146345Sharti ArgArray aa; 2885146345Sharti char *cmdStart; /* Start of expanded command */ 2886146345Sharti Boolean silent; /* Don't print command */ 2887146345Sharti Boolean doit; /* Execute even in -n */ 2888146345Sharti Boolean errCheck; /* Check errors */ 2889146345Sharti int reason; /* Reason for child's death */ 2890146345Sharti int status; /* Description of child's death */ 2891146345Sharti LstNode *cmdNode; /* Node where current cmd is located */ 2892146345Sharti char **av; /* Argument vector for thing to exec */ 2893146129Sharti ProcStuff ps; 2894146056Sharti 2895146056Sharti silent = gn->type & OP_SILENT; 2896146056Sharti errCheck = !(gn->type & OP_IGNORE); 2897146056Sharti doit = FALSE; 2898146056Sharti 2899146056Sharti cmdNode = Lst_Member(&gn->commands, cmd); 2900146056Sharti cmdStart = Buf_Peel(Var_Subst(cmd, gn, FALSE)); 2901146056Sharti 2902146056Sharti /* 2903146056Sharti * brk_string will return an argv with a NULL in av[0], thus causing 2904146129Sharti * execvp() to choke and die horribly. Besides, how can we execute a 2905146129Sharti * null command? In any case, we warn the user that the command 2906146129Sharti * expanded to nothing (is this the right thing to do?). 2907146056Sharti */ 2908146056Sharti if (*cmdStart == '\0') { 2909146056Sharti free(cmdStart); 2910146056Sharti Error("%s expands to empty string", cmd); 2911146056Sharti return (0); 2912146056Sharti } else { 2913146056Sharti cmd = cmdStart; 2914146056Sharti } 2915146056Sharti Lst_Replace(cmdNode, cmdStart); 2916146056Sharti 2917146056Sharti if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) { 2918146056Sharti Lst_AtEnd(&ENDNode->commands, cmdStart); 2919146056Sharti return (0); 2920146056Sharti } else if (strcmp(cmdStart, "...") == 0) { 2921146056Sharti gn->type |= OP_SAVE_CMDS; 2922146056Sharti return (0); 2923146056Sharti } 2924146056Sharti 2925146056Sharti while (*cmd == '@' || *cmd == '-' || *cmd == '+') { 2926146056Sharti switch (*cmd) { 2927146056Sharti 2928146056Sharti case '@': 2929146056Sharti silent = DEBUG(LOUD) ? FALSE : TRUE; 2930146056Sharti break; 2931146056Sharti 2932146056Sharti case '-': 2933146056Sharti errCheck = FALSE; 2934146056Sharti break; 2935146056Sharti 2936146129Sharti case '+': 2937146056Sharti doit = TRUE; 2938146056Sharti break; 2939146056Sharti } 2940146056Sharti cmd++; 2941146056Sharti } 2942146056Sharti 2943146056Sharti while (isspace((unsigned char)*cmd)) 2944146056Sharti cmd++; 2945146056Sharti 2946146056Sharti /* 2947146056Sharti * Print the command before echoing if we're not supposed to be quiet 2948146056Sharti * for this one. We also print the command if -n given, but not if '+'. 2949146056Sharti */ 2950146056Sharti if (!silent || (noExecute && !doit)) { 2951146056Sharti printf("%s\n", cmd); 2952146056Sharti fflush(stdout); 2953146056Sharti } 2954146056Sharti 2955146056Sharti /* 2956146056Sharti * If we're not supposed to execute any commands, this is as far as 2957146056Sharti * we go... 2958146056Sharti */ 2959146056Sharti if (!doit && noExecute) { 2960146056Sharti return (0); 2961146056Sharti } 2962146056Sharti 2963146129Sharti ps.in = STDIN_FILENO; 2964146129Sharti ps.out = STDOUT_FILENO; 2965146129Sharti ps.err = STDERR_FILENO; 2966146056Sharti 2967146129Sharti ps.merge_errors = 0; 2968146129Sharti ps.pgroup = 0; 2969146129Sharti ps.searchpath = 1; 2970146056Sharti 2971146345Sharti if ((av = shellneed(&aa, cmd)) == NULL) { 2972146056Sharti /* 2973146129Sharti * Shell meta character or shell builtin found - pass 2974146129Sharti * command to shell. We give the shell the -e flag as 2975146129Sharti * well as -c if it is supposed to exit when it hits an error. 2976146056Sharti */ 2977146129Sharti ps.argv = emalloc(4 * sizeof(char *)); 2978146557Sharti ps.argv[0] = strdup(commandShell->path); 2979146129Sharti ps.argv[1] = strdup(errCheck ? "-ec" : "-c"); 2980146129Sharti ps.argv[2] = strdup(cmd); 2981146129Sharti ps.argv[3] = NULL; 2982146156Sharti ps.argv_free = 1; 2983146056Sharti } else { 2984146129Sharti ps.argv = av; 2985146156Sharti ps.argv_free = 0; 2986146056Sharti } 2987146156Sharti ps.errCheck = errCheck; 2988146056Sharti 2989146056Sharti /* 2990146129Sharti * Warning since we are doing vfork() instead of fork(), 2991146129Sharti * do not allocate memory in the child process! 2992146056Sharti */ 2993146130Sharti if ((ps.child_pid = vfork()) == -1) { 2994146056Sharti Fatal("Could not fork"); 2995146058Sharti 2996146130Sharti } else if (ps.child_pid == 0) { 2997146129Sharti /* 2998146129Sharti * Child 2999146129Sharti */ 3000146574Sharti Proc_Exec(&ps); 3001146129Sharti /* NOTREACHED */ 3002146129Sharti 3003146131Sharti } else { 3004146156Sharti if (ps.argv_free) { 3005146131Sharti free(ps.argv[2]); 3006146131Sharti free(ps.argv[1]); 3007146131Sharti free(ps.argv[0]); 3008146131Sharti free(ps.argv); 3009146345Sharti } else { 3010146345Sharti ArgArray_Done(&aa); 3011146131Sharti } 3012146129Sharti 3013146131Sharti /* 3014146131Sharti * we need to print out the command associated with this 3015146131Sharti * Gnode in Targ_PrintCmd from Targ_PrintGraph when debugging 3016146131Sharti * at level g2, in main(), Fatal() and DieHorribly(), 3017146131Sharti * therefore do not free it when debugging. 3018146131Sharti */ 3019146131Sharti if (!DEBUG(GRAPH2)) { 3020146131Sharti free(cmdStart); 3021146131Sharti } 3022146129Sharti 3023146131Sharti /* 3024146131Sharti * The child is off and running. Now all we can do is wait... 3025146131Sharti */ 3026146131Sharti reason = ProcWait(&ps); 3027146132Sharti 3028146056Sharti if (interrupted) 3029146056Sharti CompatInterrupt(interrupted); 3030146131Sharti 3031146132Sharti /* 3032146132Sharti * Decode and report the reason child exited, then 3033146132Sharti * indicate how we handled it. 3034146132Sharti */ 3035146131Sharti if (WIFEXITED(reason)) { 3036146131Sharti status = WEXITSTATUS(reason); 3037146131Sharti if (status == 0) { 3038146131Sharti return (0); 3039146131Sharti } else { 3040146131Sharti printf("*** Error code %d", status); 3041146131Sharti } 3042146131Sharti } else if (WIFSTOPPED(reason)) { 3043146131Sharti status = WSTOPSIG(reason); 3044146131Sharti } else { 3045146131Sharti status = WTERMSIG(reason); 3046146131Sharti printf("*** Signal %d", status); 3047146131Sharti } 3048146131Sharti 3049146156Sharti if (ps.errCheck) { 3050146131Sharti gn->made = ERROR; 3051146131Sharti if (keepgoing) { 3052146131Sharti /* 3053146131Sharti * Abort the current 3054146131Sharti * target, but let 3055146131Sharti * others continue. 3056146131Sharti */ 3057146131Sharti printf(" (continuing)\n"); 3058146056Sharti } 3059146131Sharti return (status); 3060146056Sharti } else { 3061146131Sharti /* 3062146131Sharti * Continue executing 3063146131Sharti * commands for this target. 3064146131Sharti * If we return 0, this will 3065146131Sharti * happen... 3066146131Sharti */ 3067146131Sharti printf(" (ignored)\n"); 3068146131Sharti return (0); 3069146056Sharti } 3070146056Sharti } 3071146056Sharti} 3072146056Sharti 3073146056Sharti/*- 3074146056Sharti *----------------------------------------------------------------------- 3075146056Sharti * CompatMake -- 3076146056Sharti * Make a target, given the parent, to abort if necessary. 3077146056Sharti * 3078146056Sharti * Side Effects: 3079146056Sharti * If an error is detected and not being ignored, the process exits. 3080146056Sharti * 3081146056Sharti *----------------------------------------------------------------------- 3082146056Sharti */ 3083146056Shartistatic int 3084146056ShartiCompatMake(GNode *gn, GNode *pgn) 3085146056Sharti{ 3086146056Sharti LstNode *ln; 3087146056Sharti 3088146056Sharti if (gn->type & OP_USE) { 3089146056Sharti Make_HandleUse(gn, pgn); 3090146056Sharti 3091146056Sharti } else if (gn->made == UNMADE) { 3092146056Sharti /* 3093146056Sharti * First mark ourselves to be made, then apply whatever 3094146056Sharti * transformations the suffix module thinks are necessary. 3095146056Sharti * Once that's done, we can descend and make all our children. 3096146056Sharti * If any of them has an error but the -k flag was given, our 3097146056Sharti * 'make' field will be set FALSE again. This is our signal to 3098146056Sharti * not attempt to do anything but abort our parent as well. 3099146056Sharti */ 3100146056Sharti gn->make = TRUE; 3101146056Sharti gn->made = BEINGMADE; 3102146056Sharti Suff_FindDeps(gn); 3103146056Sharti LST_FOREACH(ln, &gn->children) 3104146056Sharti CompatMake(Lst_Datum(ln), gn); 3105146056Sharti if (!gn->make) { 3106146056Sharti gn->made = ABORTED; 3107146056Sharti pgn->make = FALSE; 3108146056Sharti return (0); 3109146056Sharti } 3110146056Sharti 3111146056Sharti if (Lst_Member(&gn->iParents, pgn) != NULL) { 3112146056Sharti char *p1; 3113146056Sharti Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn); 3114146056Sharti free(p1); 3115146056Sharti } 3116146056Sharti 3117146056Sharti /* 3118146056Sharti * All the children were made ok. Now cmtime contains the 3119146056Sharti * modification time of the newest child, we need to find out 3120146056Sharti * if we exist and when we were modified last. The criteria for 3121146056Sharti * datedness are defined by the Make_OODate function. 3122146056Sharti */ 3123146056Sharti DEBUGF(MAKE, ("Examining %s...", gn->name)); 3124146056Sharti if (!Make_OODate(gn)) { 3125146056Sharti gn->made = UPTODATE; 3126146056Sharti DEBUGF(MAKE, ("up-to-date.\n")); 3127146056Sharti return (0); 3128146056Sharti } else { 3129146056Sharti DEBUGF(MAKE, ("out-of-date.\n")); 3130146056Sharti } 3131146056Sharti 3132146056Sharti /* 3133146056Sharti * If the user is just seeing if something is out-of-date, 3134146056Sharti * exit now to tell him/her "yes". 3135146056Sharti */ 3136146056Sharti if (queryFlag) { 3137146056Sharti exit(1); 3138146056Sharti } 3139146056Sharti 3140146056Sharti /* 3141146056Sharti * We need to be re-made. We also have to make sure we've got 3142146056Sharti * a $? variable. To be nice, we also define the $> variable 3143146056Sharti * using Make_DoAllVar(). 3144146056Sharti */ 3145146056Sharti Make_DoAllVar(gn); 3146146056Sharti 3147146056Sharti /* 3148146056Sharti * Alter our type to tell if errors should be ignored or things 3149146056Sharti * should not be printed so Compat_RunCommand knows what to do. 3150146056Sharti */ 3151146056Sharti if (Targ_Ignore(gn)) { 3152146056Sharti gn->type |= OP_IGNORE; 3153146056Sharti } 3154146056Sharti if (Targ_Silent(gn)) { 3155146056Sharti gn->type |= OP_SILENT; 3156146056Sharti } 3157146056Sharti 3158146056Sharti if (Job_CheckCommands(gn, Fatal)) { 3159146056Sharti /* 3160146056Sharti * Our commands are ok, but we still have to worry 3161146056Sharti * about the -t flag... 3162146056Sharti */ 3163146056Sharti if (!touchFlag) { 3164146056Sharti curTarg = gn; 3165146056Sharti LST_FOREACH(ln, &gn->commands) { 3166146056Sharti if (Compat_RunCommand(Lst_Datum(ln), 3167146056Sharti gn)) 3168146056Sharti break; 3169146056Sharti } 3170146056Sharti curTarg = NULL; 3171146056Sharti } else { 3172146056Sharti Job_Touch(gn, gn->type & OP_SILENT); 3173146056Sharti } 3174146056Sharti } else { 3175146056Sharti gn->made = ERROR; 3176146056Sharti } 3177146056Sharti 3178146056Sharti if (gn->made != ERROR) { 3179146056Sharti /* 3180146056Sharti * If the node was made successfully, mark it so, update 3181146056Sharti * its modification time and timestamp all its parents. 3182146056Sharti * Note that for .ZEROTIME targets, the timestamping 3183146056Sharti * isn't done. This is to keep its state from affecting 3184146056Sharti * that of its parent. 3185146056Sharti */ 3186146056Sharti gn->made = MADE; 3187146056Sharti#ifndef RECHECK 3188146056Sharti /* 3189146056Sharti * We can't re-stat the thing, but we can at least take 3190146056Sharti * care of rules where a target depends on a source that 3191146056Sharti * actually creates the target, but only if it has 3192146056Sharti * changed, e.g. 3193146056Sharti * 3194146056Sharti * parse.h : parse.o 3195146056Sharti * 3196146056Sharti * parse.o : parse.y 3197146061Sharti * yacc -d parse.y 3198146061Sharti * cc -c y.tab.c 3199146061Sharti * mv y.tab.o parse.o 3200146061Sharti * cmp -s y.tab.h parse.h || mv y.tab.h parse.h 3201146056Sharti * 3202146056Sharti * In this case, if the definitions produced by yacc 3203146056Sharti * haven't changed from before, parse.h won't have been 3204146056Sharti * updated and gn->mtime will reflect the current 3205146056Sharti * modification time for parse.h. This is something of a 3206146056Sharti * kludge, I admit, but it's a useful one.. 3207146056Sharti * 3208146056Sharti * XXX: People like to use a rule like 3209146056Sharti * 3210146056Sharti * FRC: 3211146056Sharti * 3212146056Sharti * To force things that depend on FRC to be made, so we 3213146056Sharti * have to check for gn->children being empty as well... 3214146056Sharti */ 3215146056Sharti if (!Lst_IsEmpty(&gn->commands) || 3216146056Sharti Lst_IsEmpty(&gn->children)) { 3217146056Sharti gn->mtime = now; 3218146056Sharti } 3219146056Sharti#else 3220146056Sharti /* 3221146056Sharti * This is what Make does and it's actually a good 3222146056Sharti * thing, as it allows rules like 3223146056Sharti * 3224146056Sharti * cmp -s y.tab.h parse.h || cp y.tab.h parse.h 3225146056Sharti * 3226146056Sharti * to function as intended. Unfortunately, thanks to 3227146056Sharti * the stateless nature of NFS (and the speed of this 3228146056Sharti * program), there are times when the modification time 3229146056Sharti * of a file created on a remote machine will not be 3230146056Sharti * modified before the stat() implied by the Dir_MTime 3231146056Sharti * occurs, thus leading us to believe that the file 3232146056Sharti * is unchanged, wreaking havoc with files that depend 3233146056Sharti * on this one. 3234146056Sharti * 3235146056Sharti * I have decided it is better to make too much than to 3236146056Sharti * make too little, so this stuff is commented out 3237146056Sharti * unless you're sure it's ok. 3238146056Sharti * -- ardeb 1/12/88 3239146056Sharti */ 3240146056Sharti if (noExecute || Dir_MTime(gn) == 0) { 3241146056Sharti gn->mtime = now; 3242146056Sharti } 3243146056Sharti if (gn->cmtime > gn->mtime) 3244146056Sharti gn->mtime = gn->cmtime; 3245146056Sharti DEBUGF(MAKE, ("update time: %s\n", 3246146056Sharti Targ_FmtTime(gn->mtime))); 3247146056Sharti#endif 3248146056Sharti if (!(gn->type & OP_EXEC)) { 3249146056Sharti pgn->childMade = TRUE; 3250146056Sharti Make_TimeStamp(pgn, gn); 3251146056Sharti } 3252146056Sharti 3253146056Sharti } else if (keepgoing) { 3254146056Sharti pgn->make = FALSE; 3255146056Sharti 3256146056Sharti } else { 3257146056Sharti char *p1; 3258146056Sharti 3259146056Sharti printf("\n\nStop in %s.\n", 3260146056Sharti Var_Value(".CURDIR", gn, &p1)); 3261146056Sharti free(p1); 3262146056Sharti exit(1); 3263146056Sharti } 3264146056Sharti } else if (gn->made == ERROR) { 3265146056Sharti /* 3266146056Sharti * Already had an error when making this beastie. Tell the 3267146056Sharti * parent to abort. 3268146056Sharti */ 3269146056Sharti pgn->make = FALSE; 3270146056Sharti } else { 3271146056Sharti if (Lst_Member(&gn->iParents, pgn) != NULL) { 3272146056Sharti char *p1; 3273146056Sharti Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn); 3274146056Sharti free(p1); 3275146056Sharti } 3276146056Sharti switch(gn->made) { 3277146056Sharti case BEINGMADE: 3278146056Sharti Error("Graph cycles through %s\n", gn->name); 3279146056Sharti gn->made = ERROR; 3280146056Sharti pgn->make = FALSE; 3281146056Sharti break; 3282146056Sharti case MADE: 3283146056Sharti if ((gn->type & OP_EXEC) == 0) { 3284146056Sharti pgn->childMade = TRUE; 3285146056Sharti Make_TimeStamp(pgn, gn); 3286146056Sharti } 3287146056Sharti break; 3288146056Sharti case UPTODATE: 3289146056Sharti if ((gn->type & OP_EXEC) == 0) { 3290146056Sharti Make_TimeStamp(pgn, gn); 3291146056Sharti } 3292146056Sharti break; 3293146056Sharti default: 3294146056Sharti break; 3295146056Sharti } 3296146056Sharti } 3297146056Sharti 3298146056Sharti return (0); 3299146056Sharti} 3300146056Sharti 3301146056Sharti/*- 3302146056Sharti *----------------------------------------------------------------------- 3303146056Sharti * Compat_Run -- 3304146056Sharti * Start making again, given a list of target nodes. 3305146056Sharti * 3306146056Sharti * Results: 3307146056Sharti * None. 3308146056Sharti * 3309146056Sharti * Side Effects: 3310146056Sharti * Guess what? 3311146056Sharti * 3312146056Sharti *----------------------------------------------------------------------- 3313146056Sharti */ 3314146056Shartivoid 3315146056ShartiCompat_Run(Lst *targs) 3316146056Sharti{ 3317146056Sharti GNode *gn = NULL; /* Current root target */ 3318146056Sharti int error_cnt; /* Number of targets not remade due to errors */ 3319146056Sharti LstNode *ln; 3320146056Sharti 3321146056Sharti if (signal(SIGINT, SIG_IGN) != SIG_IGN) { 3322146056Sharti signal(SIGINT, CompatCatchSig); 3323146056Sharti } 3324146056Sharti if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { 3325146056Sharti signal(SIGTERM, CompatCatchSig); 3326146056Sharti } 3327146056Sharti if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { 3328146056Sharti signal(SIGHUP, CompatCatchSig); 3329146056Sharti } 3330146056Sharti if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { 3331146056Sharti signal(SIGQUIT, CompatCatchSig); 3332146056Sharti } 3333146056Sharti 3334146056Sharti ENDNode = Targ_FindNode(".END", TARG_CREATE); 3335146056Sharti /* 3336146056Sharti * If the user has defined a .BEGIN target, execute the commands 3337146056Sharti * attached to it. 3338146056Sharti */ 3339146056Sharti if (!queryFlag) { 3340146056Sharti gn = Targ_FindNode(".BEGIN", TARG_NOCREATE); 3341146056Sharti if (gn != NULL) { 3342146056Sharti LST_FOREACH(ln, &gn->commands) { 3343146056Sharti if (Compat_RunCommand(Lst_Datum(ln), gn)) 3344146056Sharti break; 3345146056Sharti } 3346146056Sharti if (gn->made == ERROR) { 3347146056Sharti printf("\n\nStop.\n"); 3348146056Sharti exit(1); 3349146056Sharti } 3350146056Sharti } 3351146056Sharti } 3352146056Sharti 3353146056Sharti /* 3354146056Sharti * For each entry in the list of targets to create, call CompatMake on 3355146056Sharti * it to create the thing. CompatMake will leave the 'made' field of gn 3356146056Sharti * in one of several states: 3357146056Sharti * UPTODATE gn was already up-to-date 3358146056Sharti * MADE gn was recreated successfully 3359146056Sharti * ERROR An error occurred while gn was being created 3360146056Sharti * ABORTED gn was not remade because one of its inferiors 3361146056Sharti * could not be made due to errors. 3362146056Sharti */ 3363146056Sharti error_cnt = 0; 3364146056Sharti while (!Lst_IsEmpty(targs)) { 3365146056Sharti gn = Lst_DeQueue(targs); 3366146056Sharti CompatMake(gn, gn); 3367146056Sharti 3368146056Sharti if (gn->made == UPTODATE) { 3369146056Sharti printf("`%s' is up to date.\n", gn->name); 3370146056Sharti } else if (gn->made == ABORTED) { 3371146056Sharti printf("`%s' not remade because of errors.\n", 3372146056Sharti gn->name); 3373146056Sharti error_cnt += 1; 3374146056Sharti } 3375146056Sharti } 3376146056Sharti 3377146056Sharti /* 3378146056Sharti * If the user has defined a .END target, run its commands. 3379146056Sharti */ 3380146056Sharti if (error_cnt == 0) { 3381146056Sharti LST_FOREACH(ln, &ENDNode->commands) { 3382146056Sharti if (Compat_RunCommand(Lst_Datum(ln), gn)) 3383146056Sharti break; 3384146056Sharti } 3385146056Sharti } 3386146056Sharti} 3387146155Sharti 3388