Annotation of src/usr.bin/make/job.c, Revision 1.112
1.40 espie 1: /* $OpenPackages$ */
1.93 espie 2: /* $OpenBSD$ */
1.6 millert 3: /* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */
1.1 deraadt 4:
5: /*
6: * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
7: * Copyright (c) 1988, 1989 by Adam de Boor
8: * Copyright (c) 1989 by Berkeley Softworks
9: * All rights reserved.
10: *
11: * This code is derived from software contributed to Berkeley by
12: * Adam de Boor.
13: *
14: * Redistribution and use in source and binary forms, with or without
15: * modification, are permitted provided that the following conditions
16: * are met:
17: * 1. Redistributions of source code must retain the above copyright
18: * notice, this list of conditions and the following disclaimer.
19: * 2. Redistributions in binary form must reproduce the above copyright
20: * notice, this list of conditions and the following disclaimer in the
21: * documentation and/or other materials provided with the distribution.
1.55 millert 22: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: */
38:
39: /*-
40: * job.c --
41: * handle the creation etc. of our child processes.
42: *
43: * Interface:
1.40 espie 44: * Job_Make Start the creation of the given target.
1.1 deraadt 45: *
1.53 jmc 46: * Job_Init Called to initialize this module. in addition,
1.40 espie 47: * any commands attached to the .BEGIN target
48: * are executed before this function returns.
49: * Hence, the makefile must have been parsed
50: * before this function is called.
51: *
52: * Job_End Cleanup any memory used.
53: *
1.41 espie 54: * Job_Full Return true if the job table is filled.
1.40 espie 55: *
1.41 espie 56: * Job_Empty Return true if the job table is completely
1.40 espie 57: * empty.
58: *
59: * Job_Finish Perform any final processing which needs doing.
60: * This includes the execution of any commands
61: * which have been/were attached to the .END
62: * target. It should only be called when the
63: * job table is empty.
64: *
65: * Job_AbortAll Abort all currently running jobs. It doesn't
66: * handle output or do anything for the jobs,
67: * just kills them. It should only be called in
68: * an emergency, as it were.
1.1 deraadt 69: *
1.40 espie 70: * Job_Wait Wait for all currently-running jobs to finish.
1.1 deraadt 71: */
72:
73: #include <sys/types.h>
74: #include <sys/wait.h>
1.41 espie 75: #include <ctype.h>
76: #include <errno.h>
1.1 deraadt 77: #include <fcntl.h>
1.41 espie 78: #include <signal.h>
1.69 espie 79: #include <stdarg.h>
1.1 deraadt 80: #include <stdio.h>
1.42 espie 81: #include <stdlib.h>
1.1 deraadt 82: #include <string.h>
1.41 espie 83: #include <unistd.h>
84: #include "config.h"
85: #include "defines.h"
1.1 deraadt 86: #include "job.h"
1.63 espie 87: #include "engine.h"
1.1 deraadt 88: #include "pathnames.h"
1.41 espie 89: #include "var.h"
90: #include "targ.h"
91: #include "error.h"
92: #include "lst.h"
93: #include "extern.h"
94: #include "gnode.h"
95: #include "memory.h"
96: #include "make.h"
97:
1.50 espie 98: /*
99: * The SEL_ constants determine the maximum amount of time spent in select
100: * before coming out to see if a child has finished. SEL_SEC is the number of
101: * seconds and SEL_USEC is the number of micro-seconds
102: */
103: #define SEL_SEC 0
104: #define SEL_USEC 500000
105:
106:
107: /*-
108: * Job Table definitions.
109: *
110: * Each job has several things associated with it:
111: * 1) The process id of the child shell
112: * 2) The graph node describing the target being made by this job
1.93 espie 113: * 3) An FILE* for writing out the commands. This is only
1.50 espie 114: * used before the job is actually started.
1.93 espie 115: * 4) Things used for handling the shell's output.
1.76 espie 116: * the output is being caught via a pipe and
1.50 espie 117: * the descriptors of our pipe, an array in which output is line
118: * buffered and the current position in that buffer are all
1.78 espie 119: * maintained for each job.
1.93 espie 120: * 5) A word of flags which determine how the module handles errors,
1.50 espie 121: * echoing, etc. for the job
122: *
123: * The job "table" is kept as a linked Lst in 'jobs', with the number of
124: * active jobs maintained in the 'nJobs' variable. At no time will this
125: * exceed the value of 'maxJobs', initialized by the Job_Init function.
126: *
127: * When a job is finished, the Make_Update function is called on each of the
128: * parents of the node which was just remade. This takes care of the upward
129: * traversal of the dependency graph.
130: */
131: #define JOB_BUFSIZE 1024
1.101 espie 132: struct job_pipe {
133: int fd;
134: char buffer[JOB_BUFSIZE];
135: size_t pos;
136: };
137:
1.50 espie 138: typedef struct Job_ {
1.51 mpech 139: pid_t pid; /* The child's process ID */
1.50 espie 140: GNode *node; /* The target the child is making */
141: short flags; /* Flags to control treatment of job */
1.83 espie 142: #define JOB_SPECIAL 0x004 /* Target is a special one. */
1.50 espie 143: #define JOB_RESTART 0x080 /* Job needs to be completely restarted */
1.79 espie 144: #define JOB_RESUME 0x100 /* Job needs to be resumed b/c it stopped,
145: * for some reason */
146: #define JOB_CONTINUING 0x200 /* We are in the process of resuming this job.
147: * Used to avoid infinite recursion between
148: * JobFinish and JobRestart */
1.111 espie 149: #define JOB_DIDOUTPUT 0x001
1.101 espie 150: struct job_pipe in[2];
1.50 espie 151: } Job;
152:
1.78 espie 153:
1.40 espie 154: static int aborting = 0; /* why is the make aborting? */
155: #define ABORT_ERROR 1 /* Because of an error */
156: #define ABORT_INTERRUPT 2 /* Because it was interrupted */
157: #define ABORT_WAIT 3 /* Waiting for jobs to finish */
1.1 deraadt 158:
1.40 espie 159: static int maxJobs; /* The most children we can run at once */
1.83 espie 160: static int nJobs; /* The number of children currently running */
1.95 espie 161: static LIST runningJobs; /* The structures that describe them */
1.79 espie 162: static bool jobFull; /* Flag to tell when the job table is full. It
1.83 espie 163: * is set true when nJobs equals maxJobs */
1.48 espie 164: static GNode *lastNode; /* The node for which output was most recently
1.1 deraadt 165: * produced. */
1.112 ! espie 166:
! 167: /* data structure linked to job handling through select */
! 168: static fd_set *output_mask = NULL; /* File descriptors to look for */
! 169:
! 170: static fd_set *actual_mask = NULL; /* actual select argument */
! 171: static int largest_fd = -1;
! 172: static size_t mask_size = 0;
! 173:
1.1 deraadt 174: /*
1.50 espie 175: * When JobStart attempts to run a job but isn't allowed to,
1.96 espie 176: * the job is placed on the queuedJobs queue to be run
1.6 millert 177: * when the next job finishes.
1.1 deraadt 178: */
1.96 espie 179: static LIST stoppedJobs;
180: static LIST queuedJobs;
1.112 ! espie 181:
! 182: /* wait possibilities */
! 183: #define JOB_EXITED 0
! 184: #define JOB_SIGNALED 1
! 185: #define JOB_CONTINUED 2
! 186: #define JOB_STOPPED 3
! 187: #define JOB_UNKNOWN 4
! 188:
1.101 espie 189: static LIST errorsList;
190: static int errors;
191: struct error_info {
1.112 ! espie 192: int reason;
! 193: int code;
1.111 espie 194: GNode *n;
1.101 espie 195: };
196:
1.1 deraadt 197:
198: #if defined(USE_PGRP) && defined(SYSV)
1.40 espie 199: # define KILL(pid, sig) killpg(-(pid), (sig))
1.1 deraadt 200: #else
201: # if defined(USE_PGRP)
1.2 deraadt 202: # define KILL(pid, sig) killpg((pid), (sig))
1.1 deraadt 203: # else
1.2 deraadt 204: # define KILL(pid, sig) kill((pid), (sig))
1.1 deraadt 205: # endif
206: #endif
207:
1.93 espie 208: static void pass_signal_to_job(void *, void *);
209: static void handle_all_signals(void);
210: static void handle_signal(int);
1.40 espie 211: static int JobCmpPid(void *, void *);
1.101 espie 212: static void JobFinish(Job *, int);
1.112 ! espie 213: static void finish_job(Job *, int, int);
1.101 espie 214: static void JobExec(Job *);
1.40 espie 215: static void JobRestart(Job *);
1.97 espie 216: static void JobStart(GNode *, int);
1.40 espie 217: static void JobInterrupt(int, int);
218: static void JobRestartJobs(void);
1.84 espie 219: static void debug_printf(const char *, ...);
1.98 espie 220: static Job *prepare_job(GNode *, int);
1.96 espie 221: static void start_queued_job(Job *);
1.105 espie 222: static void banner(Job *, FILE *);
1.112 ! espie 223:
! 224: /***
! 225: *** Input/output from jobs
! 226: ***/
! 227:
! 228: /* prepare_pipe(jp, &fd):
! 229: * set up pipe data structure (buffer and pos) corresponding to
! 230: * pointed fd, and prepare to watch for it.
! 231: */
! 232: static void prepare_pipe(struct job_pipe *, int *);
! 233:
! 234: /* close_job_pipes(j):
! 235: * handle final output from job, and close pipes properly
! 236: */
! 237: static void close_job_pipes(Job *);
! 238:
! 239:
! 240: static void handle_all_jobs_output(void);
! 241:
! 242: /* handle_job_output(job, n, finish):
! 243: * n = 0 or 1 (stdout/stderr), set finish to retrieve everything.
! 244: */
! 245: static void handle_job_output(Job *, int, bool);
! 246:
1.101 espie 247: static void print_partial_buffer(struct job_pipe *, Job *, FILE *, size_t);
248: static void print_partial_buffer_and_shift(struct job_pipe *, Job *, FILE *,
249: size_t);
250: static bool print_complete_lines(struct job_pipe *, Job *, FILE *, size_t);
1.112 ! espie 251:
! 252:
! 253: static void register_error(int, int, Job *);
1.111 espie 254: static void loop_handle_running_jobs(void);
255: static void Job_CatchChildren(void);
1.93 espie 256:
1.101 espie 257: static void
1.112 ! espie 258: register_error(int reason, int code, Job *job)
1.101 espie 259: {
260: struct error_info *p;
1.1 deraadt 261:
1.101 espie 262: errors++;
263: p = emalloc(sizeof(struct error_info));
1.112 ! espie 264: p->reason = reason;
! 265: p->code = code;
1.111 espie 266: p->n = job->node;
267: Lst_AtEnd(&errorsList, p);
1.101 espie 268: }
1.93 espie 269:
1.101 espie 270: void
271: print_errors()
1.88 espie 272: {
1.101 espie 273: LstNode ln;
274: struct error_info *p;
1.111 espie 275: const char *type;
1.88 espie 276:
1.101 espie 277: for (ln = Lst_First(&errorsList); ln != NULL; ln = Lst_Adv(ln)) {
278: p = (struct error_info *)Lst_Datum(ln);
1.112 ! espie 279: switch(p->reason) {
! 280: case JOB_EXITED:
1.111 espie 281: type = "Exit status";
1.112 ! espie 282: break;
! 283: case JOB_SIGNALED:
1.111 espie 284: type = "Received signal";
1.112 ! espie 285: break;
! 286: case JOB_STOPPED:
! 287: type = "Stopped";
! 288: break;
! 289: case JOB_CONTINUED:
! 290: type = "Continued";
! 291: break;
! 292: default:
! 293: type = "Should not happen";
! 294: break;
1.101 espie 295: }
1.111 espie 296: if (p->n->lineno)
297: Error(" %s %d (%s, line %lu of %s)",
1.112 ! espie 298: type, p->code, p->n->name, p->n->lineno, p->n->fname);
1.111 espie 299: else
1.112 ! espie 300: Error(" %s %d (%s)", type, p->code, p->n->name);
1.101 espie 301: }
1.88 espie 302: }
303:
1.57 espie 304: static void
1.105 espie 305: banner(Job *job, FILE *out)
1.57 espie 306: {
1.101 espie 307: if (job->node != lastNode) {
1.105 espie 308: if (DEBUG(JOBBANNER))
1.101 espie 309: (void)fprintf(out, "--- %s ---\n", job->node->name);
310: lastNode = job->node;
1.57 espie 311: }
312: }
313:
314: static void
1.93 espie 315: handle_all_signals()
1.57 espie 316: {
1.93 espie 317: if (got_signal)
318: got_signal = 0;
319: else
320: return;
321:
1.57 espie 322: if (got_SIGINT) {
323: got_SIGINT=0;
1.93 espie 324: handle_signal(SIGINT);
1.57 espie 325: }
326: if (got_SIGHUP) {
327: got_SIGHUP=0;
1.93 espie 328: handle_signal(SIGHUP);
1.57 espie 329: }
330: if (got_SIGQUIT) {
331: got_SIGQUIT=0;
1.93 espie 332: handle_signal(SIGQUIT);
1.57 espie 333: }
334: if (got_SIGTERM) {
335: got_SIGTERM=0;
1.93 espie 336: handle_signal(SIGTERM);
1.57 espie 337: }
338: if (got_SIGTSTP) {
339: got_SIGTSTP=0;
1.93 espie 340: handle_signal(SIGTSTP);
1.57 espie 341: }
342: if (got_SIGTTOU) {
343: got_SIGTTOU=0;
1.93 espie 344: handle_signal(SIGTTOU);
1.57 espie 345: }
346: if (got_SIGTTIN) {
347: got_SIGTTIN=0;
1.93 espie 348: handle_signal(SIGTTIN);
1.57 espie 349: }
350: if (got_SIGWINCH) {
351: got_SIGWINCH=0;
1.93 espie 352: handle_signal(SIGWINCH);
1.57 espie 353: }
354: }
355:
1.1 deraadt 356: /*-
357: *-----------------------------------------------------------------------
358: * JobCondPassSig --
1.50 espie 359: * Pass a signal to a job if USE_PGRP
1.1 deraadt 360: * is defined.
361: *
362: * Side Effects:
363: * None, except the job may bite it.
364: *-----------------------------------------------------------------------
365: */
1.27 espie 366: static void
1.93 espie 367: pass_signal_to_job(void *jobp, /* Job to biff */
1.56 espie 368: void *signop) /* Signal to send it */
1.1 deraadt 369: {
1.66 espie 370: Job *job = (Job *)jobp;
371: int signo = *(int *)signop;
372: if (DEBUG(JOB)) {
373: (void)fprintf(stdout,
1.93 espie 374: "pass_signal_to_job passing signal %d to child %ld.\n",
1.66 espie 375: signo, (long)job->pid);
376: (void)fflush(stdout);
377: }
378: KILL(job->pid, signo);
1.1 deraadt 379: }
380:
381: /*-
382: *-----------------------------------------------------------------------
1.94 espie 383: * handle_signal --
1.68 espie 384: * Pass a signal to all local jobs if USE_PGRP is defined,
1.50 espie 385: * then die ourselves.
1.1 deraadt 386: *
387: * Side Effects:
388: * We die by the same signal.
389: *-----------------------------------------------------------------------
390: */
391: static void
1.93 espie 392: handle_signal(int signo) /* The signal number we've received */
1.1 deraadt 393: {
1.66 espie 394: sigset_t nmask, omask;
395: struct sigaction act;
1.6 millert 396:
1.66 espie 397: if (DEBUG(JOB)) {
1.93 espie 398: (void)fprintf(stdout, "handle_signal(%d) called.\n", signo);
1.66 espie 399: (void)fflush(stdout);
400: }
1.95 espie 401: Lst_ForEach(&runningJobs, pass_signal_to_job, &signo);
1.66 espie 402:
403: /*
404: * Deal with proper cleanup based on the signal received. We only run
405: * the .INTERRUPT target if the signal was in fact an interrupt. The
406: * other three termination signals are more of a "get out *now*"
407: * command.
408: */
409: if (signo == SIGINT) {
410: JobInterrupt(true, signo);
411: } else if (signo == SIGHUP || signo == SIGTERM || signo == SIGQUIT) {
412: JobInterrupt(false, signo);
413: }
1.1 deraadt 414:
1.66 espie 415: /*
416: * Leave gracefully if SIGQUIT, rather than core dumping.
417: */
418: if (signo == SIGQUIT) {
419: Finish(0);
420: }
1.6 millert 421:
1.66 espie 422: /*
423: * Send ourselves the signal now we've given the message to everyone
424: * else. Note we block everything else possible while we're getting
425: * the signal. This ensures that all our jobs get continued when we
426: * wake up before we take any other signal.
427: */
428: sigemptyset(&nmask);
429: sigaddset(&nmask, signo);
430: sigprocmask(SIG_SETMASK, &nmask, &omask);
431: memset(&act, 0, sizeof act);
432: act.sa_handler = SIG_DFL;
433: sigemptyset(&act.sa_mask);
434: act.sa_flags = 0;
435: sigaction(signo, &act, NULL);
1.6 millert 436:
1.66 espie 437: if (DEBUG(JOB)) {
438: (void)fprintf(stdout,
1.93 espie 439: "handle_signal passing signal to self, mask = %x.\n",
1.66 espie 440: ~0 & ~(1 << (signo-1)));
441: (void)fflush(stdout);
442: }
443: (void)signal(signo, SIG_DFL);
1.1 deraadt 444:
1.66 espie 445: (void)KILL(getpid(), signo);
1.1 deraadt 446:
1.66 espie 447: signo = SIGCONT;
1.95 espie 448: Lst_ForEach(&runningJobs, pass_signal_to_job, &signo);
1.1 deraadt 449:
1.66 espie 450: (void)sigprocmask(SIG_SETMASK, &omask, NULL);
451: sigprocmask(SIG_SETMASK, &omask, NULL);
452: act.sa_handler = SigHandler;
453: sigaction(signo, &act, NULL);
1.1 deraadt 454: }
455:
456: /*-
457: *-----------------------------------------------------------------------
458: * JobCmpPid --
459: * Compare the pid of the job with the given pid and return 0 if they
460: * are equal. This function is called from Job_CatchChildren via
461: * Lst_Find to find the job descriptor of the finished job.
462: *
463: * Results:
464: * 0 if the pid's match
465: *-----------------------------------------------------------------------
466: */
467: static int
1.56 espie 468: JobCmpPid(void *job, /* job to examine */
469: void *pid) /* process id desired */
1.1 deraadt 470: {
1.66 espie 471: return *(pid_t *)pid - ((Job *)job)->pid;
1.1 deraadt 472: }
473:
1.69 espie 474: static void
1.84 espie 475: debug_printf(const char *fmt, ...)
476: {
477: if (DEBUG(JOB)) {
478: va_list va;
479:
480: va_start(va, fmt);
481: (void)vfprintf(stdout, fmt, va);
482: fflush(stdout);
483: va_end(va);
484: }
485: }
486:
1.2 deraadt 487: static void
1.112 ! espie 488: close_job_pipes(Job *job)
1.2 deraadt 489: {
1.101 espie 490: int i;
491:
1.112 ! espie 492: for (i = 1; i >= 0; i--) {
! 493: FD_CLR(job->in[i].fd, output_mask);
1.101 espie 494: handle_job_output(job, i, true);
495: (void)close(job->in[i].fd);
1.66 espie 496: }
1.1 deraadt 497: }
498:
499: /*-
500: *-----------------------------------------------------------------------
501: * JobFinish --
502: * Do final processing for the given job including updating
1.106 espie 503: * parents and starting new jobs as available/necessary.
1.1 deraadt 504: *
505: * Side Effects:
506: * Some nodes may be put on the toBeMade queue.
1.78 espie 507: * Final commands for the job are placed on end_node.
1.1 deraadt 508: *
1.6 millert 509: * If we got an error and are aborting (aborting == ABORT_ERROR) and
1.1 deraadt 510: * the job list is now empty, we are done for the day.
1.101 espie 511: * If we recognized an error we set the aborting flag
1.1 deraadt 512: * to ABORT_ERROR so no more jobs will be started.
513: *-----------------------------------------------------------------------
514: */
515: /*ARGSUSED*/
1.112 ! espie 516:
1.1 deraadt 517: static void
1.101 espie 518: JobFinish(Job *job, int status)
1.2 deraadt 519: {
1.112 ! espie 520: int reason, code;
! 521: /* parse status */
! 522: if (WIFEXITED(status)) {
! 523: reason = JOB_EXITED;
! 524: code = WEXITSTATUS(status);
! 525: } else if (WIFSIGNALED(status)) {
! 526: reason = JOB_SIGNALED;
! 527: code = WTERMSIG(status);
! 528: } else if (WIFCONTINUED(status)) {
! 529: reason = JOB_CONTINUED;
! 530: code = 0;
! 531: } else if (WIFSTOPPED(status)) {
! 532: reason = JOB_STOPPED;
! 533: code = WSTOPSIG(status);
! 534: } else {
! 535: /* can't happen, set things to be bad. */
! 536: reason = UNKNOWN;
! 537: code = status;
! 538: }
! 539: finish_job(job, reason, code);
! 540: }
! 541:
! 542:
! 543: static void
! 544: finish_job(Job *job, int reason, int code)
! 545: {
1.78 espie 546: bool done;
1.2 deraadt 547:
1.112 ! espie 548: if ((reason == JOB_EXITED &&
! 549: code != 0 && !(job->node->type & OP_IGNORE)) ||
! 550: (reason == JOB_SIGNALED && code != SIGCONT)) {
1.66 espie 551: /*
552: * If it exited non-zero and either we're doing things our
553: * way or we're not ignoring errors, the job is finished.
554: * Similarly, if the shell died because of a signal
555: * the job is also finished. In these
556: * cases, finish out the job's output before printing the exit
557: * status...
558: */
1.112 ! espie 559: close_job_pipes(job);
1.66 espie 560: done = true;
1.112 ! espie 561: } else if (reason == JOB_EXITED) {
1.66 espie 562: /*
563: * Deal with ignored errors in -B mode. We need to print a
564: * message telling of the ignored error as well as setting
565: * status.w_status to 0 so the next command gets run. To do
566: * this, we set done to be true if in -B mode and the job
567: * exited non-zero.
568: */
1.112 ! espie 569: done = code != 0;
1.66 espie 570: /*
571: * Old comment said: "Note we don't want to close down any of
572: * the streams until we know we're at the end." But we do.
573: * Otherwise when are we going to print the rest of the stuff?
574: */
1.112 ! espie 575: close_job_pipes(job);
1.66 espie 576: } else {
577: /*
578: * No need to close things down or anything.
579: */
580: done = false;
1.1 deraadt 581: }
1.6 millert 582:
1.112 ! espie 583: if (reason == JOB_STOPPED) {
! 584: debug_printf("Process %ld stopped.\n", (long)job->pid);
! 585: banner(job, stdout);
! 586: (void)fprintf(stdout, "*** Stopped -- signal %d\n",
! 587: code);
! 588: job->flags |= JOB_RESUME;
! 589: Lst_AtEnd(&stoppedJobs, job);
! 590: (void)fflush(stdout);
! 591: return;
! 592: }
! 593: if (reason == JOB_SIGNALED && code == SIGCONT) {
! 594: /*
! 595: * If the beastie has continued, shift the Job from the
! 596: * stopped list to the running one (or re-stop it if
! 597: * concurrency is exceeded) and go and get another
! 598: * child.
! 599: */
! 600: if (job->flags & (JOB_RESUME|JOB_RESTART)) {
! 601: banner(job, stdout);
! 602: (void)fprintf(stdout, "*** Continued\n");
! 603: }
! 604: if (!(job->flags & JOB_CONTINUING)) {
! 605: debug_printf(
! 606: "Warning: "
! 607: "process %ld was not continuing.\n",
! 608: (long)job->pid);
! 609: #if 0
! 610: /*
! 611: * We don't really want to restart a job from
! 612: * scratch just because it continued,
! 613: * especially not without killing the
! 614: * continuing process! That's why this is
! 615: * ifdef'ed out. FD - 9/17/90
! 616: */
! 617: JobRestart(job);
! 618: #endif
! 619: }
! 620: job->flags &= ~JOB_CONTINUING;
! 621: Lst_AtEnd(&runningJobs, job);
! 622: nJobs++;
! 623: debug_printf("Process %ld is continuing locally.\n",
! 624: (long)job->pid);
! 625: if (nJobs == maxJobs) {
! 626: jobFull = true;
! 627: debug_printf("Job queue is full.\n");
! 628: }
! 629: (void)fflush(stdout);
! 630: return;
! 631: }
! 632:
! 633: if (done || DEBUG(JOB)) {
! 634: if (reason == JOB_EXITED) {
1.84 espie 635: debug_printf("Process %ld exited.\n", (long)job->pid);
1.112 ! espie 636: if (code != 0) {
1.105 espie 637: banner(job, stdout);
1.111 espie 638: (void)fprintf(stdout, "*** Error code %d %s\n",
1.112 ! espie 639: code,
1.106 espie 640: (job->node->type & OP_IGNORE) ?
641: "(ignored)" : "");
1.66 espie 642:
1.106 espie 643: if (job->node->type & OP_IGNORE) {
1.112 ! espie 644: reason = JOB_EXITED;
! 645: code = 0;
1.66 espie 646: }
647: } else if (DEBUG(JOB)) {
1.105 espie 648: banner(job, stdout);
1.101 espie 649: (void)fprintf(stdout,
1.66 espie 650: "*** Completed successfully\n");
651: }
652: } else {
1.105 espie 653: banner(job, stdout);
1.112 ! espie 654: (void)fprintf(stdout, "*** Signal %d\n", code);
1.40 espie 655: }
1.66 espie 656:
1.101 espie 657: (void)fflush(stdout);
1.1 deraadt 658: }
659:
1.85 espie 660: done = true;
1.1 deraadt 661:
1.66 espie 662: if (done &&
663: aborting != ABORT_ERROR &&
664: aborting != ABORT_INTERRUPT &&
1.112 ! espie 665: reason == JOB_EXITED && code == 0) {
1.66 espie 666: /* As long as we aren't aborting and the job didn't return a
667: * non-zero status that we shouldn't ignore, we call
1.101 espie 668: * Make_Update to update the parents. */
1.108 espie 669: job->node->built_status = MADE;
1.66 espie 670: Make_Update(job->node);
671: free(job);
1.112 ! espie 672: } else if (!(reason == JOB_EXITED && code == 0)) {
! 673: register_error(reason, code, job);
1.66 espie 674: free(job);
675: }
1.1 deraadt 676:
677: /*
1.66 espie 678: * Set aborting if any error.
1.1 deraadt 679: */
1.101 espie 680: if (errors && !keepgoing &&
681: aborting != ABORT_INTERRUPT) {
1.66 espie 682: /*
683: * If we found any errors in this batch of children and the -k
684: * flag wasn't given, we set the aborting flag so no more jobs
685: * get started.
686: */
687: aborting = ABORT_ERROR;
688: }
1.6 millert 689:
1.111 espie 690: if (aborting != ABORT_ERROR)
691: JobRestartJobs();
692:
1.66 espie 693: if (aborting == ABORT_ERROR && Job_Empty()) {
694: /*
695: * If we are aborting and the job table is now empty, we finish.
696: */
697: Finish(errors);
698: }
1.1 deraadt 699: }
700:
1.101 espie 701: static void
702: prepare_pipe(struct job_pipe *p, int *fd)
703: {
704: p->pos = 0;
705: (void)fcntl(fd[0], F_SETFD, FD_CLOEXEC);
706: p->fd = fd[0];
707: close(fd[1]);
708:
1.112 ! espie 709: if (output_mask == NULL || p->fd > largest_fd) {
1.101 espie 710: int fdn, ofdn;
711:
712: fdn = howmany(p->fd+1, NFDBITS);
1.112 ! espie 713: ofdn = howmany(largest_fd+1, NFDBITS);
1.101 espie 714:
715: if (fdn != ofdn) {
1.112 ! espie 716: output_mask = erecalloc(output_mask, fdn,
! 717: sizeof(fd_mask));
! 718: actual_mask = erecalloc(actual_mask, fdn,
! 719: sizeof(fd_mask));
! 720: mask_size = fdn * sizeof(fd_mask);
1.101 espie 721: }
1.112 ! espie 722: largest_fd = p->fd;
1.101 espie 723: }
724: fcntl(p->fd, F_SETFL, O_NONBLOCK);
1.112 ! espie 725: FD_SET(p->fd, output_mask);
1.101 espie 726: }
727:
1.1 deraadt 728: /*-
729: *-----------------------------------------------------------------------
730: * JobExec --
731: * Execute the shell for the given job. Called from JobStart and
732: * JobRestart.
733: *
734: * Side Effects:
735: * A shell is executed, outputs is altered and the Job structure added
736: * to the job table.
737: *-----------------------------------------------------------------------
738: */
739: static void
1.101 espie 740: JobExec(Job *job)
1.1 deraadt 741: {
1.66 espie 742: pid_t cpid; /* ID of new child */
1.101 espie 743: int fds[4];
744: int *fdout = fds;
745: int *fderr = fds+2;
746: int result;
747: int i;
1.6 millert 748:
1.66 espie 749: if (DEBUG(JOB)) {
1.107 espie 750: LstNode ln;
751:
1.66 espie 752: (void)fprintf(stdout, "Running %s\n", job->node->name);
1.107 espie 753: for (ln = Lst_First(&job->node->commands); ln != NULL ;
754: ln = Lst_Adv(ln))
755: fprintf(stdout, "\t%s\n", (char *)Lst_Datum(ln));
1.66 espie 756: (void)fflush(stdout);
1.1 deraadt 757: }
1.6 millert 758:
1.66 espie 759: /*
760: * Some jobs produce no output and it's disconcerting to have
761: * no feedback of their running (since they produce no output, the
762: * banner with their name in it never appears). This is an attempt to
763: * provide that feedback, even if nothing follows it.
764: */
1.105 espie 765: banner(job, stdout);
1.101 espie 766:
767: setup_engine();
768:
769: /* Create the pipe by which we'll get the shell's output.
770: */
771: if (pipe(fdout) == -1)
772: Punt("Cannot create pipe: %s", strerror(errno));
1.1 deraadt 773:
1.101 espie 774: if (pipe(fderr) == -1)
775: Punt("Cannot create pipe: %s", strerror(errno));
1.94 espie 776:
1.66 espie 777: if ((cpid = fork()) == -1) {
778: Punt("Cannot fork");
779: } else if (cpid == 0) {
1.104 espie 780: supervise_jobs = false;
1.101 espie 781: /* standard pipe code to route stdout and stderr */
782: close(fdout[0]);
783: if (dup2(fdout[1], 1) == -1)
784: Punt("Cannot dup2(outPipe): %s", strerror(errno));
785: if (fdout[1] != 1)
786: close(fdout[1]);
787: close(fderr[0]);
788: if (dup2(fderr[1], 2) == -1)
789: Punt("Cannot dup2(errPipe): %s", strerror(errno));
790: if (fderr[1] != 2)
791: close(fderr[1]);
1.1 deraadt 792:
793: #ifdef USE_PGRP
1.66 espie 794: /*
795: * We want to switch the child into a different process family
796: * so we can kill it and all its descendants in one fell swoop,
797: * by killing its process family, but not commit suicide.
798: */
1.2 deraadt 799: # if defined(SYSV)
1.66 espie 800: (void)setsid();
1.2 deraadt 801: # else
1.66 espie 802: (void)setpgid(0, getpid());
1.2 deraadt 803: # endif
804: #endif /* USE_PGRP */
1.1 deraadt 805:
1.109 espie 806: if (random_delay)
1.110 espie 807: if (!(nJobs == 1 && no_jobs_left()))
808: usleep(random() % random_delay);
1.109 espie 809:
1.101 espie 810: /* most cases won't return, but will exit directly */
1.112 ! espie 811: result = run_prepared_gnode(job->node, 1);
1.101 espie 812: switch(result) {
813: case MADE:
814: exit(0);
815: case ERROR:
816: exit(1);
817: default:
818: fprintf(stderr,
819: "Could not run gnode, returned %d\n", result);
820: exit(1);
821: }
1.66 espie 822: } else {
1.104 espie 823: supervise_jobs = true;
1.66 espie 824: job->pid = cpid;
825:
1.101 espie 826: /* we set the current position in the buffers to the beginning
1.87 espie 827: * and mark another stream to watch in the outputs mask
828: */
1.101 espie 829: for (i = 0; i < 2; i++)
830: prepare_pipe(&job->in[i], fds+2*i);
1.1 deraadt 831: }
832:
1.48 espie 833: /*
1.66 espie 834: * Now the job is actually running, add it to the table.
1.48 espie 835: */
1.67 espie 836: nJobs++;
1.95 espie 837: Lst_AtEnd(&runningJobs, job);
1.66 espie 838: if (nJobs == maxJobs) {
839: jobFull = true;
1.1 deraadt 840: }
841: }
842:
1.96 espie 843: static void
844: start_queued_job(Job *job)
845: {
846: if (DEBUG(JOB)) {
847: (void)fprintf(stdout, "Restarting %s...",
848: job->node->name);
849: (void)fflush(stdout);
850: }
851: if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) {
852: /*
853: * Can't be exported and not allowed to run locally --
854: * put it back on the hold queue and mark the table
855: * full
856: */
857: debug_printf("holding\n");
858: Lst_AtFront(&stoppedJobs, job);
859: jobFull = true;
860: debug_printf("Job queue is full.\n");
861: return;
862: } else {
863: /*
864: * Job may be run locally.
865: */
866: debug_printf("running locally\n");
867: }
1.101 espie 868: JobExec(job);
1.96 espie 869: }
870:
1.1 deraadt 871: /*-
872: *-----------------------------------------------------------------------
873: * JobRestart --
1.6 millert 874: * Restart a job that stopped for some reason.
1.1 deraadt 875: *
876: * Side Effects:
877: * jobFull will be set if the job couldn't be run.
878: *-----------------------------------------------------------------------
879: */
880: static void
1.56 espie 881: JobRestart(Job *job)
1.1 deraadt 882: {
1.66 espie 883: if (job->flags & JOB_RESTART) {
1.96 espie 884: start_queued_job(job);
1.66 espie 885: } else {
1.1 deraadt 886: /*
1.66 espie 887: * The job has stopped and needs to be restarted. Why it
888: * stopped, we don't know...
1.1 deraadt 889: */
1.84 espie 890: debug_printf("Resuming %s...", job->node->name);
1.83 espie 891: if ((nJobs < maxJobs || ((job->flags & JOB_SPECIAL) &&
892: maxJobs == 0)) && nJobs != maxJobs) {
1.66 espie 893: /*
1.79 espie 894: * If we haven't reached the concurrency limit already
1.83 espie 895: * (or maxJobs is 0), it's ok to resume the job.
1.66 espie 896: */
897: bool error;
898:
899: error = KILL(job->pid, SIGCONT) != 0;
900:
901: if (!error) {
902: /*
903: * Make sure the user knows we've continued the
904: * beast and actually put the thing in the job
905: * table.
906: */
907: job->flags |= JOB_CONTINUING;
1.112 ! espie 908: finish_job(job, JOB_SIGNALED, SIGCONT);
1.66 espie 909:
910: job->flags &= ~(JOB_RESUME|JOB_CONTINUING);
1.84 espie 911: debug_printf("done\n");
1.66 espie 912: } else {
913: Error("couldn't resume %s: %s",
914: job->node->name, strerror(errno));
1.112 ! espie 915: finish_job(job, JOB_EXITED, 1);
1.66 espie 916: }
917: } else {
918: /*
919: * Job cannot be restarted. Mark the table as full and
920: * place the job back on the list of stopped jobs.
921: */
1.84 espie 922: debug_printf("table full\n");
1.66 espie 923: Lst_AtFront(&stoppedJobs, job);
924: jobFull = true;
1.84 espie 925: debug_printf("Job queue is full.\n");
1.1 deraadt 926: }
927: }
928: }
929:
1.98 espie 930: static Job *
931: prepare_job(GNode *gn, int flags)
1.78 espie 932: {
933: Job *job; /* new job descriptor */
934: bool cmdsOK; /* true if the nodes commands were all right */
935: bool noExec; /* Set true if we decide not to run the job */
1.66 espie 936:
1.86 espie 937: job = emalloc(sizeof(Job));
938: if (job == NULL) {
939: Punt("JobStart out of memory");
1.1 deraadt 940: }
941:
1.66 espie 942: job->node = gn;
1.1 deraadt 943:
944: /*
1.66 espie 945: * Set the initial value of the flags for this job based on the global
946: * ones and the node's attributes... Any flags supplied by the caller
947: * are also added to the field.
1.1 deraadt 948: */
1.87 espie 949: job->flags = flags;
1.6 millert 950:
1.1 deraadt 951: /*
1.66 espie 952: * Check the commands now so any attributes from .DEFAULT have a chance
953: * to migrate to the node
1.1 deraadt 954: */
1.87 espie 955: cmdsOK = Job_CheckCommands(gn, Error);
1.112 ! espie 956: expand_commands(gn);
1.1 deraadt 957:
1.66 espie 958: if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) {
959: /*
960: * We're serious here, but if the commands were bogus, we're
961: * also dead...
962: */
963: if (!cmdsOK) {
964: DieHorribly();
965: }
1.6 millert 966:
1.101 espie 967: if (Lst_IsEmpty(&gn->commands))
968: noExec = true;
969: else
970: noExec = false;
1.66 espie 971:
1.101 espie 972: } else if (noExecute) {
973: if (!cmdsOK || Lst_IsEmpty(&gn->commands))
1.85 espie 974: noExec = true;
1.101 espie 975: else
976: noExec = false;
1.66 espie 977: } else {
978: /*
979: * Just touch the target and note that no shell should be
1.101 espie 980: * executed. Check
1.66 espie 981: * the commands, too, but don't die if they're no good -- it
982: * does no harm to keep working up the graph.
1.30 espie 983: */
1.106 espie 984: Job_Touch(gn);
1.41 espie 985: noExec = true;
1.1 deraadt 986: }
1.66 espie 987:
1.1 deraadt 988: /*
1.66 espie 989: * If we're not supposed to execute a shell, don't.
1.1 deraadt 990: */
1.66 espie 991: if (noExec) {
992: /*
993: * We only want to work our way up the graph if we aren't here
994: * because the commands for the job were no good.
995: */
996: if (cmdsOK) {
997: if (aborting == 0) {
1.108 espie 998: job->node->built_status = MADE;
1.66 espie 999: Make_Update(job->node);
1000: }
1001: }
1.99 espie 1002: free(job);
1003: return NULL;
1.1 deraadt 1004: } else {
1.98 espie 1005: return job;
1.1 deraadt 1006: }
1.98 espie 1007: }
1.1 deraadt 1008:
1.98 espie 1009: /*-
1010: *-----------------------------------------------------------------------
1011: * JobStart --
1012: * Start a target-creation process going for the target described
1013: * by the graph node gn.
1014: *
1015: * Side Effects:
1016: * A new Job node is created and added to the list of running
1017: * jobs. PMake is forked and a child shell created.
1018: *-----------------------------------------------------------------------
1019: */
1020: static void
1021: JobStart(GNode *gn, /* target to create */
1022: int flags) /* flags for the job to override normal ones.
1023: * e.g. JOB_SPECIAL */
1024: {
1025: Job *job;
1026: job = prepare_job(gn, flags);
1027: if (!job)
1028: return;
1.83 espie 1029: if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) &&
1030: maxJobs != 0) {
1.79 espie 1031: /*
1032: * The job can only be run locally, but we've hit the limit of
1033: * local concurrency, so put the job on hold until some other
1034: * job finishes. Note that the special jobs (.BEGIN, .INTERRUPT
1035: * and .END) may be run locally even when the local limit has
1.83 espie 1036: * been reached (e.g. when maxJobs == 0), though they will be
1.79 espie 1037: * exported if at all possible. In addition, any target marked
1.83 espie 1038: * with .NOEXPORT will be run locally if maxJobs is 0.
1.66 espie 1039: */
1040: jobFull = true;
1.6 millert 1041:
1.84 espie 1042: debug_printf("Can only run job locally.\n");
1.66 espie 1043: job->flags |= JOB_RESTART;
1044: Lst_AtEnd(&stoppedJobs, job);
1.79 espie 1045: } else {
1.83 espie 1046: if (nJobs >= maxJobs) {
1.79 espie 1047: /*
1048: * If we're running this job locally as a special case
1049: * (see above), at least say the table is full.
1050: */
1051: jobFull = true;
1.84 espie 1052: debug_printf("Local job queue is full.\n");
1.79 espie 1053: }
1.101 espie 1054: JobExec(job);
1.1 deraadt 1055: }
1056: }
1057:
1.101 espie 1058: /* Helper functions for JobDoOutput */
1059:
1060:
1.105 espie 1061: /* output debugging banner and print characters from 0 to endpos */
1.101 espie 1062: static void
1063: print_partial_buffer(struct job_pipe *p, Job *job, FILE *out, size_t endPos)
1.2 deraadt 1064: {
1.101 espie 1065: size_t i;
1.2 deraadt 1066:
1.105 espie 1067: banner(job, out);
1.111 espie 1068: job->flags |= JOB_DIDOUTPUT;
1.101 espie 1069: for (i = 0; i < endPos; i++)
1070: putc(p->buffer[i], out);
1071: }
1072:
1073: /* print partial buffer and shift remaining contents */
1074: static void
1075: print_partial_buffer_and_shift(struct job_pipe *p, Job *job, FILE *out,
1076: size_t endPos)
1077: {
1078: size_t i;
1079:
1080: print_partial_buffer(p, job, out, endPos);
1081:
1082: for (i = endPos; i < p->pos; i++)
1083: p->buffer[i-endPos] = p->buffer[i];
1084: p->pos -= endPos;
1085: }
1086:
1087: /* print complete lines, looking back to the limit position
1088: * (stuff before limit was already scanned).
1089: * returns true if something was printed.
1090: */
1091: static bool
1092: print_complete_lines(struct job_pipe *p, Job *job, FILE *out, size_t limit)
1093: {
1094: size_t i;
1095:
1096: for (i = p->pos; i > limit; i--) {
1097: if (p->buffer[i-1] == '\n') {
1098: print_partial_buffer_and_shift(p, job, out, i);
1099: return true;
1.2 deraadt 1100: }
1101: }
1.101 espie 1102: return false;
1.2 deraadt 1103: }
1.111 espie 1104:
1.1 deraadt 1105: /*-
1106: *-----------------------------------------------------------------------
1.101 espie 1107: * handle_pipe --
1.89 espie 1108: * This functions is called whenever there is something to read on the
1109: * pipe. We collect more output from the given job and store it in the
1.101 espie 1110: * job's outBuf. If this makes up lines, we print it tagged by the job's
1.89 espie 1111: * identifier, as necessary.
1.1 deraadt 1112: *
1113: * Side Effects:
1114: * curPos may be shifted as may the contents of outBuf.
1115: *-----------------------------------------------------------------------
1116: */
1.48 espie 1117: static void
1.101 espie 1118: handle_pipe(struct job_pipe *p,
1119: Job *job, FILE *out, bool finish)
1.66 espie 1120: {
1121: int nr; /* number of bytes read */
1.101 espie 1122: int oldpos; /* optimization */
1.1 deraadt 1123:
1.101 espie 1124: /* want to get everything ? -> we block */
1125: if (finish)
1126: fcntl(p->fd, F_SETFL, 0);
1127:
1128: do {
1129: nr = read(p->fd, &p->buffer[p->pos],
1130: JOB_BUFSIZE - p->pos);
1131: if (nr == -1) {
1132: if (errno == EAGAIN)
1133: break;
1134: if (DEBUG(JOB)) {
1135: perror("JobDoOutput(piperead)");
1136: }
1.66 espie 1137: }
1.101 espie 1138: oldpos = p->pos;
1139: p->pos += nr;
1140: if (!print_complete_lines(p, job, out, oldpos))
1141: if (p->pos == JOB_BUFSIZE) {
1142: print_partial_buffer(p, job, out, p->pos);
1143: p->pos = 0;
1144: }
1145: } while (nr != 0);
1.1 deraadt 1146:
1.101 espie 1147: /* at end of file, we print whatever is left */
1148: if (nr == 0) {
1149: print_partial_buffer(p, job, out, p->pos);
1150: if (p->pos > 0 && p->buffer[p->pos - 1] != '\n')
1151: putchar('\n');
1152: p->pos = 0;
1.76 espie 1153: }
1.101 espie 1154: }
1.6 millert 1155:
1.101 espie 1156: static void
1157: handle_job_output(Job *job, int i, bool finish)
1158: {
1159: handle_pipe(&job->in[i], job, i == 0 ? stdout : stderr, finish);
1.1 deraadt 1160: }
1161:
1162: /*-
1163: *-----------------------------------------------------------------------
1164: * Job_CatchChildren --
1.111 espie 1165: * Handle the exit of a child. Called by handle_running_jobs
1.1 deraadt 1166: *
1167: * Side Effects:
1168: * The job descriptor is removed from the list of children.
1169: *
1170: * Notes:
1171: * We do waits, blocking or not, according to the wisdom of our
1172: * caller, until there are no more children to report. For each
1173: * job, call JobFinish to finish things off. This will take care of
1174: * putting jobs on the stoppedJobs queue.
1175: *-----------------------------------------------------------------------
1176: */
1177: void
1.76 espie 1178: Job_CatchChildren()
1.1 deraadt 1179: {
1.78 espie 1180: pid_t pid; /* pid of dead child */
1181: Job *job; /* job descriptor for dead child */
1182: LstNode jnode; /* list element for finding job */
1183: int status; /* Exit/termination status */
1.1 deraadt 1184:
1.66 espie 1185: /*
1186: * Don't even bother if we know there's no one around.
1187: */
1.112 ! espie 1188: if (nJobs == 0)
1.66 espie 1189: return;
1.6 millert 1190:
1.76 espie 1191: while ((pid = waitpid((pid_t) -1, &status, WNOHANG|WUNTRACED)) > 0) {
1.93 espie 1192: handle_all_signals();
1.84 espie 1193: debug_printf("Process %ld exited or stopped.\n", (long)pid);
1.1 deraadt 1194:
1.95 espie 1195: jnode = Lst_Find(&runningJobs, JobCmpPid, &pid);
1.1 deraadt 1196:
1.18 espie 1197: if (jnode == NULL) {
1.68 espie 1198: if (WIFSIGNALED(status) &&
1.66 espie 1199: (WTERMSIG(status) == SIGCONT)) {
1200: jnode = Lst_Find(&stoppedJobs, JobCmpPid, &pid);
1201: if (jnode == NULL) {
1202: Error("Resumed child (%ld) not in table", (long)pid);
1203: continue;
1204: }
1205: job = (Job *)Lst_Datum(jnode);
1206: Lst_Remove(&stoppedJobs, jnode);
1207: } else {
1208: Error("Child (%ld) not in table?", (long)pid);
1209: continue;
1210: }
1211: } else {
1212: job = (Job *)Lst_Datum(jnode);
1.95 espie 1213: Lst_Remove(&runningJobs, jnode);
1.67 espie 1214: nJobs--;
1.84 espie 1215: if (jobFull)
1216: debug_printf("Job queue is no longer full.\n");
1.66 espie 1217: jobFull = false;
1.1 deraadt 1218: }
1.66 espie 1219:
1.101 espie 1220: JobFinish(job, status);
1.1 deraadt 1221: }
1222: }
1223:
1224: void
1.112 ! espie 1225: handle_all_jobs_output(void)
1.1 deraadt 1226: {
1.66 espie 1227: int nfds;
1228: struct timeval timeout;
1.111 espie 1229: LstNode ln, ln2;
1.66 espie 1230: Job *job;
1.101 espie 1231: int i;
1.111 espie 1232: int status;
1.66 espie 1233:
1.112 ! espie 1234: /* no jobs */
! 1235: if (Lst_IsEmpty(&runningJobs))
! 1236: return;
1.91 espie 1237:
1.77 espie 1238: (void)fflush(stdout);
1.76 espie 1239:
1.112 ! espie 1240: memcpy(actual_mask, output_mask, mask_size);
1.76 espie 1241: timeout.tv_sec = SEL_SEC;
1242: timeout.tv_usec = SEL_USEC;
1.66 espie 1243:
1.112 ! espie 1244: nfds = select(largest_fd+1, actual_mask, NULL, NULL, &timeout);
1.93 espie 1245: handle_all_signals();
1.111 espie 1246: for (ln = Lst_First(&runningJobs); nfds && ln != NULL;
1247: ln = ln2) {
1248: ln2 = Lst_Adv(ln);
1249: job = (Job *)Lst_Datum(ln);
1250: job->flags &= ~JOB_DIDOUTPUT;
1251: for (i = 1; i >= 0; i--) {
1.112 ! espie 1252: if (FD_ISSET(job->in[i].fd, actual_mask)) {
1.111 espie 1253: nfds--;
1254: handle_job_output(job, i, false);
1255: }
1256: }
1257: if (job->flags & JOB_DIDOUTPUT) {
1258: if (wait4(job->pid, &status, WNOHANG|WUNTRACED, NULL) ==
1259: job->pid) {
1260: Lst_Remove(&runningJobs, ln);
1261: nJobs--;
1262: jobFull = false;
1263: JobFinish(job, status);
1264: } else {
1265: Lst_Requeue(&runningJobs, ln);
1.66 espie 1266: }
1.1 deraadt 1267: }
1268: }
1269: }
1270:
1.111 espie 1271: void
1272: handle_running_jobs()
1273: {
1.112 ! espie 1274: handle_all_jobs_output();
1.111 espie 1275: Job_CatchChildren();
1276: }
1277:
1278: static void
1279: loop_handle_running_jobs()
1280: {
1281: while (nJobs)
1282: handle_running_jobs();
1283: }
1.1 deraadt 1284: /*-
1285: *-----------------------------------------------------------------------
1286: * Job_Make --
1287: * Start the creation of a target. Basically a front-end for
1288: * JobStart used by the Make module.
1289: *
1290: * Side Effects:
1291: * Another job is started.
1292: *-----------------------------------------------------------------------
1293: */
1294: void
1.56 espie 1295: Job_Make(GNode *gn)
1.1 deraadt 1296: {
1.86 espie 1297: (void)JobStart(gn, 0);
1.1 deraadt 1298: }
1299:
1300: /*-
1301: *-----------------------------------------------------------------------
1302: * Job_Init --
1303: * Initialize the process module
1304: *
1305: * Side Effects:
1306: * lists and counters are initialized
1307: *-----------------------------------------------------------------------
1308: */
1309: void
1.83 espie 1310: Job_Init(int maxproc)
1.1 deraadt 1311: {
1.95 espie 1312: Static_Lst_Init(&runningJobs);
1.66 espie 1313: Static_Lst_Init(&stoppedJobs);
1.96 espie 1314: Static_Lst_Init(&queuedJobs);
1.101 espie 1315: Static_Lst_Init(&errorsList);
1.66 espie 1316: maxJobs = maxproc;
1.79 espie 1317: nJobs = 0;
1.66 espie 1318: jobFull = false;
1.101 espie 1319: errors = 0;
1.66 espie 1320:
1321: aborting = 0;
1.40 espie 1322:
1.66 espie 1323: lastNode = NULL;
1.1 deraadt 1324:
1.78 espie 1325: if ((begin_node->type & OP_DUMMY) == 0) {
1.86 espie 1326: JobStart(begin_node, JOB_SPECIAL);
1.111 espie 1327: loop_handle_running_jobs();
1.1 deraadt 1328: }
1329: }
1330:
1331: /*-
1332: *-----------------------------------------------------------------------
1333: * Job_Full --
1334: * See if the job table is full. It is considered full if it is OR
1335: * if we are in the process of aborting OR if we have
1336: * reached/exceeded our local quota. This prevents any more jobs
1337: * from starting up.
1338: *
1339: * Results:
1.41 espie 1340: * true if the job table is full, false otherwise
1.1 deraadt 1341: *-----------------------------------------------------------------------
1342: */
1.41 espie 1343: bool
1.56 espie 1344: Job_Full(void)
1.1 deraadt 1345: {
1.66 espie 1346: return aborting || jobFull;
1.1 deraadt 1347: }
1348:
1349: /*-
1350: *-----------------------------------------------------------------------
1351: * Job_Empty --
1.40 espie 1352: * See if the job table is empty. Because the local concurrency may
1.1 deraadt 1353: * be set to 0, it is possible for the job table to become empty,
1354: * while the list of stoppedJobs remains non-empty. In such a case,
1355: * we want to restart as many jobs as we can.
1356: *
1357: * Results:
1.41 espie 1358: * true if it is. false if it ain't.
1.1 deraadt 1359: * -----------------------------------------------------------------------
1360: */
1.41 espie 1361: bool
1.56 espie 1362: Job_Empty(void)
1.1 deraadt 1363: {
1.66 espie 1364: if (nJobs == 0) {
1365: if (!Lst_IsEmpty(&stoppedJobs) && !aborting) {
1366: /*
1367: * The job table is obviously not full if it has no
1368: * jobs in it...Try and restart the stopped jobs.
1369: */
1370: jobFull = false;
1371: JobRestartJobs();
1372: return false;
1373: } else {
1374: return true;
1375: }
1.1 deraadt 1376: } else {
1.66 espie 1377: return false;
1.1 deraadt 1378: }
1379: }
1380:
1381: /*-
1382: *-----------------------------------------------------------------------
1383: * JobInterrupt --
1384: * Handle the receipt of an interrupt.
1385: *
1386: * Side Effects:
1387: * All children are killed. Another job will be started if the
1388: * .INTERRUPT target was given.
1389: *-----------------------------------------------------------------------
1390: */
1391: static void
1.56 espie 1392: JobInterrupt(int runINTERRUPT, /* Non-zero if commands for the .INTERRUPT
1.1 deraadt 1393: * target should be executed */
1.66 espie 1394: int signo) /* signal received */
1.1 deraadt 1395: {
1.66 espie 1396: LstNode ln; /* element in job table */
1.78 espie 1397: Job *job; /* job descriptor in that element */
1.66 espie 1398:
1399: aborting = ABORT_INTERRUPT;
1400:
1.95 espie 1401: for (ln = Lst_First(&runningJobs); ln != NULL; ln = Lst_Adv(ln)) {
1.66 espie 1402: job = (Job *)Lst_Datum(ln);
1403:
1404: if (!Targ_Precious(job->node)) {
1405: const char *file = job->node->path == NULL ?
1406: job->node->name : job->node->path;
1407: if (!noExecute && eunlink(file) != -1) {
1408: Error("*** %s removed", file);
1409: }
1410: }
1411: if (job->pid) {
1.84 espie 1412: debug_printf("JobInterrupt passing signal to "
1413: "child %ld.\n", (long)job->pid);
1.66 espie 1414: KILL(job->pid, signo);
1415: }
1.2 deraadt 1416: }
1.1 deraadt 1417:
1.66 espie 1418: if (runINTERRUPT && !touchFlag) {
1.78 espie 1419: if ((interrupt_node->type & OP_DUMMY) == 0) {
1.66 espie 1420: ignoreErrors = false;
1421:
1.101 espie 1422: JobStart(interrupt_node, 0);
1.111 espie 1423: loop_handle_running_jobs();
1.66 espie 1424: }
1.1 deraadt 1425: }
1.66 espie 1426: exit(signo);
1.1 deraadt 1427: }
1428:
1429: /*
1430: *-----------------------------------------------------------------------
1.12 espie 1431: * Job_Finish --
1.1 deraadt 1432: * Do final processing such as the running of the commands
1.6 millert 1433: * attached to the .END target.
1.1 deraadt 1434: *
1435: * Results:
1436: * Number of errors reported.
1.40 espie 1437: *
1.1 deraadt 1438: *-----------------------------------------------------------------------
1439: */
1440: int
1.56 espie 1441: Job_Finish(void)
1.1 deraadt 1442: {
1.78 espie 1443: if (end_node != NULL && !Lst_IsEmpty(&end_node->commands)) {
1.66 espie 1444: if (errors) {
1445: Error("Errors reported so .END ignored");
1446: } else {
1.101 espie 1447: JobStart(end_node, JOB_SPECIAL);
1.111 espie 1448: loop_handle_running_jobs();
1.66 espie 1449: }
1.1 deraadt 1450: }
1.66 espie 1451: return errors;
1.1 deraadt 1452: }
1453:
1.41 espie 1454: #ifdef CLEANUP
1.12 espie 1455: void
1.56 espie 1456: Job_End(void)
1.12 espie 1457: {
1.41 espie 1458: }
1.13 espie 1459: #endif
1.40 espie 1460:
1.1 deraadt 1461: /*-
1462: *-----------------------------------------------------------------------
1463: * Job_Wait --
1464: * Waits for all running jobs to finish and returns. Sets 'aborting'
1465: * to ABORT_WAIT to prevent other jobs from starting.
1466: *
1467: * Side Effects:
1468: * Currently running jobs finish.
1469: *
1470: *-----------------------------------------------------------------------
1471: */
1472: void
1.56 espie 1473: Job_Wait(void)
1.1 deraadt 1474: {
1.66 espie 1475: aborting = ABORT_WAIT;
1.111 espie 1476: loop_handle_running_jobs();
1.66 espie 1477: aborting = 0;
1.1 deraadt 1478: }
1479:
1480: /*-
1481: *-----------------------------------------------------------------------
1482: * Job_AbortAll --
1483: * Abort all currently running jobs without handling output or anything.
1484: * This function is to be called only in the event of a major
1485: * error. Most definitely NOT to be called from JobInterrupt.
1486: *
1487: * Side Effects:
1488: * All children are killed, not just the firstborn
1489: *-----------------------------------------------------------------------
1490: */
1491: void
1.56 espie 1492: Job_AbortAll(void)
1.1 deraadt 1493: {
1.66 espie 1494: LstNode ln; /* element in job table */
1495: Job *job; /* the job descriptor in that element */
1496: int foo;
1.6 millert 1497:
1.66 espie 1498: aborting = ABORT_ERROR;
1.6 millert 1499:
1.66 espie 1500: if (nJobs) {
1.95 espie 1501: for (ln = Lst_First(&runningJobs); ln != NULL;
1502: ln = Lst_Adv(ln)) {
1.66 espie 1503: job = (Job *)Lst_Datum(ln);
1504:
1505: /*
1506: * kill the child process with increasingly drastic
1507: * signals to make darn sure it's dead.
1508: */
1509: KILL(job->pid, SIGINT);
1510: KILL(job->pid, SIGKILL);
1511: }
1.1 deraadt 1512: }
1.6 millert 1513:
1.66 espie 1514: /*
1515: * Catch as many children as want to report in at first, then give up
1516: */
1517: while (waitpid(-1, &foo, WNOHANG) > 0)
1518: continue;
1.2 deraadt 1519: }
1.40 espie 1520:
1.2 deraadt 1521: /*-
1522: *-----------------------------------------------------------------------
1523: * JobRestartJobs --
1524: * Tries to restart stopped jobs if there are slots available.
1525: * Note that this tries to restart them regardless of pending errors.
1526: * It's not good to leave stopped jobs lying around!
1527: *
1528: * Side Effects:
1529: * Resumes(and possibly migrates) jobs.
1530: *-----------------------------------------------------------------------
1531: */
1532: static void
1.56 espie 1533: JobRestartJobs(void)
1.2 deraadt 1534: {
1.66 espie 1535: Job *job;
1.19 espie 1536:
1.111 espie 1537: while (!Job_Full() &&
1538: (job = (Job *)Lst_DeQueue(&stoppedJobs)) != NULL) {
1.84 espie 1539: debug_printf("Job queue is not full. "
1540: "Restarting a stopped job.\n");
1.66 espie 1541: JobRestart(job);
1.2 deraadt 1542: }
1.1 deraadt 1543: }