diff options
Diffstat (limited to 'usr.bin/make/job.c')
| -rw-r--r-- | usr.bin/make/job.c | 1657 |
1 files changed, 607 insertions, 1050 deletions
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c index 89a7e1b8bd659..166fd974797aa 100644 --- a/usr.bin/make/job.c +++ b/usr.bin/make/job.c @@ -1,8 +1,6 @@ -/* $NetBSD: job.c,v 1.15 1996/05/29 15:28:05 christos Exp $ */ - /* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor + * Copyright (c) 1988, 1989, 1990, 1993 + * The Regents of the University of California. All rights reserved. * Copyright (c) 1989 by Berkeley Softworks * All rights reserved. * @@ -39,11 +37,7 @@ */ #ifndef lint -#if 0 -static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; -#else -static char rcsid[] = "$NetBSD: job.c,v 1.15 1996/05/29 15:28:05 christos Exp $"; -#endif +static char sccsid[] = "@(#)job.c 8.3 (Berkeley) 4/28/95"; #endif /* not lint */ /*- @@ -103,13 +97,13 @@ static char rcsid[] = "$NetBSD: job.c,v 1.15 1996/05/29 15:28:05 christos Exp $" */ #include <sys/types.h> +#include <sys/signal.h> #include <sys/stat.h> #include <sys/file.h> #include <sys/time.h> #include <sys/wait.h> #include <fcntl.h> #include <errno.h> -#include <utime.h> #include <stdio.h> #include <string.h> #include <signal.h> @@ -118,17 +112,11 @@ static char rcsid[] = "$NetBSD: job.c,v 1.15 1996/05/29 15:28:05 christos Exp $" #include "dir.h" #include "job.h" #include "pathnames.h" -#ifdef REMOTE -#include "rmt.h" -# define STATIC -#else -# define STATIC static -#endif extern int errno; /* - * error handling variables + * error handling variables */ static int errors = 0; /* number of errors reported */ static int aborting = 0; /* why is the make aborting? */ @@ -136,11 +124,6 @@ static int aborting = 0; /* why is the make aborting? */ #define ABORT_INTERRUPT 2 /* Because it was interrupted */ #define ABORT_WAIT 3 /* Waiting for jobs to finish */ -/* - * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file - * is a char! So when we go above 127 we turn negative! - */ -#define FILENO(a) ((unsigned) fileno(a)) /* * post-make command processing. The node postCommands is really just the @@ -153,6 +136,7 @@ static int numCommands; /* The number of commands actually printed * for a target. Should this number be * 0, no shell will be executed. */ + /* * Return values from JobStart. */ @@ -165,7 +149,7 @@ static int numCommands; /* The number of commands actually printed * tfile is the name of a file into which all shell commands are put. It is * used over by removing it before the child shell is executed. The XXXXX in * the string are replaced by the pid of the make process in a 5-character - * field with leading zeroes. + * field with leading zeroes. */ static char tfile[] = TMPPAT; @@ -192,20 +176,17 @@ static Shell shells[] = { { "sh", TRUE, "set -", "set -v", "set -", 5, - TRUE, "set -e", "set +e", -#ifdef OLDBOURNESHELL FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n", -#endif "v", "e", }, /* * UNKNOWN. */ { - (char *) 0, - FALSE, (char *) 0, (char *) 0, (char *) 0, 0, - FALSE, (char *) 0, (char *) 0, - (char *) 0, (char *) 0, + (char *)0, + FALSE, (char *)0, (char *)0, (char *)0, 0, + FALSE, (char *)0, (char *)0, + (char *)0, (char *)0, } }; static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to @@ -213,17 +194,17 @@ static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to * commands in the Makefile. * It is set by the * Job_ParseShell function */ -static char *shellPath = NULL, /* full pathname of +static char *shellPath = (char *) NULL, /* full pathname of * executable image */ *shellName; /* last component of shell */ static int maxJobs; /* The most children we can run at once */ static int maxLocal; /* The most local ones we can have */ -STATIC int nJobs; /* The number of children currently running */ -STATIC int nLocal; /* The number of local children */ -STATIC Lst jobs; /* The structures that describe them */ -STATIC Boolean jobFull; /* Flag to tell when the job table is full. It +int nJobs; /* The number of children currently running */ +int nLocal; /* The number of local children */ +Lst jobs; /* The structures that describe them */ +Boolean jobFull; /* Flag to tell when the job table is full. It * is set TRUE when (1) the total number of * running jobs equals the maximum allowed or * (2) a job can only be run locally, but @@ -233,86 +214,47 @@ static fd_set outputs; /* Set of descriptors of pipes connected to * the output channels of children */ #endif -STATIC GNode *lastNode; /* The node for which output was most recently +GNode *lastNode; /* The node for which output was most recently * produced. */ -STATIC char *targFmt; /* Format string to use to head output from a +char *targFmt; /* Format string to use to head output from a * job when it's not the most-recent job heard * from */ - -#ifdef REMOTE -# define TARG_FMT "--- %s at %s ---\n" /* Default format */ -# define MESSAGE(fp, gn) \ - (void) fprintf(fp, targFmt, gn->name, gn->rem.hname); -#else -# define TARG_FMT "--- %s ---\n" /* Default format */ -# define MESSAGE(fp, gn) \ - (void) fprintf(fp, targFmt, gn->name); -#endif +#define TARG_FMT "--- %s ---\n" /* Default format */ /* * When JobStart attempts to run a job remotely but can't, and isn't allowed * to run the job locally, or when Job_CatchChildren detects a job that has * been migrated home, the job is placed on the stoppedJobs queue to be run - * when the next job finishes. + * when the next job finishes. */ -STATIC Lst stoppedJobs; /* Lst of Job structures describing +Lst stoppedJobs; /* Lst of Job structures describing * jobs that were stopped due to concurrency * limits or migration home */ #if defined(USE_PGRP) && defined(SYSV) -# define KILL(pid, sig) killpg(-(pid), (sig)) +#define KILL(pid,sig) killpg (-(pid),(sig)) #else # if defined(USE_PGRP) -# define KILL(pid, sig) killpg((pid), (sig)) +#define KILL(pid,sig) killpg ((pid),(sig)) # else -# define KILL(pid, sig) kill((pid), (sig)) +#define KILL(pid,sig) kill ((pid),(sig)) # endif #endif -/* - * Grmpf... There is no way to set bits of the wait structure - * anymore with the stupid W*() macros. I liked the union wait - * stuff much more. So, we devise our own macros... This is - * really ugly, use dramamine sparingly. You have been warned. - */ -#define W_SETMASKED(st, val, fun) \ - { \ - int sh = (int) ~0; \ - int mask = fun(sh); \ - \ - for (sh = 0; ((mask >> sh) & 1) == 0; sh++) \ - continue; \ - *(st) = (*(st) & ~mask) | ((val) << sh); \ - } - -#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG) -#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS) - - static int JobCondPassSig __P((ClientData, ClientData)); static void JobPassSig __P((int)); static int JobCmpPid __P((ClientData, ClientData)); static int JobPrintCommand __P((ClientData, ClientData)); static int JobSaveCommand __P((ClientData, ClientData)); -static void JobClose __P((Job *)); -#ifdef REMOTE -static int JobCmpRmtID __P((Job *, int)); -# ifdef RMT_WILL_WATCH -static void JobLocalInput __P((int, Job *)); -# endif -#else -static void JobFinish __P((Job *, int *)); +static void JobFinish __P((Job *, union wait)); static void JobExec __P((Job *, char **)); -#endif static void JobMakeArgv __P((Job *, char **)); static void JobRestart __P((Job *)); static int JobStart __P((GNode *, int, Job *)); -static char *JobOutput __P((Job *, char *, char *, int)); static void JobDoOutput __P((Job *, Boolean)); static Shell *JobMatchShell __P((char *)); -static void JobInterrupt __P((int, int)); -static void JobRestartJobs __P((void)); +static void JobInterrupt __P((int)); /*- *----------------------------------------------------------------------- @@ -337,7 +279,7 @@ JobCondPassSig(jobp, signop) int signo = *(int *) signop; #ifdef RMT_WANTS_SIGNALS if (job->flags & JOB_REMOTE) { - (void) Rmt_Signal(job, signo); + (void)Rmt_Signal(job, signo); } else { KILL(job->pid, signo); } @@ -346,15 +288,9 @@ JobCondPassSig(jobp, signop) * Assume that sending the signal to job->pid will signal any remote * job as well. */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobCondPassSig passing signal %d to child %d.\n", - signo, job->pid); - (void) fflush(stdout); - } KILL(job->pid, signo); #endif - return 0; + return(0); } /*- @@ -368,21 +304,16 @@ JobCondPassSig(jobp, signop) * * Side Effects: * We die by the same signal. - * + * *----------------------------------------------------------------------- */ static void JobPassSig(signo) int signo; /* The signal number we've received */ { - sigset_t nmask, omask; - struct sigaction act; - - if (DEBUG(JOB)) { - (void) fprintf(stdout, "JobPassSig(%d) called.\n", signo); - (void) fflush(stdout); - } - Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo); + int mask; + + Lst_ForEach(jobs, JobCondPassSig, (ClientData)(long)signo); /* * Deal with proper cleanup based on the signal received. We only run @@ -390,49 +321,36 @@ JobPassSig(signo) * three termination signals are more of a "get out *now*" command. */ if (signo == SIGINT) { - JobInterrupt(TRUE, signo); + JobInterrupt(TRUE); } else if ((signo == SIGHUP) || (signo == SIGTERM) || (signo == SIGQUIT)) { - JobInterrupt(FALSE, signo); + JobInterrupt(FALSE); } - + /* * Leave gracefully if SIGQUIT, rather than core dumping. */ if (signo == SIGQUIT) { Finish(0); } - + /* * Send ourselves the signal now we've given the message to everyone else. * Note we block everything else possible while we're getting the signal. * This ensures that all our jobs get continued when we wake up before * we take any other signal. */ - sigemptyset(&nmask); - sigaddset(&nmask, signo); - sigprocmask(SIG_SETMASK, &nmask, &omask); - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - sigaction(signo, &act, NULL); - - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobPassSig passing signal to self, mask = %x.\n", - ~0 & ~(1 << (signo-1))); - (void) fflush(stdout); - } - (void) signal(signo, SIG_DFL); + mask = sigblock(0); + (void) sigsetmask(~0 & ~(1 << (signo-1))); + signal(signo, SIG_DFL); - (void) KILL(getpid(), signo); + kill(getpid(), signo); signo = SIGCONT; Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo); - (void) sigprocmask(SIG_SETMASK, &omask, NULL); - sigprocmask(SIG_SETMASK, &omask, NULL); - act.sa_handler = JobPassSig; - sigaction(signo, &act, NULL); + sigsetmask(mask); + signal(signo, JobPassSig); + } /*- @@ -450,36 +368,13 @@ JobPassSig(signo) *----------------------------------------------------------------------- */ static int -JobCmpPid(job, pid) +JobCmpPid (job, pid) ClientData job; /* job to examine */ ClientData pid; /* process id desired */ { - return *(int *) pid - ((Job *) job)->pid; + return ( *(int *) pid - ((Job *) job)->pid); } -#ifdef REMOTE -/*- - *----------------------------------------------------------------------- - * JobCmpRmtID -- - * Compare the rmtID of the job with the given rmtID and return 0 if they - * are equal. - * - * Results: - * 0 if the rmtID's match - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static int -JobCmpRmtID(job, rmtID) - ClientData job; /* job to examine */ - ClientData rmtID; /* remote id desired */ -{ - return(*(int *) rmtID - *(int *) job->rmtID); -} -#endif - /*- *----------------------------------------------------------------------- * JobPrintCommand -- @@ -508,7 +403,7 @@ JobCmpRmtID(job, rmtID) *----------------------------------------------------------------------- */ static int -JobPrintCommand(cmdp, jobp) +JobPrintCommand (cmdp, jobp) ClientData cmdp; /* command string to print */ ClientData jobp; /* job for which to print it */ { @@ -525,26 +420,21 @@ JobPrintCommand(cmdp, jobp) char *cmdStart; /* Start of expanded command */ LstNode cmdNode; /* Node for replacing the command */ char *cmd = (char *) cmdp; - Job *job = (Job *) jobp; + Job *job = (Job *) jobp; - noSpecials = (noExecute && !(job->node->type & OP_MAKE)); + noSpecials = (noExecute && ! (job->node->type & OP_MAKE)); - if (strcmp(cmd, "...") == 0) { - job->node->type |= OP_SAVE_CMDS; + if (strcmp (cmd, "...") == 0) { + job->node->type |= OP_SAVE_CMDS; if ((job->flags & JOB_IGNDOTS) == 0) { - job->tailCmds = Lst_Succ(Lst_Member(job->node->commands, - (ClientData)cmd)); - return 1; + job->tailCmds = Lst_Succ (Lst_Member (job->node->commands, + (ClientData)cmd)); + return (1); } - return 0; + return (0); } -#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ - (void) fprintf(stdout, fmt, arg); \ - (void) fflush(stdout); \ - } \ - (void) fprintf(job->cmdFILE, fmt, arg); \ - (void) fflush(job->cmdFILE); +#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) printf (fmt, arg); fprintf (job->cmdFILE, fmt, arg) numCommands += 1; @@ -552,9 +442,9 @@ JobPrintCommand(cmdp, jobp) * For debugging, we replace each command with the result of expanding * the variables in the command. */ - cmdNode = Lst_Member(job->node->commands, (ClientData)cmd); - cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE); - Lst_Replace(cmdNode, (ClientData)cmdStart); + cmdNode = Lst_Member (job->node->commands, (ClientData)cmd); + cmdStart = cmd = Var_Subst (NULL, cmd, job->node, FALSE); + Lst_Replace (cmdNode, (ClientData)cmdStart); cmdTemplate = "%s\n"; @@ -574,16 +464,16 @@ JobPrintCommand(cmdp, jobp) cmd++; if (shutUp) { - if (!(job->flags & JOB_SILENT) && !noSpecials && + if (! (job->flags & JOB_SILENT) && !noSpecials && commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); + DBPRINTF ("%s\n", commandShell->echoOff); } else { shutUp = FALSE; } } if (errOff) { - if ( !(job->flags & JOB_IGNERR) && !noSpecials) { + if ( ! (job->flags & JOB_IGNERR) && !noSpecials) { if (commandShell->hasErrCtl) { /* * we don't want the error-control commands showing @@ -593,16 +483,16 @@ JobPrintCommand(cmdp, jobp) * string too, but why make it any more complex than * it already is? */ - if (!(job->flags & JOB_SILENT) && !shutUp && + if (! (job->flags & JOB_SILENT) && !shutUp && commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - DBPRINTF("%s\n", commandShell->ignErr); - DBPRINTF("%s\n", commandShell->echoOn); + DBPRINTF ("%s\n", commandShell->echoOff); + DBPRINTF ("%s\n", commandShell->ignErr); + DBPRINTF ("%s\n", commandShell->echoOn); } else { - DBPRINTF("%s\n", commandShell->ignErr); + DBPRINTF ("%s\n", commandShell->ignErr); } } else if (commandShell->ignErr && - (*commandShell->ignErr != '\0')) + (*commandShell->ignErr != '\0')) { /* * The shell has no error control, so we need to be @@ -613,10 +503,10 @@ JobPrintCommand(cmdp, jobp) * to ignore errors. Set cmdTemplate to use the weirdness * instead of the simple "%s\n" template. */ - if (!(job->flags & JOB_SILENT) && !shutUp && + if (! (job->flags & JOB_SILENT) && !shutUp && commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - DBPRINTF(commandShell->errCheck, cmd); + DBPRINTF ("%s\n", commandShell->echoOff); + DBPRINTF (commandShell->errCheck, cmd); shutUp = TRUE; } cmdTemplate = commandShell->ignErr; @@ -633,9 +523,9 @@ JobPrintCommand(cmdp, jobp) errOff = FALSE; } } - - DBPRINTF(cmdTemplate, cmd); - + + DBPRINTF (cmdTemplate, cmd); + if (errOff) { /* * If echoing is already off, there's no point in issuing the @@ -643,15 +533,15 @@ JobPrintCommand(cmdp, jobp) * for the whole command... */ if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){ - DBPRINTF("%s\n", commandShell->echoOff); + DBPRINTF ("%s\n", commandShell->echoOff); shutUp = TRUE; } - DBPRINTF("%s\n", commandShell->errCheck); + DBPRINTF ("%s\n", commandShell->errCheck); } if (shutUp) { - DBPRINTF("%s\n", commandShell->echoOn); + DBPRINTF ("%s\n", commandShell->echoOn); } - return 0; + return (0); } /*- @@ -669,48 +559,13 @@ JobPrintCommand(cmdp, jobp) *----------------------------------------------------------------------- */ static int -JobSaveCommand(cmd, gn) +JobSaveCommand (cmd, gn) ClientData cmd; ClientData gn; { - cmd = (ClientData) Var_Subst(NULL, (char *) cmd, (GNode *) gn, FALSE); - (void) Lst_AtEnd(postCommands->commands, cmd); - return(0); -} - - -/*- - *----------------------------------------------------------------------- - * JobClose -- - * Called to close both input and output pipes when a job is finished. - * - * Results: - * Nada - * - * Side Effects: - * The file descriptors associated with the job are closed. - * - *----------------------------------------------------------------------- - */ -static void -JobClose(job) - Job *job; -{ - if (usePipes) { -#ifdef RMT_WILL_WATCH - Rmt_Ignore(job->inPipe); -#else - FD_CLR(job->inPipe, &outputs); -#endif - if (job->outPipe != job->inPipe) { - (void) close(job->outPipe); - } - JobDoOutput(job, TRUE); - (void) close(job->inPipe); - } else { - (void) close(job->outFd); - JobDoOutput(job, TRUE); - } + cmd = (ClientData) Var_Subst (NULL, (char *) cmd, (GNode *) gn, FALSE); + (void)Lst_AtEnd (postCommands->commands, cmd); + return (0); } /*- @@ -738,15 +593,15 @@ JobClose(job) */ /*ARGSUSED*/ static void -JobFinish(job, status) - Job *job; /* job to finish */ - int *status; /* sub-why job went away */ +JobFinish (job, status) + Job *job; /* job to finish */ + union wait status; /* sub-why job went away */ { - Boolean done; + Boolean done; - if ((WIFEXITED(*status) && - (((WEXITSTATUS(*status) != 0) && !(job->flags & JOB_IGNERR)))) || - (WIFSIGNALED(*status) && (WTERMSIG(*status) != SIGCONT))) + if ((WIFEXITED(status) && + (((status.w_retcode != 0) && !(job->flags & JOB_IGNERR)))) || + (WIFSIGNALED(status) && (status.w_termsig != SIGCONT))) { /* * If it exited non-zero and either we're doing things our @@ -756,109 +611,93 @@ JobFinish(job, status) * cases, finish out the job's output before printing the exit * status... */ -#ifdef REMOTE - KILL(job->pid, SIGCONT); -#endif - JobClose(job); + if (usePipes) { +#ifdef RMT_WILL_WATCH + Rmt_Ignore(job->inPipe); +#else + FD_CLR(job->inPipe, &outputs); +#endif /* RMT_WILL_WATCH */ + if (job->outPipe != job->inPipe) { + (void)close (job->outPipe); + } + JobDoOutput (job, TRUE); + (void)close (job->inPipe); + } else { + (void)close (job->outFd); + JobDoOutput (job, TRUE); + } + if (job->cmdFILE != NULL && job->cmdFILE != stdout) { - (void) fclose(job->cmdFILE); + fclose(job->cmdFILE); } done = TRUE; -#ifdef REMOTE - if (job->flags & JOB_REMOTE) - Rmt_Done(job->rmtID, job->node); -#endif - } else if (WIFEXITED(*status)) { + } else if (WIFEXITED(status) && status.w_retcode != 0) { /* * Deal with ignored errors in -B mode. We need to print a message * telling of the ignored error as well as setting status.w_status * to 0 so the next command gets run. To do this, we set done to be - * TRUE if in -B mode and the job exited non-zero. - */ - done = WEXITSTATUS(*status) != 0; - /* - * Old comment said: "Note we don't + * TRUE if in -B mode and the job exited non-zero. Note we don't * want to close down any of the streams until we know we're at the - * end." - * But we do. Otherwise when are we going to print the rest of the - * stuff? + * end. */ - JobClose(job); -#ifdef REMOTE - if (job->flags & JOB_REMOTE) - Rmt_Done(job->rmtID, job->node); -#endif /* REMOTE */ + done = TRUE; } else { /* * No need to close things down or anything. */ done = FALSE; } - + if (done || - WIFSTOPPED(*status) || - (WIFSIGNALED(*status) && (WTERMSIG(*status) == SIGCONT)) || + WIFSTOPPED(status) || + (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) || DEBUG(JOB)) { FILE *out; - - if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) { + + if (!usePipes && (job->flags & JOB_IGNERR)) { /* * If output is going to a file and this job is ignoring * errors, arrange to have the exit status sent to the * output file as well. */ - out = fdopen(job->outFd, "w"); + out = fdopen (job->outFd, "w"); } else { out = stdout; } - if (WIFEXITED(*status)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Process %d exited.\n", job->pid); - (void) fflush(stdout); - } - if (WEXITSTATUS(*status) != 0) { + if (WIFEXITED(status)) { + if (status.w_retcode != 0) { if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); + fprintf (out, targFmt, job->node->name); lastNode = job->node; } - (void) fprintf(out, "*** Error code %d%s\n", - WEXITSTATUS(*status), - (job->flags & JOB_IGNERR) ? "(ignored)" : ""); + fprintf (out, "*** Error code %d%s\n", status.w_retcode, + (job->flags & JOB_IGNERR) ? " (ignored)" : ""); if (job->flags & JOB_IGNERR) { - *status = 0; + status.w_status = 0; } } else if (DEBUG(JOB)) { if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); + fprintf (out, targFmt, job->node->name); lastNode = job->node; } - (void) fprintf(out, "*** Completed successfully\n"); - } - } else if (WIFSTOPPED(*status)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Process %d stopped.\n", job->pid); - (void) fflush(stdout); + fprintf (out, "*** Completed successfully\n"); } + } else if (WIFSTOPPED(status)) { if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); + fprintf (out, targFmt, job->node->name); lastNode = job->node; } - if (!(job->flags & JOB_REMIGRATE)) { - (void) fprintf(out, "*** Stopped -- signal %d\n", - WSTOPSIG(*status)); + if (! (job->flags & JOB_REMIGRATE)) { + fprintf (out, "*** Stopped -- signal %d\n", status.w_stopsig); } job->flags |= JOB_RESUME; (void)Lst_AtEnd(stoppedJobs, (ClientData)job); -#ifdef REMOTE - if (job->flags & JOB_REMIGRATE) - JobRestart(job); -#endif - (void) fflush(out); + fflush(out); return; - } else if (WTERMSIG(*status) == SIGCONT) { + } else if (status.w_termsig == SIGCONT) { /* * If the beastie has continued, shift the Job from the stopped * list to the running one (or re-stop it if concurrency is @@ -866,58 +705,37 @@ JobFinish(job, status) */ if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) { if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); + fprintf (out, targFmt, job->node->name); lastNode = job->node; } - (void) fprintf(out, "*** Continued\n"); + fprintf (out, "*** Continued\n"); } - if (!(job->flags & JOB_CONTINUING)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "Warning: process %d was not continuing.\n", - job->pid); - (void) fflush(stdout); - } -#ifdef notdef - /* - * We don't really want to restart a job from scratch just - * because it continued, especially not without killing the - * continuing process! That's why this is ifdef'ed out. - * FD - 9/17/90 - */ + if (! (job->flags & JOB_CONTINUING)) { JobRestart(job); -#endif - } - job->flags &= ~JOB_CONTINUING; - Lst_AtEnd(jobs, (ClientData)job); - nJobs += 1; - if (!(job->flags & JOB_REMOTE)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "Process %d is continuing locally.\n", - job->pid); - (void) fflush(stdout); - } - nLocal += 1; + } else { + Lst_AtEnd(jobs, (ClientData)job); + nJobs += 1; + if (! (job->flags & JOB_REMOTE)) { + nLocal += 1; + } + if (nJobs == maxJobs) { + jobFull = TRUE; + if (DEBUG(JOB)) { + printf("Job queue is full.\n"); + } + } } - if (nJobs == maxJobs) { - jobFull = TRUE; - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Job queue is full.\n"); - (void) fflush(stdout); - } - } - (void) fflush(out); - return; + fflush(out); + return; } else { if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); + fprintf (out, targFmt, job->node->name); lastNode = job->node; } - (void) fprintf(out, "*** Signal %d\n", WTERMSIG(*status)); + fprintf (out, "*** Signal %d\n", status.w_termsig); } - (void) fflush(out); + fflush (out); } /* @@ -925,36 +743,40 @@ JobFinish(job, status) * try and restart the job on the next command. If JobStart says it's * ok, it's ok. If there's an error, this puppy is done. */ - if (compatMake && (WIFEXITED(*status) && - !Lst_IsAtEnd(job->node->commands))) { - switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) { - case JOB_RUNNING: - done = FALSE; - break; - case JOB_ERROR: - done = TRUE; - W_SETEXITSTATUS(status, 1); - break; - case JOB_FINISHED: - /* - * If we got back a JOB_FINISHED code, JobStart has already - * called Make_Update and freed the job descriptor. We set - * done to false here to avoid fake cycles and double frees. - * JobStart needs to do the update so we can proceed up the - * graph when given the -n flag.. - */ - done = FALSE; - break; + if ((status.w_status == 0) && + !Lst_IsAtEnd (job->node->commands)) + { + switch (JobStart (job->node, + job->flags & JOB_IGNDOTS, + job)) + { + case JOB_RUNNING: + done = FALSE; + break; + case JOB_ERROR: + done = TRUE; + status.w_retcode = 1; + break; + case JOB_FINISHED: + /* + * If we got back a JOB_FINISHED code, JobStart has already + * called Make_Update and freed the job descriptor. We set + * done to false here to avoid fake cycles and double frees. + * JobStart needs to do the update so we can proceed up the + * graph when given the -n flag.. + */ + done = FALSE; + break; } } else { done = TRUE; } - + if (done && (aborting != ABORT_ERROR) && (aborting != ABORT_INTERRUPT) && - (*status == 0)) + (status.w_status == 0)) { /* * As long as we aren't aborting and the job didn't return a non-zero @@ -963,19 +785,21 @@ JobFinish(job, status) * on the .END target. */ if (job->tailCmds != NILLNODE) { - Lst_ForEachFrom(job->node->commands, job->tailCmds, + Lst_ForEachFrom (job->node->commands, job->tailCmds, JobSaveCommand, - (ClientData)job->node); + (ClientData)job->node); } job->node->made = MADE; - Make_Update(job->node); + Make_Update (job->node); free((Address)job); - } else if (*status != 0) { + } else if (status.w_status) { errors += 1; free((Address)job); } - JobRestartJobs(); + while (!errors && !jobFull && !Lst_IsEmpty(stoppedJobs)) { + JobRestart((Job *)Lst_DeQueue(stoppedJobs)); + } /* * Set aborting if any error. @@ -988,13 +812,13 @@ JobFinish(job, status) */ aborting = ABORT_ERROR; } - + if ((aborting == ABORT_ERROR) && Job_Empty()) { /* * If we are aborting and the job table is now empty, we finish. */ - (void) eunlink(tfile); - Finish(errors); + (void) unlink (tfile); + Finish (errors); } } @@ -1013,12 +837,12 @@ JobFinish(job, status) *----------------------------------------------------------------------- */ void -Job_Touch(gn, silent) +Job_Touch (gn, silent) GNode *gn; /* the node of the file to touch */ Boolean silent; /* TRUE if should not print messages */ { int streamID; /* ID of stream opened to do the touch */ - struct utimbuf times; /* Times for utime() call */ + struct timeval times[2]; /* Times for utimes() call */ if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) { /* @@ -1027,10 +851,9 @@ Job_Touch(gn, silent) */ return; } - + if (!silent) { - (void) fprintf(stdout, "touch %s\n", gn->name); - (void) fflush(stdout); + printf ("touch %s\n", gn->name); } if (noExecute) { @@ -1038,15 +861,16 @@ Job_Touch(gn, silent) } if (gn->type & OP_ARCHV) { - Arch_Touch(gn); + Arch_Touch (gn); } else if (gn->type & OP_LIB) { - Arch_TouchLib(gn); + Arch_TouchLib (gn); } else { char *file = gn->path ? gn->path : gn->name; - times.actime = times.modtime = now; - if (utime(file, ×) < 0){ - streamID = open(file, O_RDWR | O_CREAT, 0666); + times[0].tv_sec = times[1].tv_sec = now; + times[0].tv_usec = times[1].tv_usec = 0; + if (utimes(file, times) < 0){ + streamID = open (file, O_RDWR | O_CREAT, 0666); if (streamID >= 0) { char c; @@ -1056,16 +880,13 @@ Job_Touch(gn, silent) * modification time, then close the file. */ if (read(streamID, &c, 1) == 1) { - (void) lseek(streamID, 0L, L_SET); - (void) write(streamID, &c, 1); + lseek(streamID, 0L, L_SET); + write(streamID, &c, 1); } - - (void) close(streamID); - } else { - (void) fprintf(stdout, "*** couldn't touch %s: %s", - file, strerror(errno)); - (void) fflush(stdout); - } + + (void)close (streamID); + } else + printf("*** couldn't touch %s: %s", file, strerror(errno)); } } } @@ -1073,7 +894,7 @@ Job_Touch(gn, silent) /*- *----------------------------------------------------------------------- * Job_CheckCommands -- - * Make sure the given node has all the commands it needs. + * Make sure the given node has all the commands it needs. * * Results: * TRUE if the commands list is/was ok. @@ -1084,17 +905,17 @@ Job_Touch(gn, silent) *----------------------------------------------------------------------- */ Boolean -Job_CheckCommands(gn, abortProc) +Job_CheckCommands (gn, abortProc) GNode *gn; /* The target whose commands need * verifying */ - void (*abortProc) __P((char *, ...)); + void (*abortProc) __P((char *, ...)); /* Function to abort with message */ { - if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) && + if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) && (gn->type & OP_LIB) == 0) { /* * No commands. Look for .DEFAULT rule from which we might infer - * commands + * commands */ if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) { char *p1; @@ -1108,33 +929,32 @@ Job_CheckCommands(gn, abortProc) * .DEFAULT itself. */ Make_HandleUse(DEFAULT, gn); - Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn); + Var_Set (IMPSRC, Var_Value (TARGET, gn, &p1), gn); if (p1) free(p1); - } else if (Dir_MTime(gn) == 0) { + } else if (Dir_MTime (gn) == 0) { /* * The node wasn't the target of an operator we have no .DEFAULT * rule to go on and the target doesn't already exist. There's * nothing more we can do for this branch. If the -k flag wasn't * given, we stop in our tracks, otherwise we just don't update - * this node's parents so they never get examined. + * this node's parents so they never get examined. */ - static const char msg[] = "make: don't know how to make"; - if (gn->type & OP_OPTIONAL) { - (void) fprintf(stdout, "%s %s(ignored)\n", msg, gn->name); - (void) fflush(stdout); + printf ("make: don't know how to make %s (ignored)\n", + gn->name); } else if (keepgoing) { - (void) fprintf(stdout, "%s %s(continuing)\n", msg, gn->name); - (void) fflush(stdout); - return FALSE; + printf ("make: don't know how to make %s (continuing)\n", + gn->name); + return (FALSE); } else { - (*abortProc)("%s %s. Stop", msg, gn->name); - return FALSE; + (*abortProc) ("make: don't know how to make %s. Stop", + gn->name); + return(FALSE); } } } - return TRUE; + return (TRUE); } #ifdef RMT_WILL_WATCH /*- @@ -1147,7 +967,7 @@ Job_CheckCommands(gn, abortProc) * * Side Effects: * JobDoOutput is called. - * + * *----------------------------------------------------------------------- */ /*ARGSUSED*/ @@ -1181,20 +1001,19 @@ JobExec(job, argv) char **argv; { int cpid; /* ID of new child */ - + if (DEBUG(JOB)) { int i; - - (void) fprintf(stdout, "Running %s %sly\n", job->node->name, - job->flags&JOB_REMOTE?"remote":"local"); - (void) fprintf(stdout, "\tCommand: "); - for (i = 0; argv[i] != NULL; i++) { - (void) fprintf(stdout, "%s ", argv[i]); + + printf("Running %s %sly\n", job->node->name, + job->flags&JOB_REMOTE?"remote":"local"); + printf("\tCommand: "); + for (i = 0; argv[i] != (char *)NULL; i++) { + printf("%s ", argv[i]); } - (void) fprintf(stdout, "\n"); - (void) fflush(stdout); + printf("\n"); } - + /* * Some jobs produce no output and it's disconcerting to have * no feedback of their running (since they produce no output, the @@ -1202,19 +1021,20 @@ JobExec(job, argv) * provide that feedback, even if nothing follows it. */ if ((lastNode != job->node) && (job->flags & JOB_FIRST) && - !(job->flags & JOB_SILENT)) { - MESSAGE(stdout, job->node); + !(job->flags & JOB_SILENT)) + { + printf(targFmt, job->node->name); lastNode = job->node; } - + #ifdef RMT_NO_EXEC if (job->flags & JOB_REMOTE) { goto jobExecFinish; } #endif /* RMT_NO_EXEC */ - if ((cpid = vfork()) == -1) { - Punt("Cannot fork"); + if ((cpid = vfork()) == -1) { + Punt ("Cannot fork"); } else if (cpid == 0) { /* @@ -1222,26 +1042,23 @@ JobExec(job, argv) * reset it to the beginning (again). Since the stream was marked * close-on-exec, we must clear that bit in the new input. */ - if (dup2(FILENO(job->cmdFILE), 0) == -1) - Punt("Cannot dup2: %s", strerror(errno)); - (void) fcntl(0, F_SETFD, 0); - (void) lseek(0, 0, L_SET); - + (void) dup2(fileno(job->cmdFILE), 0); + fcntl(0, F_SETFD, 0); + lseek(0, 0, L_SET); + if (usePipes) { /* * Set up the child's output to be routed through the pipe * we've created for it. */ - if (dup2(job->outPipe, 1) == -1) - Punt("Cannot dup2: %s", strerror(errno)); + (void) dup2 (job->outPipe, 1); } else { /* * We're capturing output in a file, so we duplicate the * descriptor to the temporary file into the standard * output. */ - if (dup2(job->outFd, 1) == -1) - Punt("Cannot dup2: %s", strerror(errno)); + (void) dup2 (job->outFd, 1); } /* * The output channels are marked close on exec. This bit was @@ -1249,9 +1066,8 @@ JobExec(job, argv) * it before routing the shell's error output to the same place as * its standard output. */ - (void) fcntl(1, F_SETFD, 0); - if (dup2(1, 2) == -1) - Punt("Cannot dup2: %s", strerror(errno)); + fcntl(1, F_SETFD, 0); + (void) dup2 (1, 2); #ifdef USE_PGRP /* @@ -1259,27 +1075,15 @@ JobExec(job, argv) * we can kill it and all its descendants in one fell swoop, * by killing its process family, but not commit suicide. */ -# if defined(SYSV) - (void) setsid(); -# else - (void) setpgid(0, getpid()); -# endif -#endif /* USE_PGRP */ + + (void) setpgrp(0, getpid()); +#endif USE_PGRP -#ifdef REMOTE - if (job->flags & JOB_REMOTE) { - Rmt_Exec(shellPath, argv, FALSE); - } else -#endif /* REMOTE */ - (void) execv(shellPath, argv); - - (void) write(2, "Could not execute shell\n", - sizeof("Could not execute shell")); - _exit(1); + (void) execv (shellPath, argv); + (void) write (2, "Could not execute shell\n", + sizeof ("Could not execute shell")); + _exit (1); } else { -#ifdef REMOTE - long omask = sigblock(sigmask(SIGCHLD)); -#endif job->pid = cpid; if (usePipes && (job->flags & JOB_FIRST) ) { @@ -1289,7 +1093,7 @@ JobExec(job, argv) * stream to watch in the outputs mask */ job->curPos = 0; - + #ifdef RMT_WILL_WATCH Rmt_Watch(job->inPipe, JobLocalInput, job); #else @@ -1298,34 +1102,27 @@ JobExec(job, argv) } if (job->flags & JOB_REMOTE) { -#ifndef REMOTE job->rmtID = 0; -#else - job->rmtID = Rmt_LastID(job->pid); -#endif /* REMOTE */ } else { nLocal += 1; /* - * XXX: Used to not happen if REMOTE. Why? + * XXX: Used to not happen if CUSTOMS. Why? */ - if (job->cmdFILE != NULL && job->cmdFILE != stdout) { - (void) fclose(job->cmdFILE); + if (job->cmdFILE != stdout) { + fclose(job->cmdFILE); job->cmdFILE = NULL; } } -#ifdef REMOTE - (void) sigsetmask(omask); -#endif } #ifdef RMT_NO_EXEC -jobExecFinish: +jobExecFinish: #endif /* * Now the job is actually running, add it to the table. */ nJobs += 1; - (void) Lst_AtEnd(jobs, (ClientData)job); + (void)Lst_AtEnd (jobs, (ClientData)job); if (nJobs == maxJobs) { jobFull = TRUE; } @@ -1335,7 +1132,7 @@ jobExecFinish: *----------------------------------------------------------------------- * JobMakeArgv -- * Create the argv needed to execute the shell for a given job. - * + * * * Results: * @@ -1350,7 +1147,7 @@ JobMakeArgv(job, argv) { int argc; static char args[10]; /* For merged arguments */ - + argv[0] = shellName; argc = 1; @@ -1383,13 +1180,13 @@ JobMakeArgv(job, argv) argc++; } } - argv[argc] = NULL; + argv[argc] = (char *)NULL; } /*- *----------------------------------------------------------------------- * JobRestart -- - * Restart a job that stopped for some reason. + * Restart a job that stopped for some reason. * * Results: * None. @@ -1403,91 +1200,44 @@ static void JobRestart(job) Job *job; /* Job to restart */ { -#ifdef REMOTE - int host; -#endif - if (job->flags & JOB_REMIGRATE) { - if ( -#ifdef REMOTE - verboseRemigrates || -#endif - DEBUG(JOB)) { - (void) fprintf(stdout, "*** remigrating %x(%s)\n", - job->pid, job->node->name); - (void) fflush(stdout); + if (DEBUG(JOB)) { + printf("Remigrating %x\n", job->pid); } - -#ifdef REMOTE - if (!Rmt_ReExport(job->pid, job->node, &host)) { - if (verboseRemigrates || DEBUG(JOB)) { - (void) fprintf(stdout, "*** couldn't migrate...\n"); - (void) fflush(stdout); - } -#endif - if (nLocal != maxLocal) { + if (nLocal != maxLocal) { /* * Job cannot be remigrated, but there's room on the local * machine, so resume the job and note that another * local job has started. */ - if ( -#ifdef REMOTE - verboseRemigrates || -#endif - DEBUG(JOB)) { - (void) fprintf(stdout, "*** resuming on local machine\n"); - (void) fflush(stdout); - } + if (DEBUG(JOB)) { + printf("resuming on local machine\n"); + } KILL(job->pid, SIGCONT); nLocal +=1; -#ifdef REMOTE - job->flags &= ~(JOB_REMIGRATE|JOB_RESUME|JOB_REMOTE); - job->flags |= JOB_CONTINUING; -#else job->flags &= ~(JOB_REMIGRATE|JOB_RESUME); -#endif } else { /* * Job cannot be restarted. Mark the table as full and * place the job back on the list of stopped jobs. */ - if ( -#ifdef REMOTE - verboseRemigrates || -#endif - DEBUG(JOB)) { - (void) fprintf(stdout, "*** holding\n"); - (void) fflush(stdout); - } + if (DEBUG(JOB)) { + printf("holding\n"); + } (void)Lst_AtFront(stoppedJobs, (ClientData)job); jobFull = TRUE; if (DEBUG(JOB)) { - (void) fprintf(stdout, "Job queue is full.\n"); - (void) fflush(stdout); + printf("Job queue is full.\n"); } return; - } -#ifdef REMOTE - } else { - /* - * Clear out the remigrate and resume flags. Set the continuing - * flag so we know later on that the process isn't exiting just - * because of a signal. - */ - job->flags &= ~(JOB_REMIGRATE|JOB_RESUME); - job->flags |= JOB_CONTINUING; - job->rmtID = host; } -#endif - + (void)Lst_AtEnd(jobs, (ClientData)job); nJobs += 1; if (nJobs == maxJobs) { jobFull = TRUE; if (DEBUG(JOB)) { - (void) fprintf(stdout, "Job queue is full.\n"); - (void) fflush(stdout); + printf("Job queue is full.\n"); } } } else if (job->flags & JOB_RESTART) { @@ -1497,65 +1247,38 @@ JobRestart(job) * the 'exit' flag of the commandShell is used to cause it to exit * upon receiving an error. If the JOB_SILENT flag is clear, the * 'echo' flag of the commandShell is used to get it to start echoing - * as soon as it starts processing commands. + * as soon as it starts processing commands. */ char *argv[4]; - + JobMakeArgv(job, argv); - + if (DEBUG(JOB)) { - (void) fprintf(stdout, "Restarting %s...", job->node->name); - (void) fflush(stdout); + printf("Restarting %s...", job->node->name); } -#ifdef REMOTE - if ((job->node->type&OP_NOEXPORT) || - (nLocal < maxLocal && runLocalFirst) -# ifdef RMT_NO_EXEC - || !Rmt_Export(shellPath, argv, job) -# else - || !Rmt_Begin(shellPath, argv, job->node) -# endif -#endif - { - if (((nLocal >= maxLocal) && !(job->flags & JOB_SPECIAL))) { + if (((nLocal >= maxLocal) && ! (job->flags & JOB_SPECIAL))) { /* * Can't be exported and not allowed to run locally -- put it * back on the hold queue and mark the table full */ if (DEBUG(JOB)) { - (void) fprintf(stdout, "holding\n"); - (void) fflush(stdout); + printf("holding\n"); } (void)Lst_AtFront(stoppedJobs, (ClientData)job); jobFull = TRUE; if (DEBUG(JOB)) { - (void) fprintf(stdout, "Job queue is full.\n"); - (void) fflush(stdout); + printf("Job queue is full.\n"); } return; - } else { + } else { /* * Job may be run locally. */ if (DEBUG(JOB)) { - (void) fprintf(stdout, "running locally\n"); - (void) fflush(stdout); + printf("running locally\n"); } job->flags &= ~JOB_REMOTE; - } } -#ifdef REMOTE - else { - /* - * Can be exported. Hooray! - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, "exporting\n"); - (void) fflush(stdout); - } - job->flags |= JOB_REMOTE; - } -#endif JobExec(job, argv); } else { /* @@ -1563,20 +1286,13 @@ JobRestart(job) * we don't know... */ if (DEBUG(JOB)) { - (void) fprintf(stdout, "Resuming %s...", job->node->name); - (void) fflush(stdout); + printf("Resuming %s...", job->node->name); } if (((job->flags & JOB_REMOTE) || - (nLocal < maxLocal) || -#ifdef REMOTE - (((job->flags & JOB_SPECIAL) && - (job->node->type & OP_NOEXPORT)) && - (maxLocal == 0))) && -#else - ((job->flags & JOB_SPECIAL) && - (maxLocal == 0))) && -#endif - (nJobs != maxJobs)) + (nLocal < maxLocal) || + (((job->flags & JOB_SPECIAL)) && + (maxLocal == 0))) && + (nJobs != maxJobs)) { /* * If the job is remote, it's ok to resume it as long as the @@ -1587,8 +1303,8 @@ JobRestart(job) */ Boolean error; extern int errno; - int status; - + union wait status; + #ifdef RMT_WANTS_SIGNALS if (job->flags & JOB_REMOTE) { error = !Rmt_Signal(job, SIGCONT); @@ -1602,20 +1318,19 @@ JobRestart(job) * actually put the thing in the job table. */ job->flags |= JOB_CONTINUING; - W_SETTERMSIG(&status, SIGCONT); - JobFinish(job, &status); - + status.w_termsig = SIGCONT; + JobFinish(job, status); + job->flags &= ~(JOB_RESUME|JOB_CONTINUING); if (DEBUG(JOB)) { - (void) fprintf(stdout, "done\n"); - (void) fflush(stdout); + printf("done\n"); } } else { Error("couldn't resume %s: %s", job->node->name, strerror(errno)); - status = 0; - W_SETEXITSTATUS(&status, 1); - JobFinish(job, &status); + status.w_status = 0; + status.w_retcode = 1; + JobFinish(job, status); } } else { /* @@ -1623,14 +1338,12 @@ JobRestart(job) * place the job back on the list of stopped jobs. */ if (DEBUG(JOB)) { - (void) fprintf(stdout, "table full\n"); - (void) fflush(stdout); + printf("table full\n"); } - (void) Lst_AtFront(stoppedJobs, (ClientData)job); + (void)Lst_AtFront(stoppedJobs, (ClientData)job); jobFull = TRUE; if (DEBUG(JOB)) { - (void) fprintf(stdout, "Job queue is full.\n"); - (void) fflush(stdout); + printf("Job queue is full.\n"); } } } @@ -1640,7 +1353,7 @@ JobRestart(job) *----------------------------------------------------------------------- * JobStart -- * Start a target-creation process going for the target described - * by the graph node gn. + * by the graph node gn. * * Results: * JOB_ERROR if there was an error in the commands, JOB_FINISHED @@ -1653,7 +1366,7 @@ JobRestart(job) *----------------------------------------------------------------------- */ static int -JobStart(gn, flags, previous) +JobStart (gn, flags, previous) GNode *gn; /* target to create */ int flags; /* flags for the job to override normal ones. * e.g. JOB_SPECIAL or JOB_IGNDOTS */ @@ -1667,12 +1380,12 @@ JobStart(gn, flags, previous) Boolean local; /* Set true if the job was run locally */ Boolean noExec; /* Set true if we decide not to run the job */ - if (previous != NULL) { - previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE); + if (previous != (Job *)NULL) { + previous->flags &= ~ (JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE); job = previous; } else { - job = (Job *) emalloc(sizeof(Job)); - if (job == NULL) { + job = (Job *) emalloc (sizeof (Job)); + if (job == (Job *)NULL) { Punt("JobStart out of memory"); } flags |= JOB_FIRST; @@ -1687,10 +1400,10 @@ JobStart(gn, flags, previous) * are also added to the field. */ job->flags = 0; - if (Targ_Ignore(gn)) { + if (Targ_Ignore (gn)) { job->flags |= JOB_IGNERR; } - if (Targ_Silent(gn)) { + if (Targ_Silent (gn)) { job->flags |= JOB_SILENT; } job->flags |= flags; @@ -1699,12 +1412,12 @@ JobStart(gn, flags, previous) * Check the commands now so any attributes from .DEFAULT have a chance * to migrate to the node */ - if (!compatMake && job->flags & JOB_FIRST) { + if (job->flags & JOB_FIRST) { cmdsOK = Job_CheckCommands(gn, Error); } else { cmdsOK = TRUE; } - + /* * If the -n flag wasn't given, we open up OUR (not the child's) * temporary file to stuff commands in it. The thing is rd/wr so we don't @@ -1719,12 +1432,12 @@ JobStart(gn, flags, previous) if (!cmdsOK) { DieHorribly(); } - - job->cmdFILE = fopen(tfile, "w+"); - if (job->cmdFILE == NULL) { - Punt("Could not open %s", tfile); + + job->cmdFILE = fopen (tfile, "w+"); + if (job->cmdFILE == (FILE *) NULL) { + Punt ("Could not open %s", tfile); } - (void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1); + fcntl(fileno(job->cmdFILE), F_SETFD, 1); /* * Send the commands to the command file, flush all its buffers then * rewind and remove the thing. @@ -1747,14 +1460,13 @@ JobStart(gn, flags, previous) if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){ cmdsOK = FALSE; } else { - LstNode ln = Lst_Next(gn->commands); - + LstNode ln = Lst_Next (gn->commands); + if ((ln == NILLNODE) || - JobPrintCommand((ClientData) Lst_Datum(ln), - (ClientData) job)) + JobPrintCommand ((char *)Lst_Datum (ln), job)) { noExec = TRUE; - Lst_Close(gn->commands); + Lst_Close (gn->commands); } if (noExec && !(job->flags & JOB_FIRST)) { /* @@ -1768,7 +1480,21 @@ JobStart(gn, flags, previous) * Job_CatchChildren b/c it wasn't clear if there were * more commands to execute or not... */ - JobClose(job); + if (usePipes) { +#ifdef RMT_WILL_WATCH + Rmt_Ignore(job->inPipe); +#else + FD_CLR(job->inPipe, &outputs); +#endif + if (job->outPipe != job->inPipe) { + (void)close (job->outPipe); + } + JobDoOutput (job, TRUE); + (void)close (job->inPipe); + } else { + (void)close (job->outFd); + JobDoOutput (job, TRUE); + } } } } else { @@ -1776,8 +1502,8 @@ JobStart(gn, flags, previous) * We can do all the commands at once. hooray for sanity */ numCommands = 0; - Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); - + Lst_ForEach (gn->commands, JobPrintCommand, (ClientData)job); + /* * If we didn't print out any commands to the shell script, * there's not much point in executing the shell, is there? @@ -1792,7 +1518,7 @@ JobStart(gn, flags, previous) * in one fell swoop. This will still set up job->tailCmds correctly. */ if (lastNode != gn) { - MESSAGE(stdout, gn); + printf (targFmt, gn->name); lastNode = gn; } job->cmdFILE = stdout; @@ -1816,23 +1542,22 @@ JobStart(gn, flags, previous) * up the graph. */ job->cmdFILE = stdout; - Job_Touch(gn, job->flags&JOB_SILENT); + Job_Touch (gn, job->flags&JOB_SILENT); noExec = TRUE; } /* - * If we're not supposed to execute a shell, don't. + * If we're not supposed to execute a shell, don't. */ if (noExec) { /* * Unlink and close the command file if we opened one */ if (job->cmdFILE != stdout) { - (void) eunlink(tfile); - if (job->cmdFILE != NULL) - (void) fclose(job->cmdFILE); + (void) unlink (tfile); + fclose(job->cmdFILE); } else { - (void) fflush(stdout); + fflush (stdout); } /* @@ -1844,7 +1569,7 @@ JobStart(gn, flags, previous) if (job->tailCmds != NILLNODE) { Lst_ForEachFrom(job->node->commands, job->tailCmds, JobSaveCommand, - (ClientData)job->node); + (ClientData)job->node); } Make_Update(job->node); } @@ -1855,8 +1580,8 @@ JobStart(gn, flags, previous) return(JOB_ERROR); } } else { - (void) fflush(job->cmdFILE); - (void) eunlink(tfile); + fflush (job->cmdFILE); + (void) unlink (tfile); } /* @@ -1871,47 +1596,29 @@ JobStart(gn, flags, previous) * starting a job and then set up its temporary-file name. This is just * tfile with two extra digits tacked on -- jobno. */ - if (!compatMake || (job->flags & JOB_FIRST)) { + if (job->flags & JOB_FIRST) { if (usePipes) { int fd[2]; - if (pipe(fd) == -1) - Punt("Cannot create pipe: %s", strerror(errno)); + (void) pipe(fd); job->inPipe = fd[0]; job->outPipe = fd[1]; - (void) fcntl(job->inPipe, F_SETFD, 1); - (void) fcntl(job->outPipe, F_SETFD, 1); + (void)fcntl (job->inPipe, F_SETFD, 1); + (void)fcntl (job->outPipe, F_SETFD, 1); } else { - (void) fprintf(stdout, "Remaking `%s'\n", gn->name); - (void) fflush(stdout); - sprintf(job->outFile, "%s%02d", tfile, jobno); + printf ("Remaking `%s'\n", gn->name); + fflush (stdout); + sprintf (job->outFile, "%s%02d", tfile, jobno); jobno = (jobno + 1) % 100; job->outFd = open(job->outFile,O_WRONLY|O_CREAT|O_APPEND,0600); - (void) fcntl(job->outFd, F_SETFD, 1); + (void)fcntl (job->outFd, F_SETFD, 1); } } -#ifdef REMOTE - if (!(gn->type & OP_NOEXPORT) && !(runLocalFirst && nLocal < maxLocal)) { -#ifdef RMT_NO_EXEC - local = !Rmt_Export(shellPath, argv, job); -#else - local = !Rmt_Begin(shellPath, argv, job->node); -#endif /* RMT_NO_EXEC */ - if (!local) { - job->flags |= JOB_REMOTE; - } - } else -#endif - local = TRUE; + local = TRUE; if (local && (((nLocal >= maxLocal) && - !(job->flags & JOB_SPECIAL) && -#ifdef REMOTE - (!(gn->type & OP_NOEXPORT) || (maxLocal != 0)) -#else - (maxLocal != 0) -#endif - ))) + !(job->flags & JOB_SPECIAL) && + (maxLocal != 0)))) { /* * The job can only be run locally, but we've hit the limit of @@ -1919,17 +1626,15 @@ JobStart(gn, flags, previous) * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END) * may be run locally even when the local limit has been reached * (e.g. when maxLocal == 0), though they will be exported if at - * all possible. In addition, any target marked with .NOEXPORT will - * be run locally if maxLocal is 0. + * all possible. */ jobFull = TRUE; - + if (DEBUG(JOB)) { - (void) fprintf(stdout, "Can only run job locally.\n"); - (void) fflush(stdout); + printf("Can only run job locally.\n"); } job->flags |= JOB_RESTART; - (void) Lst_AtEnd(stoppedJobs, (ClientData)job); + (void)Lst_AtEnd(stoppedJobs, (ClientData)job); } else { if ((nLocal >= maxLocal) && local) { /* @@ -1938,8 +1643,7 @@ JobStart(gn, flags, previous) */ jobFull = TRUE; if (DEBUG(JOB)) { - (void) fprintf(stdout, "Local job queue is full.\n"); - (void) fflush(stdout); + printf("Local job queue is full.\n"); } } JobExec(job, argv); @@ -1947,52 +1651,6 @@ JobStart(gn, flags, previous) return(JOB_RUNNING); } -static char * -JobOutput(job, cp, endp, msg) - register Job *job; - register char *cp, *endp; - int msg; -{ - register char *ecp; - - if (commandShell->noPrint) { - ecp = Str_FindSubstring(cp, commandShell->noPrint); - while (ecp != NULL) { - if (cp != ecp) { - *ecp = '\0'; - if (msg && job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - /* - * The only way there wouldn't be a newline after - * this line is if it were the last in the buffer. - * however, since the non-printable comes after it, - * there must be a newline, so we don't print one. - */ - (void) fprintf(stdout, "%s", cp); - (void) fflush(stdout); - } - cp = ecp + commandShell->noPLen; - if (cp != endp) { - /* - * Still more to print, look again after skipping - * the whitespace following the non-printable - * command.... - */ - cp++; - while (*cp == ' ' || *cp == '\t' || *cp == '\n') { - cp++; - } - ecp = Str_FindSubstring(cp, commandShell->noPrint); - } else { - return cp; - } - } - } - return cp; -} - /*- *----------------------------------------------------------------------- * JobDoOutput -- @@ -2020,14 +1678,13 @@ JobOutput(job, cp, endp, msg) * curPos may be shifted as may the contents of outBuf. *----------------------------------------------------------------------- */ -STATIC void -JobDoOutput(job, finish) +static void +JobDoOutput (job, finish) register Job *job; /* the job whose output needs printing */ Boolean finish; /* TRUE if this is the last time we'll be * called for this job */ { Boolean gotNL = FALSE; /* true if got a newline */ - Boolean fbuf; /* true if our buffer filled up */ register int nr; /* number of bytes read */ register int i; /* auxiliary index into outBuf */ register int max; /* limit for i (end of current data) */ @@ -2036,16 +1693,14 @@ JobDoOutput(job, finish) FILE *oFILE; /* Stream pointer to shell's output file */ char inLine[132]; - + if (usePipes) { /* * Read as many bytes as will fit in the buffer. */ end_loop: - gotNL = FALSE; - fbuf = FALSE; - - nRead = read(job->inPipe, &job->outBuf[job->curPos], + + nRead = read (job->inPipe, &job->outBuf[job->curPos], JOB_BUFSIZE - job->curPos); if (nRead < 0) { if (DEBUG(JOB)) { @@ -2069,11 +1724,11 @@ end_loop: } else if (nr == 0) { finish = FALSE; } - + /* * Look for the last newline in the bytes we just got. If there is * one, break out of the loop with 'i' as its index and gotNL set - * TRUE. + * TRUE. */ max = job->curPos + nr; for (i = job->curPos + nr - 1; i >= job->curPos; i--) { @@ -2087,19 +1742,19 @@ end_loop: job->outBuf[i] = ' '; } } - + if (!gotNL) { job->curPos += nr; if (job->curPos == JOB_BUFSIZE) { /* * If we've run out of buffer space, we have no choice - * but to print the stuff. sigh. + * but to print the stuff. sigh. */ - fbuf = TRUE; + gotNL = TRUE; i = job->curPos; } } - if (gotNL || fbuf) { + if (gotNL) { /* * Need to send the output to the screen. Null terminate it * first, overwriting the newline character if there was one. @@ -2108,13 +1763,49 @@ end_loop: * by a target banner if this target isn't the same as the * one for which we last printed something. * The rest of the data in the buffer are then shifted down - * to the start of the buffer and curPos is set accordingly. + * to the start of the buffer and curPos is set accordingly. */ job->outBuf[i] = '\0'; if (i >= job->curPos) { - char *cp; + register char *cp, *ecp; - cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE); + cp = job->outBuf; + if (commandShell->noPrint) { + ecp = Str_FindSubstring(job->outBuf, + commandShell->noPrint); + while (ecp != (char *)NULL) { + if (cp != ecp) { + *ecp = '\0'; + if (job->node != lastNode) { + printf (targFmt, job->node->name); + lastNode = job->node; + } + /* + * The only way there wouldn't be a newline after + * this line is if it were the last in the buffer. + * however, since the non-printable comes after it, + * there must be a newline, so we don't print one. + */ + printf ("%s", cp); + } + cp = ecp + commandShell->noPLen; + if (cp != &job->outBuf[i]) { + /* + * Still more to print, look again after skipping + * the whitespace following the non-printable + * command.... + */ + cp++; + while (*cp == ' ' || *cp == '\t' || *cp == '\n') { + cp++; + } + ecp = Str_FindSubstring (cp, + commandShell->noPrint); + } else { + break; + } + } + } /* * There's still more in that thar buffer. This time, though, @@ -2123,18 +1814,19 @@ end_loop: */ if (*cp != '\0') { if (job->node != lastNode) { - MESSAGE(stdout, job->node); + printf (targFmt, job->node->name); lastNode = job->node; } - (void) fprintf(stdout, "%s%s", cp, gotNL ? "\n" : ""); - (void) fflush(stdout); + printf ("%s\n", cp); } + + fflush (stdout); } if (i < max - 1) { /* shift the remaining characters down */ - (void) memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1)); + memcpy ( job->outBuf, &job->outBuf[i + 1], max - (i + 1)); job->curPos = max - (i + 1); - + } else { /* * We have written everything out, so we just start over @@ -2146,11 +1838,10 @@ end_loop: if (finish) { /* * If the finish flag is true, we must loop until we hit - * end-of-file on the pipe. This is guaranteed to happen - * eventually since the other end of the pipe is now closed - * (we closed it explicitly and the child has exited). When - * we do get an EOF, finish will be set FALSE and we'll fall - * through and out. + * end-of-file on the pipe. This is guaranteed to happen eventually + * since the other end of the pipe is now closed (we closed it + * explicitly and the child has exited). When we do get an EOF, + * finish will be set FALSE and we'll fall through and out. */ goto end_loop; } @@ -2165,36 +1856,62 @@ end_loop: * Change to read in blocks and do FindSubString type things as for * pipes? That would allow for "@echo -n..." */ - oFILE = fopen(job->outFile, "r"); - if (oFILE != NULL) { - (void) fprintf(stdout, "Results of making %s:\n", job->node->name); - (void) fflush(stdout); - while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { - register char *cp, *endp, *oendp; + oFILE = fopen (job->outFile, "r"); + if (oFILE != (FILE *) NULL) { + printf ("Results of making %s:\n", job->node->name); + while (fgets (inLine, sizeof(inLine), oFILE) != NULL) { + register char *cp, *ecp, *endp; cp = inLine; - oendp = endp = inLine + strlen(inLine); + endp = inLine + strlen(inLine); if (endp[-1] == '\n') { *--endp = '\0'; } - cp = JobOutput(job, inLine, endp, FALSE); + if (commandShell->noPrint) { + ecp = Str_FindSubstring(cp, commandShell->noPrint); + while (ecp != (char *)NULL) { + if (cp != ecp) { + *ecp = '\0'; + /* + * The only way there wouldn't be a newline after + * this line is if it were the last in the buffer. + * however, since the non-printable comes after it, + * there must be a newline, so we don't print one. + */ + printf ("%s", cp); + } + cp = ecp + commandShell->noPLen; + if (cp != endp) { + /* + * Still more to print, look again after skipping + * the whitespace following the non-printable + * command.... + */ + cp++; + while (*cp == ' ' || *cp == '\t' || *cp == '\n') { + cp++; + } + ecp = Str_FindSubstring(cp, commandShell->noPrint); + } else { + break; + } + } + } /* * There's still more in that thar buffer. This time, though, * we know there's no newline at the end, so we add one of * our own free will. */ - (void) fprintf(stdout, "%s", cp); - (void) fflush(stdout); - if (endp != oendp) { - (void) fprintf(stdout, "\n"); - (void) fflush(stdout); + if (*cp != '\0') { + printf ("%s\n", cp); } } - (void) fclose(oFILE); - (void) eunlink(job->outFile); + fclose (oFILE); + (void) unlink (job->outFile); } } + fflush(stdout); } /*- @@ -2217,13 +1934,13 @@ end_loop: *----------------------------------------------------------------------- */ void -Job_CatchChildren(block) +Job_CatchChildren (block) Boolean block; /* TRUE if should block on the wait. */ { int pid; /* pid of dead child */ register Job *job; /* job descriptor for dead child */ LstNode jnode; /* list element for finding job */ - int status; /* Exit/termination status */ + union wait status; /* Exit/termination status */ /* * Don't even bother if we know there's no one around. @@ -2231,55 +1948,41 @@ Job_CatchChildren(block) if (nLocal == 0) { return; } - - while ((pid = waitpid((pid_t) -1, &status, - (block?0:WNOHANG)|WUNTRACED)) > 0) + + while ((pid = wait3((int *)&status, (block?0:WNOHANG)|WUNTRACED, + (struct rusage *)0)) > 0) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Process %d exited or stopped.\n", pid); - (void) fflush(stdout); - } + if (DEBUG(JOB)) + printf("Process %d exited or stopped.\n", pid); + - - jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid); + jnode = Lst_Find (jobs, (ClientData)&pid, JobCmpPid); if (jnode == NILLNODE) { - if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) { + if (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) { jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid); if (jnode == NILLNODE) { Error("Resumed child (%d) not in table", pid); continue; } job = (Job *)Lst_Datum(jnode); - (void) Lst_Remove(stoppedJobs, jnode); + (void)Lst_Remove(stoppedJobs, jnode); } else { - Error("Child (%d) not in table?", pid); + Error ("Child (%d) not in table?", pid); continue; } } else { - job = (Job *) Lst_Datum(jnode); - (void) Lst_Remove(jobs, jnode); + job = (Job *) Lst_Datum (jnode); + (void)Lst_Remove (jobs, jnode); nJobs -= 1; if (jobFull && DEBUG(JOB)) { - (void) fprintf(stdout, "Job queue is no longer full.\n"); - (void) fflush(stdout); + printf("Job queue is no longer full.\n"); } jobFull = FALSE; -#ifdef REMOTE - if (!(job->flags & JOB_REMOTE)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "Job queue has one fewer local process.\n"); - (void) fflush(stdout); - } - nLocal -= 1; - } -#else nLocal -= 1; -#endif } - JobFinish(job, &status); + JobFinish (job, status); } } @@ -2290,17 +1993,17 @@ Job_CatchChildren(block) * pipes do so. Otherwise just block time until we get a * signal (most likely a SIGCHLD) since there's no point in * just spinning when there's nothing to do and the reaping - * of a child can wait for a while. + * of a child can wait for a while. * * Results: - * None + * None * * Side Effects: * Output is read from pipes if we're piping. * ----------------------------------------------------------------------- */ void -Job_CatchOutput() +Job_CatchOutput () { int nfds; struct timeval timeout; @@ -2311,7 +2014,7 @@ Job_CatchOutput() int pnJobs; /* Previous nJobs */ #endif - (void) fflush(stdout); + fflush(stdout); #ifdef RMT_WILL_WATCH pnJobs = nJobs; @@ -2340,21 +2043,21 @@ Job_CatchOutput() timeout.tv_sec = SEL_SEC; timeout.tv_usec = SEL_USEC; - if ((nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0, - (fd_set *) 0, &timeout)) <= 0) + if ((nfds = select (FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0) + { return; - else { - if (Lst_Open(jobs) == FAILURE) { - Punt("Cannot open job table"); + } else { + if (Lst_Open (jobs) == FAILURE) { + Punt ("Cannot open job table"); } - while (nfds && (ln = Lst_Next(jobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); + while (nfds && (ln = Lst_Next (jobs)) != NILLNODE) { + job = (Job *) Lst_Datum (ln); if (FD_ISSET(job->inPipe, &readfds)) { - JobDoOutput(job, FALSE); + JobDoOutput (job, FALSE); nfds -= 1; } } - Lst_Close(jobs); + Lst_Close (jobs); } } #endif /* RMT_WILL_WATCH */ @@ -2375,10 +2078,10 @@ Job_CatchOutput() *----------------------------------------------------------------------- */ void -Job_Make(gn) +Job_Make (gn) GNode *gn; { - (void) JobStart(gn, 0, NULL); + (void)JobStart (gn, 0, (Job *)NULL); } /*- @@ -2394,7 +2097,7 @@ Job_Make(gn) *----------------------------------------------------------------------- */ void -Job_Init(maxproc, maxlocal) +Job_Init (maxproc, maxlocal) int maxproc; /* the greatest number of jobs which may be * running at one time */ int maxlocal; /* the greatest number of local jobs which may @@ -2402,9 +2105,9 @@ Job_Init(maxproc, maxlocal) { GNode *begin; /* node for commands to do at the very start */ - (void) sprintf(tfile, "/tmp/make%05d", getpid()); + sprintf (tfile, "/tmp/make%05d", getpid()); - jobs = Lst_Init(FALSE); + jobs = Lst_Init (FALSE); stoppedJobs = Lst_Init(FALSE); maxJobs = maxproc; maxLocal = maxlocal; @@ -2417,11 +2120,7 @@ Job_Init(maxproc, maxlocal) lastNode = NILGNODE; - if (maxJobs == 1 -#ifdef REMOTE - || noMessages -#endif - ) { + if (maxJobs == 1) { /* * If only one job can run at a time, there's no need for a banner, * no is there? @@ -2430,8 +2129,8 @@ Job_Init(maxproc, maxlocal) } else { targFmt = TARG_FMT; } - - if (shellPath == NULL) { + + if (shellPath == (char *) NULL) { /* * The user didn't specify a shell to use, so we are using the * default one... Both the absolute path and the last component @@ -2440,13 +2139,13 @@ Job_Init(maxproc, maxlocal) * All default shells are located in _PATH_DEFSHELLDIR. */ shellName = commandShell->name; - shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH); + shellPath = str_concat (_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH); } - if (commandShell->exit == NULL) { + if (commandShell->exit == (char *)NULL) { commandShell->exit = ""; } - if (commandShell->echo == NULL) { + if (commandShell->echo == (char *)NULL) { commandShell->echo = ""; } @@ -2454,17 +2153,17 @@ Job_Init(maxproc, maxlocal) * Catch the four signals that POSIX specifies if they aren't ignored. * JobPassSig will take care of calling JobInterrupt if appropriate. */ - if (signal(SIGINT, SIG_IGN) != SIG_IGN) { - (void) signal(SIGINT, JobPassSig); + if (signal (SIGINT, SIG_IGN) != SIG_IGN) { + signal (SIGINT, JobPassSig); } - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { - (void) signal(SIGHUP, JobPassSig); + if (signal (SIGHUP, SIG_IGN) != SIG_IGN) { + signal (SIGHUP, JobPassSig); } - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { - (void) signal(SIGQUIT, JobPassSig); + if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) { + signal (SIGQUIT, JobPassSig); } - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTERM, JobPassSig); + if (signal (SIGTERM, SIG_IGN) != SIG_IGN) { + signal (SIGTERM, JobPassSig); } /* * There are additional signals that need to be caught and passed if @@ -2473,32 +2172,32 @@ Job_Init(maxproc, maxlocal) * signals from the terminal driver as we own the terminal) */ #if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP) - if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTSTP, JobPassSig); + if (signal (SIGTSTP, SIG_IGN) != SIG_IGN) { + signal (SIGTSTP, JobPassSig); } - if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTTOU, JobPassSig); + if (signal (SIGTTOU, SIG_IGN) != SIG_IGN) { + signal (SIGTTOU, JobPassSig); } - if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTTIN, JobPassSig); + if (signal (SIGTTIN, SIG_IGN) != SIG_IGN) { + signal (SIGTTIN, JobPassSig); } - if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) { - (void) signal(SIGWINCH, JobPassSig); + if (signal (SIGWINCH, SIG_IGN) != SIG_IGN) { + signal (SIGWINCH, JobPassSig); } #endif - - begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); + + begin = Targ_FindNode (".BEGIN", TARG_NOCREATE); if (begin != NILGNODE) { - JobStart(begin, JOB_SPECIAL, (Job *)0); + JobStart (begin, JOB_SPECIAL, (Job *)0); while (nJobs) { Job_CatchOutput(); #ifndef RMT_WILL_WATCH - Job_CatchChildren(!usePipes); + Job_CatchChildren (!usePipes); #endif /* RMT_WILL_WATCH */ } } - postCommands = Targ_FindNode(".END", TARG_CREATE); + postCommands = Targ_FindNode (".END", TARG_CREATE); } /*- @@ -2516,9 +2215,9 @@ Job_Init(maxproc, maxlocal) *----------------------------------------------------------------------- */ Boolean -Job_Full() +Job_Full () { - return(aborting || jobFull); + return (aborting || jobFull); } /*- @@ -2538,7 +2237,7 @@ Job_Full() * ----------------------------------------------------------------------- */ Boolean -Job_Empty() +Job_Empty () { if (nJobs == 0) { if (!Lst_IsEmpty(stoppedJobs) && !aborting) { @@ -2547,7 +2246,9 @@ Job_Empty() * it...Try and restart the stopped jobs. */ jobFull = FALSE; - JobRestartJobs(); + while (!jobFull && !Lst_IsEmpty(stoppedJobs)) { + JobRestart((Job *)Lst_DeQueue(stoppedJobs)); + } return(FALSE); } else { return(TRUE); @@ -2571,7 +2272,7 @@ Job_Empty() *----------------------------------------------------------------------- */ static Shell * -JobMatchShell(name) +JobMatchShell (name) char *name; /* Final component of shell path */ { register Shell *sh; /* Pointer into shells table */ @@ -2580,23 +2281,24 @@ JobMatchShell(name) *cp2; char *eoname; - eoname = name + strlen(name); + eoname = name + strlen (name); - match = NULL; + match = (Shell *) NULL; for (sh = shells; sh->name != NULL; sh++) { - for (cp1 = eoname - strlen(sh->name), cp2 = sh->name; + for (cp1 = eoname - strlen (sh->name), cp2 = sh->name; *cp1 != '\0' && *cp1 == *cp2; cp1++, cp2++) { continue; } if (*cp1 != *cp2) { continue; - } else if (match == NULL || strlen(match->name) < strlen(sh->name)) { - match = sh; + } else if (match == (Shell *) NULL || + strlen (match->name) < strlen (sh->name)) { + match = sh; } } - return(match == NULL ? sh : match); + return (match == (Shell *) NULL ? sh : match); } /*- @@ -2643,7 +2345,7 @@ JobMatchShell(name) *----------------------------------------------------------------------- */ ReturnStatus -Job_ParseShell(line) +Job_ParseShell (line) char *line; /* The shell spec */ { char **words; @@ -2654,64 +2356,64 @@ Job_ParseShell(line) Shell newShell; Boolean fullSpec = FALSE; - while (isspace(*line)) { + while (isspace (*line)) { line++; } - words = brk_string(line, &wordCount, TRUE); - - memset((Address)&newShell, 0, sizeof(newShell)); + words = brk_string (line, &wordCount, TRUE); + memset ((Address)&newShell, 0, sizeof(newShell)); + /* * Parse the specification by keyword */ - for (path = NULL, argc = wordCount - 1, argv = words + 1; + for (path = (char *)NULL, argc = wordCount - 1, argv = words + 1; argc != 0; argc--, argv++) { - if (strncmp(*argv, "path=", 5) == 0) { + if (strncmp (*argv, "path=", 5) == 0) { path = &argv[0][5]; - } else if (strncmp(*argv, "name=", 5) == 0) { + } else if (strncmp (*argv, "name=", 5) == 0) { newShell.name = &argv[0][5]; } else { - if (strncmp(*argv, "quiet=", 6) == 0) { + if (strncmp (*argv, "quiet=", 6) == 0) { newShell.echoOff = &argv[0][6]; - } else if (strncmp(*argv, "echo=", 5) == 0) { + } else if (strncmp (*argv, "echo=", 5) == 0) { newShell.echoOn = &argv[0][5]; - } else if (strncmp(*argv, "filter=", 7) == 0) { + } else if (strncmp (*argv, "filter=", 7) == 0) { newShell.noPrint = &argv[0][7]; newShell.noPLen = strlen(newShell.noPrint); - } else if (strncmp(*argv, "echoFlag=", 9) == 0) { + } else if (strncmp (*argv, "echoFlag=", 9) == 0) { newShell.echo = &argv[0][9]; - } else if (strncmp(*argv, "errFlag=", 8) == 0) { + } else if (strncmp (*argv, "errFlag=", 8) == 0) { newShell.exit = &argv[0][8]; - } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) { + } else if (strncmp (*argv, "hasErrCtl=", 10) == 0) { char c = argv[0][10]; newShell.hasErrCtl = !((c != 'Y') && (c != 'y') && - (c != 'T') && (c != 't')); - } else if (strncmp(*argv, "check=", 6) == 0) { + (c != 'T') && (c != 't')); + } else if (strncmp (*argv, "check=", 6) == 0) { newShell.errCheck = &argv[0][6]; - } else if (strncmp(*argv, "ignore=", 7) == 0) { + } else if (strncmp (*argv, "ignore=", 7) == 0) { newShell.ignErr = &argv[0][7]; } else { - Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"", + Parse_Error (PARSE_FATAL, "Unknown keyword \"%s\"", *argv); - return(FAILURE); + return (FAILURE); } fullSpec = TRUE; } } - if (path == NULL) { + if (path == (char *)NULL) { /* * If no path was given, the user wants one of the pre-defined shells, * yes? So we find the one s/he wants with the help of JobMatchShell * and set things up the right way. shellPath will be set up by * Job_Init. */ - if (newShell.name == NULL) { - Parse_Error(PARSE_FATAL, "Neither path nor name specified"); - return(FAILURE); + if (newShell.name == (char *)NULL) { + Parse_Error (PARSE_FATAL, "Neither path nor name specified"); + return (FAILURE); } else { - commandShell = JobMatchShell(newShell.name); + commandShell = JobMatchShell (newShell.name); shellName = newShell.name; } } else { @@ -2723,19 +2425,19 @@ Job_ParseShell(line) * path the user gave for the shell. */ shellPath = path; - path = strrchr(path, '/'); - if (path == NULL) { + path = strrchr (path, '/'); + if (path == (char *)NULL) { path = shellPath; } else { path += 1; } - if (newShell.name != NULL) { + if (newShell.name != (char *)NULL) { shellName = newShell.name; } else { shellName = path; } if (!fullSpec) { - commandShell = JobMatchShell(shellName); + commandShell = JobMatchShell (shellName); } else { commandShell = (Shell *) emalloc(sizeof(Shell)); *commandShell = newShell; @@ -2745,21 +2447,21 @@ Job_ParseShell(line) if (commandShell->echoOn && commandShell->echoOff) { commandShell->hasEchoCtl = TRUE; } - + if (!commandShell->hasErrCtl) { - if (commandShell->errCheck == NULL) { + if (commandShell->errCheck == (char *)NULL) { commandShell->errCheck = ""; } - if (commandShell->ignErr == NULL) { + if (commandShell->ignErr == (char *)NULL) { commandShell->ignErr = "%s\n"; } } - + /* * Do not free up the words themselves, since they might be in use by the * shell specification... */ - free(words); + free (words); return SUCCESS; } @@ -2777,27 +2479,28 @@ Job_ParseShell(line) *----------------------------------------------------------------------- */ static void -JobInterrupt(runINTERRUPT, signo) +JobInterrupt (runINTERRUPT) int runINTERRUPT; /* Non-zero if commands for the .INTERRUPT * target should be executed */ - int signo; /* signal received */ { LstNode ln; /* element in job table */ Job *job; /* job descriptor in that element */ GNode *interrupt; /* the node describing the .INTERRUPT target */ - + aborting = ABORT_INTERRUPT; - (void) Lst_Open(jobs); - while ((ln = Lst_Next(jobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); + (void)Lst_Open (jobs); + while ((ln = Lst_Next (jobs)) != NILLNODE) { + job = (Job *) Lst_Datum (ln); - if (!Targ_Precious(job->node)) { - char *file = (job->node->path == NULL ? + if (!Targ_Precious (job->node)) { + char *file = (job->node->path == (char *)NULL ? job->node->name : job->node->path); - if (!noExecute && eunlink(file) != -1) { - Error("*** %s removed", file); + struct stat st; + if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) && + unlink(file) != -1) { + Error ("*** %s removed", file); } } #ifdef RMT_WANTS_SIGNALS @@ -2805,117 +2508,51 @@ JobInterrupt(runINTERRUPT, signo) /* * If job is remote, let the Rmt module do the killing. */ - if (!Rmt_Signal(job, signo)) { + if (!Rmt_Signal(job, SIGINT)) { /* * If couldn't kill the thing, finish it out now with an * error code, since no exit report will come in likely. */ - int status; + union wait status; status.w_status = 0; status.w_retcode = 1; - JobFinish(job, &status); + JobFinish(job, status); } } else if (job->pid) { - KILL(job->pid, signo); + KILL(job->pid, SIGINT); } #else if (job->pid) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobInterrupt passing signal to child %d.\n", - job->pid); - (void) fflush(stdout); - } - KILL(job->pid, signo); - } -#endif /* RMT_WANTS_SIGNALS */ - } - -#ifdef REMOTE - (void)Lst_Open(stoppedJobs); - while ((ln = Lst_Next(stoppedJobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); - - if (job->flags & JOB_RESTART) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "%s%s", - "JobInterrupt skipping job on stopped queue", - "-- it was waiting to be restarted.\n"); - (void) fflush(stdout); - } - continue; - } - if (!Targ_Precious(job->node)) { - char *file = (job->node->path == NULL ? - job->node->name : - job->node->path); - if (eunlink(file) == 0) { - Error("*** %s removed", file); - } - } - /* - * Resume the thing so it will take the signal. - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobInterrupt passing CONT to stopped child %d.\n", - job->pid); - (void) fflush(stdout); - } - KILL(job->pid, SIGCONT); -#ifdef RMT_WANTS_SIGNALS - if (job->flags & JOB_REMOTE) { - /* - * If job is remote, let the Rmt module do the killing. - */ - if (!Rmt_Signal(job, SIGINT)) { - /* - * If couldn't kill the thing, finish it out now with an - * error code, since no exit report will come in likely. - */ - int status; - status.w_status = 0; - status.w_retcode = 1; - JobFinish(job, &status); - } - } else if (job->pid) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobInterrupt passing interrupt to stopped child %d.\n", - job->pid); - (void) fflush(stdout); - } KILL(job->pid, SIGINT); } #endif /* RMT_WANTS_SIGNALS */ } -#endif - Lst_Close(stoppedJobs); + Lst_Close (jobs); if (runINTERRUPT && !touchFlag) { - interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); + interrupt = Targ_FindNode (".INTERRUPT", TARG_NOCREATE); if (interrupt != NILGNODE) { ignoreErrors = FALSE; - JobStart(interrupt, JOB_IGNDOTS, (Job *)0); + JobStart (interrupt, JOB_IGNDOTS, (Job *)0); while (nJobs) { Job_CatchOutput(); #ifndef RMT_WILL_WATCH - Job_CatchChildren(!usePipes); + Job_CatchChildren (!usePipes); #endif /* RMT_WILL_WATCH */ } } } - (void) eunlink(tfile); - exit(signo); + (void) unlink (tfile); + exit (0); } /* *----------------------------------------------------------------------- * Job_End -- * Do final processing such as the running of the commands - * attached to the .END target. + * attached to the .END target. * * Results: * Number of errors reported. @@ -2926,23 +2563,24 @@ JobInterrupt(runINTERRUPT, signo) *----------------------------------------------------------------------- */ int -Job_End() +Job_End () { - if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) { + if (postCommands != NILGNODE && !Lst_IsEmpty (postCommands->commands)) { if (errors) { - Error("Errors reported so .END ignored"); + Error ("Errors reported so .END ignored"); } else { - JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL); + JobStart (postCommands, JOB_SPECIAL | JOB_IGNDOTS, + (Job *)0); while (nJobs) { Job_CatchOutput(); #ifndef RMT_WILL_WATCH - Job_CatchChildren(!usePipes); + Job_CatchChildren (!usePipes); #endif /* RMT_WILL_WATCH */ } } } - (void) eunlink(tfile); + (void) unlink (tfile); return(errors); } @@ -2988,23 +2626,23 @@ Job_Wait() *----------------------------------------------------------------------- */ void -Job_AbortAll() +Job_AbortAll () { - LstNode ln; /* element in job table */ + LstNode ln; /* element in job table */ Job *job; /* the job descriptor in that element */ int foo; - + aborting = ABORT_ERROR; - + if (nJobs) { - (void) Lst_Open(jobs); - while ((ln = Lst_Next(jobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); + (void)Lst_Open (jobs); + while ((ln = Lst_Next (jobs)) != NILLNODE) { + job = (Job *) Lst_Datum (ln); /* * kill the child process with increasingly drastic signals to make - * darn sure it's dead. + * darn sure it's dead. */ #ifdef RMT_WANTS_SIGNALS if (job->flags & JOB_REMOTE) { @@ -3020,92 +2658,11 @@ Job_AbortAll() #endif /* RMT_WANTS_SIGNALS */ } } - + /* * Catch as many children as want to report in at first, then give up */ - while (waitpid((pid_t) -1, &foo, WNOHANG) > 0) + while (wait3(&foo, WNOHANG, (struct rusage *)0) > 0) continue; - (void) eunlink(tfile); -} - -#ifdef REMOTE -/*- - *----------------------------------------------------------------------- - * JobFlagForMigration -- - * Handle the eviction of a child. Called from RmtStatusChange. - * Flags the child as remigratable and then suspends it. - * - * Results: - * none. - * - * Side Effects: - * The job descriptor is flagged for remigration. - * - *----------------------------------------------------------------------- - */ -void -JobFlagForMigration(hostID) - int hostID; /* ID of host we used, for matching children. */ -{ - register Job *job; /* job descriptor for dead child */ - LstNode jnode; /* list element for finding job */ - - if (DEBUG(JOB)) { - (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID); - (void) fflush(stdout); - } - jnode = Lst_Find(jobs, (ClientData)hostID, JobCmpRmtID); - - if (jnode == NILLNODE) { - jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID); - if (jnode == NILLNODE) { - if (DEBUG(JOB)) { - Error("Evicting host(%d) not in table", hostID); - } - return; - } - } - job = (Job *) Lst_Datum(jnode); - - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobFlagForMigration(%d) found job '%s'.\n", hostID, - job->node->name); - (void) fflush(stdout); - } - - KILL(job->pid, SIGSTOP); - - job->flags |= JOB_REMIGRATE; -} - -#endif - -/*- - *----------------------------------------------------------------------- - * JobRestartJobs -- - * Tries to restart stopped jobs if there are slots available. - * Note that this tries to restart them regardless of pending errors. - * It's not good to leave stopped jobs lying around! - * - * Results: - * None. - * - * Side Effects: - * Resumes(and possibly migrates) jobs. - * - *----------------------------------------------------------------------- - */ -static void -JobRestartJobs() -{ - while (!jobFull && !Lst_IsEmpty(stoppedJobs)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "Job queue is not full. Restarting a stopped job.\n"); - (void) fflush(stdout); - } - JobRestart((Job *)Lst_DeQueue(stoppedJobs)); - } + (void) unlink (tfile); } |
