Changeset 51 for trunk/src/kmk/job.c


Ignore:
Timestamp:
Apr 7, 2003, 3:30:32 AM (22 years ago)
Author:
bird
Message:

kMk and porting to kLib.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/job.c

    r46 r51  
    1818 * 3. All advertising materials mentioning features or use of this software
    1919 *    must display the following acknowledgement:
    20  *      This product includes software developed by the University of
    21  *      California, Berkeley and its contributors.
     20 *      This product includes software developed by the University of
     21 *      California, Berkeley and its contributors.
    2222 * 4. Neither the name of the University nor the names of its contributors
    2323 *    may be used to endorse or promote products derived from this software
     
    3939#ifndef lint
    4040#if 0
    41 static char sccsid[] = "@(#)job.c       8.2 (Berkeley) 3/19/94";
     41static char sccsid[] = "@(#)job.c       8.2 (Berkeley) 3/19/94";
    4242#else
    4343static const char rcsid[] =
    4444  "$FreeBSD: src/usr.bin/make/job.c,v 1.17.2.2 2001/02/13 03:13:57 will Exp $";
    4545#endif
     46#define KLIBFILEDEF rcsid
    4647#endif /* not lint */
    4748
     
    5657/*-
    5758 * job.c --
    58  *      handle the creation etc. of our child processes.
     59 *      handle the creation etc. of our child processes.
    5960 *
    6061 * Interface:
    61  *      Job_Make                Start the creation of the given target.
    62  *
    63  *      Job_CatchChildren       Check for and handle the termination of any
    64  *                              children. This must be called reasonably
    65  *                              frequently to keep the whole make going at
    66  *                              a decent clip, since job table entries aren't
    67  *                              removed until their process is caught this way.
    68  *                              Its single argument is TRUE if the function
    69  *                              should block waiting for a child to terminate.
    70  *
    71  *      Job_CatchOutput         Print any output our children have produced.
    72  *                              Should also be called fairly frequently to
    73  *                              keep the user informed of what's going on.
    74  *                              If no output is waiting, it will block for
    75  *                              a time given by the SEL_* constants, below,
    76  *                              or until output is ready.
    77  *
    78  *      Job_Init                Called to intialize this module. in addition,
    79  *                              any commands attached to the .BEGIN target
    80  *                              are executed before this function returns.
    81  *                              Hence, the makefile must have been parsed
    82  *                              before this function is called.
    83  *
    84  *      Job_Full                Return TRUE if the job table is filled.
    85  *
    86  *      Job_Empty               Return TRUE if the job table is completely
    87  *                              empty.
    88  *
    89  *      Job_ParseShell          Given the line following a .SHELL target, parse
    90  *                              the line as a shell specification. Returns
    91  *                              FAILURE if the spec was incorrect.
    92  *
    93  *      Job_End                 Perform any final processing which needs doing.
    94  *                              This includes the execution of any commands
    95  *                              which have been/were attached to the .END
    96  *                              target. It should only be called when the
    97  *                              job table is empty.
    98  *
    99  *      Job_AbortAll            Abort all currently running jobs. It doesn't
    100  *                              handle output or do anything for the jobs,
    101  *                              just kills them. It should only be called in
    102  *                              an emergency, as it were.
    103  *
    104  *      Job_CheckCommands       Verify that the commands for a target are
    105  *                              ok. Provide them if necessary and possible.
    106  *
    107  *      Job_Touch               Update a target without really updating it.
    108  *
    109  *      Job_Wait                Wait for all currently-running jobs to finish.
     62 *      Job_Make                Start the creation of the given target.
     63 *
     64 *      Job_CatchChildren       Check for and handle the termination of any
     65 *                              children. This must be called reasonably
     66 *                              frequently to keep the whole make going at
     67 *                              a decent clip, since job table entries aren't
     68 *                              removed until their process is caught this way.
     69 *                              Its single argument is TRUE if the function
     70 *                              should block waiting for a child to terminate.
     71 *
     72 *      Job_CatchOutput         Print any output our children have produced.
     73 *                              Should also be called fairly frequently to
     74 *                              keep the user informed of what's going on.
     75 *                              If no output is waiting, it will block for
     76 *                              a time given by the SEL_* constants, below,
     77 *                              or until output is ready.
     78 *
     79 *      Job_Init                Called to intialize this module. in addition,
     80 *                              any commands attached to the .BEGIN target
     81 *                              are executed before this function returns.
     82 *                              Hence, the makefile must have been parsed
     83 *                              before this function is called.
     84 *
     85 *      Job_Full                Return TRUE if the job table is filled.
     86 *
     87 *      Job_Empty               Return TRUE if the job table is completely
     88 *                              empty.
     89 *
     90 *      Job_ParseShell          Given the line following a .SHELL target, parse
     91 *                              the line as a shell specification. Returns
     92 *                              FAILURE if the spec was incorrect.
     93 *
     94 *      Job_End                 Perform any final processing which needs doing.
     95 *                              This includes the execution of any commands
     96 *                              which have been/were attached to the .END
     97 *                              target. It should only be called when the
     98 *                              job table is empty.
     99 *
     100 *      Job_AbortAll            Abort all currently running jobs. It doesn't
     101 *                              handle output or do anything for the jobs,
     102 *                              just kills them. It should only be called in
     103 *                              an emergency, as it were.
     104 *
     105 *      Job_CheckCommands       Verify that the commands for a target are
     106 *                              ok. Provide them if necessary and possible.
     107 *
     108 *      Job_Touch               Update a target without really updating it.
     109 *
     110 *      Job_Wait                Wait for all currently-running jobs to finish.
    110111 */
    111112
     
    153154 * error handling variables
    154155 */
    155 static int      errors = 0;         /* number of errors reported */
    156 static int      aborting = 0;       /* why is the make aborting? */
    157 #define ABORT_ERROR     1           /* Because of an error */
    158 #define ABORT_INTERRUPT 2           /* Because it was interrupted */
    159 #define ABORT_WAIT      3           /* Waiting for jobs to finish */
     156static int      errors = 0;         /* number of errors reported */
     157static int      aborting = 0;       /* why is the make aborting? */
     158#define ABORT_ERROR     1           /* Because of an error */
     159#define ABORT_INTERRUPT 2           /* Because it was interrupted */
     160#define ABORT_WAIT      3           /* Waiting for jobs to finish */
    160161
    161162/*
     
    170171 * all the time.
    171172 */
    172 static GNode      *postCommands;    /* node containing commands to execute when
    173                                      * everything else is done */
    174 static int        numCommands;      /* The number of commands actually printed
    175                                      * for a target. Should this number be
    176                                      * 0, no shell will be executed. */
     173static GNode      *postCommands;    /* node containing commands to execute when
     174                                     * everything else is done */
     175static int        numCommands;      /* The number of commands actually printed
     176                                     * for a target. Should this number be
     177                                     * 0, no shell will be executed. */
    177178
    178179/*
    179180 * Return values from JobStart.
    180181 */
    181 #define JOB_RUNNING     0       /* Job is running */
    182 #define JOB_ERROR       1       /* Error in starting the job */
    183 #define JOB_FINISHED    2       /* The job is already finished */
    184 #define JOB_STOPPED     3       /* The job is stopped */
     182#define JOB_RUNNING     0       /* Job is running */
     183#define JOB_ERROR       1       /* Error in starting the job */
     184#define JOB_FINISHED    2       /* The job is already finished */
     185#define JOB_STOPPED     3       /* The job is stopped */
    185186
    186187/*
     
    229230}
    230231};
    231 static Shell    *commandShell = &shells[DEFSHELL];/* this is the shell to
    232                                                    * which we pass all
    233                                                    * commands in the Makefile.
    234                                                    * It is set by the
    235                                                    * Job_ParseShell function */
    236 static char     *shellPath = NULL,                /* full pathname of
    237                                                    * executable image */
    238                 *shellName;                       /* last component of shell */
     232static Shell    *commandShell = &shells[DEFSHELL];/* this is the shell to
     233                                                   * which we pass all
     234                                                   * commands in the Makefile.
     235                                                   * It is set by the
     236                                                   * Job_ParseShell function */
     237static char     *shellPath = NULL,                /* full pathname of
     238                                                   * executable image */
     239                *shellName;                       /* last component of shell */
    239240#endif /*!KMK*/
    240241
    241242
    242 static int      maxJobs;        /* The most children we can run at once */
    243 static int      maxLocal;       /* The most local ones we can have */
    244 STATIC int      nJobs;          /* The number of children currently running */
    245 STATIC int      nLocal;         /* The number of local children */
    246 STATIC Lst      jobs;           /* The structures that describe them */
    247 STATIC Boolean  jobFull;        /* Flag to tell when the job table is full. It
    248                                 * is set TRUE when (1) the total number of
    249                                 * running jobs equals the maximum allowed or
    250                                 * (2) a job can only be run locally, but
    251                                 * nLocal equals maxLocal */
     243static int      maxJobs;        /* The most children we can run at once */
     244static int      maxLocal;       /* The most local ones we can have */
     245STATIC int      nJobs;          /* The number of children currently running */
     246STATIC int      nLocal;         /* The number of local children */
     247STATIC Lst      jobs;           /* The structures that describe them */
     248STATIC Boolean  jobFull;        /* Flag to tell when the job table is full. It
     249                                * is set TRUE when (1) the total number of
     250                                * running jobs equals the maximum allowed or
     251                                * (2) a job can only be run locally, but
     252                                * nLocal equals maxLocal */
    252253#ifndef RMT_WILL_WATCH
    253 static fd_set   outputs;        /* Set of descriptors of pipes connected to
    254                                 * the output channels of children */
    255 #endif
    256 
    257 STATIC GNode    *lastNode;      /* The node for which output was most recently
    258                                 * produced. */
    259 STATIC char     *targFmt;       /* Format string to use to head output from a
    260                                 * job when it's not the most-recent job heard
    261                                 * from */
     254static fd_set   outputs;        /* Set of descriptors of pipes connected to
     255                                * the output channels of children */
     256#endif
     257
     258STATIC GNode    *lastNode;      /* The node for which output was most recently
     259                                * produced. */
     260STATIC char     *targFmt;       /* Format string to use to head output from a
     261                                * job when it's not the most-recent job heard
     262                                * from */
    262263
    263264#ifdef REMOTE
    264265# define TARG_FMT  "--- %s at %s ---\n" /* Default format */
    265266# define MESSAGE(fp, gn) \
    266         (void) fprintf(fp, targFmt, gn->name, gn->rem.hname);
     267        (void) fprintf(fp, targFmt, gn->name, gn->rem.hname);
    267268#else
    268269# define TARG_FMT  "--- %s ---\n" /* Default format */
    269270# define MESSAGE(fp, gn) \
    270         (void) fprintf(fp, targFmt, gn->name);
    271 #endif
    272 
     271        (void) fprintf(fp, targFmt, gn->name);
     272#endif
     273
     274#ifdef SIGCONT
    273275/*
    274276 * When JobStart attempts to run a job remotely but can't, and isn't allowed
     
    277279 * when the next job finishes.
    278280 */
    279 STATIC Lst      stoppedJobs;    /* Lst of Job structures describing
    280                                 * jobs that were stopped due to concurrency
    281                                 * limits or migration home */
    282 
     281STATIC Lst      stoppedJobs;    /* Lst of Job structures describing
     282                                * jobs that were stopped due to concurrency
     283                                * limits or migration home */
     284#endif /*SIGCONT*/
    283285
    284286#if defined(USE_PGRP) && defined(SYSV)
    285 # define KILL(pid, sig)         killpg(-(pid), (sig))
     287# define KILL(pid, sig)         killpg(-(pid), (sig))
    286288#else
    287289# if defined(USE_PGRP)
    288 #  define KILL(pid, sig)        killpg((pid), (sig))
     290#  define KILL(pid, sig)        killpg((pid), (sig))
    289291# else
    290 #  define KILL(pid, sig)        kill((pid), (sig))
     292#  define KILL(pid, sig)        kill((pid), (sig))
    291293# endif
    292294#endif
     
    298300 * really ugly, use dramamine sparingly. You have been warned.
    299301 */
    300 #define W_SETMASKED(st, val, fun)                               \
    301         {                                                       \
    302                 int sh = (int) ~0;                              \
    303                 int mask = fun(sh);                             \
    304                                                                 \
    305                 for (sh = 0; ((mask >> sh) & 1) == 0; sh++)     \
    306                         continue;                               \
    307                 *(st) = (*(st) & ~mask) | ((val) << sh);        \
    308         }
     302#define W_SETMASKED(st, val, fun)                               \
     303        {                                                       \
     304                int sh = (int) ~0;                              \
     305                int mask = fun(sh);                             \
     306                                                                \
     307                for (sh = 0; ((mask >> sh) & 1) == 0; sh++)     \
     308                        continue;                               \
     309                *(st) = (*(st) & ~mask) | ((val) << sh);        \
     310        }
    309311
    310312#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG)
     
    324326# endif
    325327#else
     328#ifdef USE_KLIB
     329static void JobFinish __P((Job *, KPROCRES *));
     330#else
    326331static void JobFinish __P((Job *, int *));
     332#endif
    327333static void JobExec __P((Job *, char **));
    328334#endif
    329 #ifndef KMK
    330335static void JobMakeArgv __P((Job *, char **));
    331 #endif
     336#ifdef SIGCONT
    332337static void JobRestart __P((Job *));
     338#endif
    333339static int JobStart __P((GNode *, int, Job *));
    334340static char *JobOutput __P((Job *, char *, char *, int));
     
    336342static Shell *JobMatchShell __P((char *));
    337343static void JobInterrupt __P((int, int));
     344#ifdef SIGCONT
    338345static void JobRestartJobs __P((void));
     346#endif
    339347
    340348/*-
    341349 *-----------------------------------------------------------------------
    342350 * JobCondPassSig --
    343  *      Pass a signal to a job if the job is remote or if USE_PGRP
    344  *      is defined.
     351 *      Pass a signal to a job if the job is remote or if USE_PGRP
     352 *      is defined.
    345353 *
    346354 * Results:
    347  *      === 0
     355 *      === 0
    348356 *
    349357 * Side Effects:
    350  *      None, except the job may bite it.
     358 *      None, except the job may bite it.
    351359 *
    352360 *-----------------------------------------------------------------------
     
    354362static int
    355363JobCondPassSig(jobp, signop)
    356     ClientData          jobp;       /* Job to biff */
    357     ClientData          signop;     /* Signal to send it */
     364    ClientData          jobp;       /* Job to biff */
     365    ClientData          signop;     /* Signal to send it */
    358366{
    359     Job *job = (Job *) jobp;
    360     int signo = *(int *) signop;
     367    Job *job = (Job *) jobp;
     368    int signo = *(int *) signop;
    361369#ifdef RMT_WANTS_SIGNALS
    362370    if (job->flags & JOB_REMOTE) {
    363         (void) Rmt_Signal(job, signo);
     371        (void) Rmt_Signal(job, signo);
    364372    } else {
    365         KILL(job->pid, signo);
     373        KILL(job->pid, signo);
    366374    }
    367375#else
     
    371379     */
    372380    if (DEBUG(JOB)) {
    373         (void) fprintf(stdout,
    374                        "JobCondPassSig passing signal %d to child %d.\n",
    375                        signo, job->pid);
    376         (void) fflush(stdout);
    377     }
     381        (void) fprintf(stdout,
     382                       "JobCondPassSig passing signal %d to child %d.\n",
     383                       signo, job->pid);
     384        (void) fflush(stdout);
     385    }
     386#if defined(USE_KLIB) && (defined(OS2) || defined(WIN32))
     387    switch (signo)
     388    {
     389        case SIGINT:
     390            kProcKill(job->pid, KPROCKILL_FLAGS_TREE | KPROCKILL_FLAGS_TYPE_INT);
     391            break;
     392        #ifdef SIGKILL
     393        case SIGKILL:
     394        #endif
     395        case SIGTERM:
     396            kProcKill(job->pid, KPROCKILL_FLAGS_TREE | KPROCKILL_FLAGS_TYPE_KILL);
     397            break;
     398    /* default: ignore signal as we don't really support it */
     399    }
     400#else
    378401    KILL(job->pid, signo);
     402#endif
    379403#endif
    380404    return 0;
     
    384408 *-----------------------------------------------------------------------
    385409 * JobPassSig --
    386  *      Pass a signal on to all remote jobs and to all local jobs if
    387  *      USE_PGRP is defined, then die ourselves.
     410 *      Pass a signal on to all remote jobs and to all local jobs if
     411 *      USE_PGRP is defined, then die ourselves.
    388412 *
    389413 * Results:
    390  *      None.
     414 *      None.
    391415 *
    392416 * Side Effects:
    393  *      We die by the same signal.
     417 *      We die by the same signal.
    394418 *
    395419 *-----------------------------------------------------------------------
     
    397421static void
    398422JobPassSig(signo)
    399     int     signo;      /* The signal number we've received */
     423    int     signo;      /* The signal number we've received */
    400424{
    401     sigset_t nmask, omask;
    402     struct sigaction act;
     425#if defined(USE_KLIB) && (defined(OS2) || defined(WIN32))
    403426
    404427    if (DEBUG(JOB)) {
    405         (void) fprintf(stdout, "JobPassSig(%d) called.\n", signo);
    406         (void) fflush(stdout);
     428        fprintf(stdout, "JobPassSig(%d) called.\n", signo);
     429        fflush(stdout);
    407430    }
    408431    Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
     
    414437     */
    415438    if (signo == SIGINT) {
    416         JobInterrupt(TRUE, signo);
    417     } else if ((signo == SIGHUP) || (signo == SIGTERM) || (signo == SIGQUIT)) {
    418         JobInterrupt(FALSE, signo);
    419     }
    420 
     439        JobInterrupt(TRUE, signo);
     440    } else if (signo == SIGTERM) {
     441        JobInterrupt(FALSE, signo);
     442    }
     443
     444
     445    if (DEBUG(JOB)) {
     446        fprintf(stdout,
     447                "JobPassSig passing signal to self, mask = %x.\n",
     448                ~0 & ~(1 << (signo-1)));
     449        fflush(stdout);
     450    }
     451    signal(signo, SIG_DFL);
     452    raise(signo);
     453
     454#ifdef SIGCONT
     455    signo = SIGCONT;
     456    Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
     457#endif
     458
     459
     460#else /* Not KLIB + OS2/Win32 */
     461    sigset_t nmask, omask;
     462    struct sigaction act;
     463
     464
     465    if (DEBUG(JOB)) {
     466        (void) fprintf(stdout, "JobPassSig(%d) called.\n", signo);
     467        (void) fflush(stdout);
     468    }
     469    Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
     470
     471    /*
     472     * Deal with proper cleanup based on the signal received. We only run
     473     * the .INTERRUPT target if the signal was in fact an interrupt. The other
     474     * three termination signals are more of a "get out *now*" command.
     475     */
     476    if (signo == SIGINT) {
     477        JobInterrupt(TRUE, signo);
     478    } else if ( 0
     479#ifdef SIGHUP  /* not all systems supports this signal */
     480               || (signo == SIGHUP)
     481#endif
     482               || (signo == SIGTERM)
     483#ifdef SIGQUIT /* not all systems supports this signal */
     484               || (signo == SIGQUIT)
     485#endif
     486               ) {
     487        JobInterrupt(FALSE, signo);
     488    }
     489
     490#ifdef SIGQUIT /* not all systems supports this signal */
    421491    /*
    422492     * Leave gracefully if SIGQUIT, rather than core dumping.
    423493     */
    424494    if (signo == SIGQUIT) {
    425         signo = SIGINT;
    426     }
    427 
     495        signo = SIGINT;
     496    }
     497#endif
     498
     499#if !defined(USE_KLIB) || !(defined(OS2) || defined(WIN32))
    428500    /*
    429501     * Send ourselves the signal now we've given the message to everyone else.
     
    439511    act.sa_flags = 0;
    440512    sigaction(signo, &act, NULL);
     513#endif
    441514
    442515    if (DEBUG(JOB)) {
    443         (void) fprintf(stdout,
    444                        "JobPassSig passing signal to self, mask = %x.\n",
    445                        ~0 & ~(1 << (signo-1)));
    446         (void) fflush(stdout);
     516        (void) fprintf(stdout,
     517                       "JobPassSig passing signal to self, mask = %x.\n",
     518                       ~0 & ~(1 << (signo-1)));
     519        (void) fflush(stdout);
    447520    }
    448521    (void) signal(signo, SIG_DFL);
     
    453526    Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
    454527
     528#if !defined(USE_KLIB) || !(defined(OS2) || defined(WIN32))
    455529    (void) sigprocmask(SIG_SETMASK, &omask, NULL);
    456530    sigprocmask(SIG_SETMASK, &omask, NULL);
    457531    act.sa_handler = JobPassSig;
    458532    sigaction(signo, &act, NULL);
     533#endif
     534#endif /* KLIB + OS2/Win32 */
    459535}
    460536
     
    462538 *-----------------------------------------------------------------------
    463539 * JobCmpPid  --
    464  *      Compare the pid of the job with the given pid and return 0 if they
    465  *      are equal. This function is called from Job_CatchChildren via
    466  *      Lst_Find to find the job descriptor of the finished job.
     540 *      Compare the pid of the job with the given pid and return 0 if they
     541 *      are equal. This function is called from Job_CatchChildren via
     542 *      Lst_Find to find the job descriptor of the finished job.
    467543 *
    468544 * Results:
    469  *      0 if the pid's match
     545 *      0 if the pid's match
    470546 *
    471547 * Side Effects:
    472  *      None
     548 *      None
    473549 *-----------------------------------------------------------------------
    474550 */
    475551static int
    476552JobCmpPid(job, pid)
    477     ClientData        job;      /* job to examine */
    478     ClientData        pid;      /* process id desired */
     553    ClientData        job;      /* job to examine */
     554    ClientData        pid;      /* process id desired */
    479555{
    480556    return *(int *) pid - ((Job *) job)->pid;
     
    485561 *-----------------------------------------------------------------------
    486562 * JobCmpRmtID  --
    487  *      Compare the rmtID of the job with the given rmtID and return 0 if they
    488  *      are equal.
     563 *      Compare the rmtID of the job with the given rmtID and return 0 if they
     564 *      are equal.
    489565 *
    490566 * Results:
    491  *      0 if the rmtID's match
     567 *      0 if the rmtID's match
    492568 *
    493569 * Side Effects:
    494  *      None.
     570 *      None.
    495571 *-----------------------------------------------------------------------
    496572 */
    497573static int
    498574JobCmpRmtID(job, rmtID)
    499     ClientData      job;        /* job to examine */
    500     ClientData      rmtID;      /* remote id desired */
     575    ClientData      job;        /* job to examine */
     576    ClientData      rmtID;      /* remote id desired */
    501577{
    502578    return(*(int *) rmtID - *(int *) job->rmtID);
     
    507583 *-----------------------------------------------------------------------
    508584 * JobPrintCommand  --
    509  *      Put out another command for the given job. If the command starts
    510  *      with an @ or a - we process it specially. In the former case,
    511  *      so long as the -s and -n flags weren't given to make, we stick
    512  *      a shell-specific echoOff command in the script. In the latter,
    513  *      we ignore errors for the entire job, unless the shell has error
    514  *      control.
    515  *      If the command is just "..." we take all future commands for this
    516  *      job to be commands to be executed once the entire graph has been
    517  *      made and return non-zero to signal that the end of the commands
    518  *      was reached. These commands are later attached to the postCommands
    519  *      node and executed by Job_End when all things are done.
    520  *      This function is called from JobStart via Lst_ForEach.
     585 *      Put out another command for the given job. If the command starts
     586 *      with an @ or a - we process it specially. In the former case,
     587 *      so long as the -s and -n flags weren't given to make, we stick
     588 *      a shell-specific echoOff command in the script. In the latter,
     589 *      we ignore errors for the entire job, unless the shell has error
     590 *      control.
     591 *      If the command is just "..." we take all future commands for this
     592 *      job to be commands to be executed once the entire graph has been
     593 *      made and return non-zero to signal that the end of the commands
     594 *      was reached. These commands are later attached to the postCommands
     595 *      node and executed by Job_End when all things are done.
     596 *      This function is called from JobStart via Lst_ForEach.
    521597 *
    522598 * Results:
    523  *      Always 0, unless the command was "..."
     599 *      Always 0, unless the command was "..."
    524600 *
    525601 * Side Effects:
    526  *      If the command begins with a '-' and the shell has no error control,
    527  *      the JOB_IGNERR flag is set in the job descriptor.
    528  *      If the command is "..." and we're not ignoring such things,
    529  *      tailCmds is set to the successor node of the cmd.
    530  *      numCommands is incremented if the command is actually printed.
     602 *      If the command begins with a '-' and the shell has no error control,
     603 *      the JOB_IGNERR flag is set in the job descriptor.
     604 *      If the command is "..." and we're not ignoring such things,
     605 *      tailCmds is set to the successor node of the cmd.
     606 *      numCommands is incremented if the command is actually printed.
    531607 *-----------------------------------------------------------------------
    532608 */
    533609static int
    534610JobPrintCommand(cmdp, jobp)
    535     ClientData    cmdp;             /* command string to print */
    536     ClientData    jobp;             /* job for which to print it */
     611    ClientData    cmdp;             /* command string to print */
     612    ClientData    jobp;             /* job for which to print it */
    537613{
    538     Boolean       noSpecials;       /* true if we shouldn't worry about
    539                                      * inserting special commands into
    540                                      * the input stream. */
     614    Boolean       noSpecials;       /* true if we shouldn't worry about
     615                                     * inserting special commands into
     616                                     * the input stream. */
    541617    Boolean       shutUp = FALSE;   /* true if we put a no echo command
    542                                      * into the command file */
    543     Boolean       errOff = FALSE;   /* true if we turned error checking
    544                                      * off before printing the command
    545                                      * and need to turn it back on */
    546     char          *cmdTemplate;     /* Template to use when printing the
    547                                      * command */
    548     char          *cmdStart;        /* Start of expanded command */
    549     LstNode       cmdNode;          /* Node for replacing the command */
    550     char          *cmd = (char *) cmdp;
     618                                     * into the command file */
     619    Boolean       errOff = FALSE;   /* true if we turned error checking
     620                                     * off before printing the command
     621                                     * and need to turn it back on */
     622    char          *cmdTemplate;     /* Template to use when printing the
     623                                     * command */
     624    char          *cmdStart;        /* Start of expanded command */
     625    LstNode       cmdNode;          /* Node for replacing the command */
     626    char          *cmd = (char *) cmdp;
    551627    Job           *job = (Job *) jobp;
    552628
     
    554630
    555631    if (strcmp(cmd, "...") == 0) {
    556         job->node->type |= OP_SAVE_CMDS;
    557         if ((job->flags & JOB_IGNDOTS) == 0) {
    558             job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
    559                                                 (ClientData)cmd));
    560             return 1;
    561         }
    562         return 0;
    563     }
    564 
    565 #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) {    \
    566         (void) fprintf(stdout, fmt, arg);       \
    567         (void) fflush(stdout);                  \
    568     }                                           \
    569    (void) fprintf(job->cmdFILE, fmt, arg);      \
     632        job->node->type |= OP_SAVE_CMDS;
     633        if ((job->flags & JOB_IGNDOTS) == 0) {
     634            job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
     635                                                (ClientData)cmd));
     636            return 1;
     637        }
     638        return 0;
     639    }
     640
     641#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) {    \
     642        (void) fprintf(stdout, fmt, arg);       \
     643        (void) fflush(stdout);                  \
     644    }                                           \
     645   (void) fprintf(job->cmdFILE, fmt, arg);      \
    570646   (void) fflush(job->cmdFILE);
    571647
     
    586662     */
    587663    while (*cmd == '@' || *cmd == '-') {
    588         if (*cmd == '@') {
    589             shutUp = DEBUG(LOUD) ? FALSE : TRUE;
    590         } else {
    591             errOff = TRUE;
    592         }
    593         cmd++;
     664        if (*cmd == '@') {
     665            shutUp = DEBUG(LOUD) ? FALSE : TRUE;
     666        } else {
     667            errOff = TRUE;
     668        }
     669        cmd++;
    594670    }
    595671
    596672    while (isspace((unsigned char) *cmd))
    597         cmd++;
     673        cmd++;
    598674
    599675    #ifndef KMK
    600676    if (shutUp) {
    601         if (!(job->flags & JOB_SILENT) && !noSpecials &&
    602             commandShell->hasEchoCtl) {
    603                 DBPRINTF("%s\n", commandShell->echoOff);
    604         } else {
    605             shutUp = FALSE;
    606         }
     677        if (!(job->flags & JOB_SILENT) && !noSpecials &&
     678            commandShell->hasEchoCtl) {
     679                DBPRINTF("%s\n", commandShell->echoOff);
     680        } else {
     681            shutUp = FALSE;
     682        }
    607683    }
    608684    #endif
    609685
    610686    if (errOff) {
    611         if ( !(job->flags & JOB_IGNERR) && !noSpecials) {
     687        if ( !(job->flags & JOB_IGNERR) && !noSpecials) {
    612688            #ifdef KMK
    613689            errOff = FALSE;
    614690            #else
    615             if (commandShell->hasErrCtl) {
    616                 /*
    617                 * we don't want the error-control commands showing
    618                 * up either, so we turn off echoing while executing
    619                 * them. We could put another field in the shell
    620                 * structure to tell JobDoOutput to look for this
    621                 * string too, but why make it any more complex than
    622                 * it already is?
    623                 */
    624                 if (!(job->flags & JOB_SILENT) && !shutUp &&
    625                     commandShell->hasEchoCtl) {
    626                         DBPRINTF("%s\n", commandShell->echoOff);
    627                         DBPRINTF("%s\n", commandShell->ignErr);
    628                         DBPRINTF("%s\n", commandShell->echoOn);
    629                 } else {
    630                     DBPRINTF("%s\n", commandShell->ignErr);
    631                 }
    632             } else if (commandShell->ignErr &&
    633                       (*commandShell->ignErr != '\0'))
    634             {
    635                 /*
    636                 * The shell has no error control, so we need to be
    637                 * weird to get it to ignore any errors from the command.
    638                 * If echoing is turned on, we turn it off and use the
    639                 * errCheck template to echo the command. Leave echoing
    640                 * off so the user doesn't see the weirdness we go through
    641                 * to ignore errors. Set cmdTemplate to use the weirdness
    642                 * instead of the simple "%s\n" template.
    643                 */
    644                 if (!(job->flags & JOB_SILENT) && !shutUp &&
    645                     commandShell->hasEchoCtl) {
    646                         DBPRINTF("%s\n", commandShell->echoOff);
    647                         DBPRINTF(commandShell->errCheck, cmd);
    648                         shutUp = TRUE;
    649                 }
    650                 cmdTemplate = commandShell->ignErr;
    651                 /*
    652                 * The error ignoration (hee hee) is already taken care
    653                 * of by the ignErr template, so pretend error checking
    654                 * is still on.
    655                 */
    656                 errOff = FALSE;
    657             } else {
    658                 errOff = FALSE;
    659             }
     691            if (commandShell->hasErrCtl) {
     692                /*
     693                * we don't want the error-control commands showing
     694                * up either, so we turn off echoing while executing
     695                * them. We could put another field in the shell
     696                * structure to tell JobDoOutput to look for this
     697                * string too, but why make it any more complex than
     698                * it already is?
     699                */
     700                if (!(job->flags & JOB_SILENT) && !shutUp &&
     701                    commandShell->hasEchoCtl) {
     702                        DBPRINTF("%s\n", commandShell->echoOff);
     703                        DBPRINTF("%s\n", commandShell->ignErr);
     704                        DBPRINTF("%s\n", commandShell->echoOn);
     705                } else {
     706                    DBPRINTF("%s\n", commandShell->ignErr);
     707                }
     708            } else if (commandShell->ignErr &&
     709                      (*commandShell->ignErr != '\0'))
     710            {
     711                /*
     712                * The shell has no error control, so we need to be
     713                * weird to get it to ignore any errors from the command.
     714                * If echoing is turned on, we turn it off and use the
     715                * errCheck template to echo the command. Leave echoing
     716                * off so the user doesn't see the weirdness we go through
     717                * to ignore errors. Set cmdTemplate to use the weirdness
     718                * instead of the simple "%s\n" template.
     719                */
     720                if (!(job->flags & JOB_SILENT) && !shutUp &&
     721                    commandShell->hasEchoCtl) {
     722                        DBPRINTF("%s\n", commandShell->echoOff);
     723                        DBPRINTF(commandShell->errCheck, cmd);
     724                        shutUp = TRUE;
     725                }
     726                cmdTemplate = commandShell->ignErr;
     727                /*
     728                * The error ignoration (hee hee) is already taken care
     729                * of by the ignErr template, so pretend error checking
     730                * is still on.
     731                */
     732                errOff = FALSE;
     733            } else {
     734                errOff = FALSE;
     735            }
    660736            #endif
    661         } else {
    662             errOff = FALSE;
    663         }
     737        } else {
     738            errOff = FALSE;
     739        }
    664740    }
    665741
     
    668744    #ifndef KMK /*todo*/
    669745    if (errOff) {
    670         /*
    671         * If echoing is already off, there's no point in issuing the
    672         * echoOff command. Otherwise we issue it and pretend it was on
    673         * for the whole command...
    674         */
    675         if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
    676             DBPRINTF("%s\n", commandShell->echoOff);
    677             shutUp = TRUE;
    678         }
    679         DBPRINTF("%s\n", commandShell->errCheck);
     746        /*
     747        * If echoing is already off, there's no point in issuing the
     748        * echoOff command. Otherwise we issue it and pretend it was on
     749        * for the whole command...
     750        */
     751        if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
     752            DBPRINTF("%s\n", commandShell->echoOff);
     753            shutUp = TRUE;
     754        }
     755        DBPRINTF("%s\n", commandShell->errCheck);
    680756    }
    681757    if (shutUp) {
    682         DBPRINTF("%s\n", commandShell->echoOn);
     758        DBPRINTF("%s\n", commandShell->echoOn);
    683759    }
    684760    #endif
     
    689765 *-----------------------------------------------------------------------
    690766 * JobSaveCommand --
    691  *      Save a command to be executed when everything else is done.
    692  *      Callback function for JobFinish...
     767 *      Save a command to be executed when everything else is done.
     768 *      Callback function for JobFinish...
    693769 *
    694770 * Results:
    695  *      Always returns 0
     771 *      Always returns 0
    696772 *
    697773 * Side Effects:
    698  *      The command is tacked onto the end of postCommands's commands list.
     774 *      The command is tacked onto the end of postCommands's commands list.
    699775 *
    700776 *-----------------------------------------------------------------------
     
    714790 *-----------------------------------------------------------------------
    715791 * JobClose --
    716  *      Called to close both input and output pipes when a job is finished.
     792 *      Called to close both input and output pipes when a job is finished.
    717793 *
    718794 * Results:
    719  *      Nada
     795 *      Nada
    720796 *
    721797 * Side Effects:
    722  *      The file descriptors associated with the job are closed.
     798 *      The file descriptors associated with the job are closed.
    723799 *
    724800 *-----------------------------------------------------------------------
     
    728804    Job *job;
    729805{
     806#ifdef USE_PIPES
    730807    if (usePipes) {
    731808#ifdef RMT_WILL_WATCH
    732         Rmt_Ignore(job->inPipe);
     809        Rmt_Ignore(job->inPipe);
    733810#else
    734         FD_CLR(job->inPipe, &outputs);
    735 #endif
    736         if (job->outPipe != job->inPipe) {
    737            (void) close(job->outPipe);
    738         }
    739         JobDoOutput(job, TRUE);
    740         (void) close(job->inPipe);
     811        FD_CLR(job->inPipe, &outputs);
     812#endif
     813        if (job->outPipe != job->inPipe) {
     814           (void) close(job->outPipe);
     815        }
     816        JobDoOutput(job, TRUE);
     817        (void) close(job->inPipe);
    741818    } else {
    742         (void) close(job->outFd);
    743         JobDoOutput(job, TRUE);
    744     }
     819        (void) close(job->outFd);
     820        JobDoOutput(job, TRUE);
     821    }
     822
     823#else  /* Don't use Pipes */
     824    close(job->outFd);
     825    JobDoOutput(job, TRUE);
     826#endif /* USE_PIPES */
    745827}
    746828
     
    748830 *-----------------------------------------------------------------------
    749831 * JobFinish  --
    750  *      Do final processing for the given job including updating
    751  *      parents and starting new jobs as available/necessary. Note
    752  *      that we pay no attention to the JOB_IGNERR flag here.
    753  *      This is because when we're called because of a noexecute flag
    754  *      or something, jstat.w_status is 0 and when called from
    755  *      Job_CatchChildren, the status is zeroed if it s/b ignored.
     832 *      Do final processing for the given job including updating
     833 *      parents and starting new jobs as available/necessary. Note
     834 *      that we pay no attention to the JOB_IGNERR flag here.
     835 *      This is because when we're called because of a noexecute flag
     836 *      or something, jstat.w_status is 0 and when called from
     837 *      Job_CatchChildren, the status is zeroed if it s/b ignored.
    756838 *
    757839 * Results:
    758  *      None
     840 *      None
    759841 *
    760842 * Side Effects:
    761  *      Some nodes may be put on the toBeMade queue.
    762  *      Final commands for the job are placed on postCommands.
    763  *
    764  *      If we got an error and are aborting (aborting == ABORT_ERROR) and
    765  *      the job list is now empty, we are done for the day.
    766  *      If we recognized an error (errors !=0), we set the aborting flag
    767  *      to ABORT_ERROR so no more jobs will be started.
     843 *      Some nodes may be put on the toBeMade queue.
     844 *      Final commands for the job are placed on postCommands.
     845 *
     846 *      If we got an error and are aborting (aborting == ABORT_ERROR) and
     847 *      the job list is now empty, we are done for the day.
     848 *      If we recognized an error (errors !=0), we set the aborting flag
     849 *      to ABORT_ERROR so no more jobs will be started.
    768850 *-----------------------------------------------------------------------
    769851 */
     
    771853static void
    772854JobFinish(job, status)
    773     Job         *job;             /* job to finish */
    774     int         *status;          /* sub-why job went away */
     855    Job         *job;             /* job to finish */
     856#ifdef USE_KLIB
     857    KPROCRES    *status;          /* sub-why job went away */
     858#else
     859    int         *status;          /* sub-why job went away */
     860#endif
    775861{
    776     Boolean      done;
     862#ifdef USE_KLIB
     863    Boolean      done;
     864
     865    if ( ( (status->fFlags & KPROCRES_FLAGS_NORMAL) && status->uExitCode != 0 && !(job->flags & JOB_IGNERR) )
     866        || !(status->fFlags & KPROCRES_FLAGS_NORMAL)
     867         )
     868    {
     869        /*
     870         * If it exited non-zero and either we're doing things our
     871         * way or we're not ignoring errors, the job is finished.
     872         * Similarly, if the shell died because of a signal
     873         * the job is also finished. In these
     874         * cases, finish out the job's output before printing the exit
     875         * status...
     876         */
     877        JobClose(job);
     878        if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
     879           (void) fclose(job->cmdFILE);
     880           job->cmdFILE = NULL;
     881        }
     882        done = TRUE;
     883    } else if (status->fFlags & KPROCRES_FLAGS_NORMAL) {
     884        /*
     885         * Deal with ignored errors in -B mode. We need to print a message
     886         * telling of the ignored error as well as setting status.w_status
     887         * to 0 so the next command gets run. To do this, we set done to be
     888         * TRUE if in -B mode and the job exited non-zero.
     889         */
     890        done = status->uExitCode != 0;
     891        /*
     892         * Old comment said: "Note we don't
     893         * want to close down any of the streams until we know we're at the
     894         * end."
     895         * But we do. Otherwise when are we going to print the rest of the
     896         * stuff?
     897         */
     898        JobClose(job);
     899    } else {
     900        /*
     901         * No need to close things down or anything.
     902         */
     903        done = FALSE;
     904    }
     905
     906    if (    done
     907        || DEBUG(JOB))
     908    {
     909        FILE      *out = stdout;
     910        if (compatMake && !usePipes && (job->flags & JOB_IGNERR))
     911        {
     912            /*
     913             * If output is going to a file and this job is ignoring
     914             * errors, arrange to have the exit status sent to the
     915             * output file as well.
     916             */
     917            out = fdopen(job->outFd, "w");
     918        }
     919
     920        if (status->fFlags & KPROCRES_FLAGS_NORMAL)
     921        {
     922            if (DEBUG(JOB))
     923            {
     924                fprintf(stdout, "Process %d exited.\n", job->pid);
     925                fflush(stdout);
     926            }
     927            if (status->uExitCode != 0)
     928            {
     929#ifdef USE_PIPES
     930                if (usePipes && job->node != lastNode)
     931                {
     932                    MESSAGE(out, job->node);
     933                    lastNode = job->node;
     934                }
     935#endif
     936                fprintf(out, "*** Error code %d%s\n",
     937                        status->uExitCode,
     938                        (job->flags & JOB_IGNERR) ? "(ignored)" : "");
     939
     940                if (job->flags & JOB_IGNERR)
     941                    status->uExitCode = 0;
     942            }
     943            else if (DEBUG(JOB))
     944            {
     945#ifdef USE_PIPES
     946                if (usePipes && job->node != lastNode)
     947                {
     948                    MESSAGE(out, job->node);
     949                    lastNode = job->node;
     950                }
     951#endif
     952                fprintf(out, "*** Completed successfully\n");
     953            }
     954        }
     955        else
     956        {
     957#ifdef USE_PIPES
     958            if (usePipes && job->node != lastNode)
     959            {
     960                MESSAGE(out, job->node);
     961                lastNode = job->node;
     962            }
     963#endif
     964            fprintf(out, "*** Abnormal End\n");
     965        }
     966
     967        fflush(out);
     968    }
     969
     970    /*
     971     * Now handle the -B-mode stuff. If the beast still isn't finished,
     972     * try and restart the job on the next command. If JobStart says it's
     973     * ok, it's ok. If there's an error, this puppy is done.
     974     */
     975    if (    compatMake
     976        && (status->fFlags & KPROCRES_FLAGS_NORMAL)
     977        && !Lst_IsAtEnd(job->node->commands)
     978        )
     979    {
     980        switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job))
     981        {
     982        case JOB_RUNNING:
     983            done = FALSE;
     984            break;
     985        case JOB_ERROR:
     986            done = TRUE;
     987            status->uExitCode = EXIT_FAILURE;
     988            break;
     989        case JOB_FINISHED:
     990            /*
     991             * If we got back a JOB_FINISHED code, JobStart has already
     992             * called Make_Update and freed the job descriptor. We set
     993             * done to false here to avoid fake cycles and double frees.
     994             * JobStart needs to do the update so we can proceed up the
     995             * graph when given the -n flag..
     996             */
     997            done = FALSE;
     998            break;
     999        }
     1000    } else {
     1001        done = TRUE;
     1002    }
     1003
     1004
     1005    if (   done
     1006        && aborting != ABORT_ERROR
     1007        && aborting != ABORT_INTERRUPT
     1008        && (status->fFlags & KPROCRES_FLAGS_NORMAL)
     1009        && status->uExitCode == 0
     1010        )
     1011    {
     1012        /*
     1013         * As long as we aren't aborting and the job didn't return a non-zero
     1014         * status that we shouldn't ignore, we call Make_Update to update
     1015         * the parents. In addition, any saved commands for the node are placed
     1016         * on the .END target.
     1017         */
     1018        if (job->tailCmds != NILLNODE) {
     1019            Lst_ForEachFrom(job->node->commands, job->tailCmds,
     1020                             JobSaveCommand,
     1021                            (ClientData)job->node);
     1022        }
     1023        job->node->made = MADE;
     1024        Make_Update(job->node);
     1025        efree((Address)job);
     1026    }
     1027    else if (!(status->fFlags & KPROCRES_FLAGS_NORMAL) || status->uExitCode != 0)
     1028    {
     1029        errors += 1;
     1030        efree((Address)job);
     1031    }
     1032
     1033    /*
     1034     * Set aborting if any error.
     1035     */
     1036    if (errors && !keepgoing && (aborting != ABORT_INTERRUPT))
     1037    {
     1038        /*
     1039         * If we found any errors in this batch of children and the -k flag
     1040         * wasn't given, we set the aborting flag so no more jobs get
     1041         * started.
     1042         */
     1043        aborting = ABORT_ERROR;
     1044    }
     1045
     1046    if ((aborting == ABORT_ERROR) && Job_Empty())
     1047    {
     1048        /*
     1049         * If we are aborting and the job table is now empty, we finish.
     1050         */
     1051        Finish(errors);
     1052    }
     1053
     1054
     1055#else /* Don't use kLib */
     1056    Boolean      done;
    7771057
    7781058    if ((WIFEXITED(*status) &&
    779         (((WEXITSTATUS(*status) != 0) && !(job->flags & JOB_IGNERR)))) ||
    780         (WIFSIGNALED(*status) && (WTERMSIG(*status) != SIGCONT)))
     1059        (((WEXITSTATUS(*status) != 0) && !(job->flags & JOB_IGNERR)))) ||
     1060        (WIFSIGNALED(*status) && (WTERMSIG(*status) != SIGCONT)))
    7811061    {
    782         /*
    783         * If it exited non-zero and either we're doing things our
    784         * way or we're not ignoring errors, the job is finished.
    785         * Similarly, if the shell died because of a signal
    786         * the job is also finished. In these
    787         * cases, finish out the job's output before printing the exit
    788         * status...
    789         */
     1062        /*
     1063        * If it exited non-zero and either we're doing things our
     1064        * way or we're not ignoring errors, the job is finished.
     1065        * Similarly, if the shell died because of a signal
     1066        * the job is also finished. In these
     1067        * cases, finish out the job's output before printing the exit
     1068        * status...
     1069        */
    7901070#ifdef REMOTE
    791         KILL(job->pid, SIGCONT);
    792 #endif
    793         JobClose(job);
    794         if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
    795            (void) fclose(job->cmdFILE);
    796         }
    797         done = TRUE;
     1071        KILL(job->pid, SIGCONT);
     1072#endif
     1073        JobClose(job);
     1074        if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
     1075           (void) fclose(job->cmdFILE);
     1076        }
     1077        done = TRUE;
    7981078#ifdef REMOTE
    799         if (job->flags & JOB_REMOTE)
    800             Rmt_Done(job->rmtID, job->node);
     1079        if (job->flags & JOB_REMOTE)
     1080            Rmt_Done(job->rmtID, job->node);
    8011081#endif
    8021082    } else if (WIFEXITED(*status)) {
    803         /*
    804         * Deal with ignored errors in -B mode. We need to print a message
    805         * telling of the ignored error as well as setting status.w_status
    806         * to 0 so the next command gets run. To do this, we set done to be
    807         * TRUE if in -B mode and the job exited non-zero.
    808         */
    809         done = WEXITSTATUS(*status) != 0;
    810         /*
    811         * Old comment said: "Note we don't
    812         * want to close down any of the streams until we know we're at the
    813         * end."
    814         * But we do. Otherwise when are we going to print the rest of the
    815         * stuff?
    816         */
    817         JobClose(job);
     1083        /*
     1084        * Deal with ignored errors in -B mode. We need to print a message
     1085        * telling of the ignored error as well as setting status.w_status
     1086        * to 0 so the next command gets run. To do this, we set done to be
     1087        * TRUE if in -B mode and the job exited non-zero.
     1088        */
     1089        done = WEXITSTATUS(*status) != 0;
     1090        /*
     1091        * Old comment said: "Note we don't
     1092        * want to close down any of the streams until we know we're at the
     1093        * end."
     1094        * But we do. Otherwise when are we going to print the rest of the
     1095        * stuff?
     1096        */
     1097        JobClose(job);
    8181098#ifdef REMOTE
    819         if (job->flags & JOB_REMOTE)
    820             Rmt_Done(job->rmtID, job->node);
     1099        if (job->flags & JOB_REMOTE)
     1100            Rmt_Done(job->rmtID, job->node);
    8211101#endif /* REMOTE */
    8221102    } else {
    823         /*
    824         * No need to close things down or anything.
    825         */
    826         done = FALSE;
     1103        /*
     1104        * No need to close things down or anything.
     1105        */
     1106        done = FALSE;
    8271107    }
    8281108
    8291109    if (done ||
    830         WIFSTOPPED(*status) ||
    831         (WIFSIGNALED(*status) && (WTERMSIG(*status) == SIGCONT)) ||
    832         DEBUG(JOB))
     1110        WIFSTOPPED(*status) ||
     1111        (WIFSIGNALED(*status) && (WTERMSIG(*status) == SIGCONT)) ||
     1112        DEBUG(JOB))
    8331113    {
    834         FILE      *out;
    835 
    836         if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) {
    837             /*
    838              * If output is going to a file and this job is ignoring
    839              * errors, arrange to have the exit status sent to the
    840              * output file as well.
    841              */
    842             out = fdopen(job->outFd, "w");
    843         } else {
    844             out = stdout;
    845         }
    846 
    847         if (WIFEXITED(*status)) {
    848             if (DEBUG(JOB)) {
    849                 (void) fprintf(stdout, "Process %d exited.\n", job->pid);
    850                 (void) fflush(stdout);
    851             }
    852             if (WEXITSTATUS(*status) != 0) {
    853                 if (usePipes && job->node != lastNode) {
    854                     MESSAGE(out, job->node);
    855                     lastNode = job->node;
    856                 }
    857                 (void) fprintf(out, "*** Error code %d%s\n",
    858                                WEXITSTATUS(*status),
    859                                (job->flags & JOB_IGNERR) ? "(ignored)" : "");
    860 
    861                 if (job->flags & JOB_IGNERR) {
    862                     *status = 0;
    863                 }
    864             } else if (DEBUG(JOB)) {
    865                 if (usePipes && job->node != lastNode) {
    866                     MESSAGE(out, job->node);
    867                     lastNode = job->node;
    868                 }
    869                 (void) fprintf(out, "*** Completed successfully\n");
    870             }
    871         } else if (WIFSTOPPED(*status)) {
    872             if (DEBUG(JOB)) {
    873                 (void) fprintf(stdout, "Process %d stopped.\n", job->pid);
    874                 (void) fflush(stdout);
    875             }
    876             if (usePipes && job->node != lastNode) {
    877                 MESSAGE(out, job->node);
    878                 lastNode = job->node;
    879             }
    880             if (!(job->flags & JOB_REMIGRATE)) {
    881                 (void) fprintf(out, "*** Stopped -- signal %d\n",
    882                     WSTOPSIG(*status));
    883             }
    884             job->flags |= JOB_RESUME;
    885             (void)Lst_AtEnd(stoppedJobs, (ClientData)job);
    886 #ifdef REMOTE
    887             if (job->flags & JOB_REMIGRATE)
    888                 JobRestart(job);
    889 #endif
    890             (void) fflush(out);
    891             return;
    892         } else if (WTERMSIG(*status) == SIGCONT) {
    893             /*
    894              * If the beastie has continued, shift the Job from the stopped
    895              * list to the running one (or re-stop it if concurrency is
    896              * exceeded) and go and get another child.
    897              */
    898             if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) {
    899                 if (usePipes && job->node != lastNode) {
    900                     MESSAGE(out, job->node);
    901                     lastNode = job->node;
    902                 }
    903                 (void) fprintf(out, "*** Continued\n");
    904             }
    905             if (!(job->flags & JOB_CONTINUING)) {
    906                 if (DEBUG(JOB)) {
    907                     (void) fprintf(stdout,
    908                                    "Warning: process %d was not continuing.\n",
    909                                    job->pid);
    910                     (void) fflush(stdout);
    911                 }
     1114        FILE      *out;
     1115
     1116        if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) {
     1117            /*
     1118             * If output is going to a file and this job is ignoring
     1119             * errors, arrange to have the exit status sent to the
     1120             * output file as well.
     1121             */
     1122            out = fdopen(job->outFd, "w");
     1123        } else {
     1124            out = stdout;
     1125        }
     1126
     1127        if (WIFEXITED(*status)) {
     1128            if (DEBUG(JOB)) {
     1129                (void) fprintf(stdout, "Process %d exited.\n", job->pid);
     1130                (void) fflush(stdout);
     1131            }
     1132            if (WEXITSTATUS(*status) != 0) {
     1133#ifdef USE_PIPES
     1134                if (usePipes && job->node != lastNode) {
     1135                    MESSAGE(out, job->node);
     1136                    lastNode = job->node;
     1137                }
     1138#endif
     1139                (void) fprintf(out, "*** Error code %d%s\n",
     1140                               WEXITSTATUS(*status),
     1141                               (job->flags & JOB_IGNERR) ? "(ignored)" : "");
     1142
     1143                if (job->flags & JOB_IGNERR) {
     1144                    *status = 0;
     1145                }
     1146            } else if (DEBUG(JOB)) {
     1147#ifdef USE_PIPES
     1148                if (usePipes && job->node != lastNode) {
     1149                    MESSAGE(out, job->node);
     1150                    lastNode = job->node;
     1151                }
     1152#endif
     1153                (void) fprintf(out, "*** Completed successfully\n");
     1154            }
     1155        } else if (WIFSTOPPED(*status)) {
     1156            if (DEBUG(JOB)) {
     1157                (void) fprintf(stdout, "Process %d stopped.\n", job->pid);
     1158                (void) fflush(stdout);
     1159            }
     1160#ifdef USE_PIPES
     1161            if (usePipes && job->node != lastNode) {
     1162                MESSAGE(out, job->node);
     1163                lastNode = job->node;
     1164            }
     1165#endif
     1166            if (!(job->flags & JOB_REMIGRATE)) {
     1167                (void) fprintf(out, "*** Stopped -- signal %d\n",
     1168                    WSTOPSIG(*status));
     1169            }
     1170            job->flags |= JOB_RESUME;
     1171            (void)Lst_AtEnd(stoppedJobs, (ClientData)job);
     1172#if defined(REMOTE) && defined(SIGCONT)
     1173            if (job->flags & JOB_REMIGRATE)
     1174                JobRestart(job);
     1175#endif
     1176            (void) fflush(out);
     1177            return;
     1178        } else if (WTERMSIG(*status) == SIGCONT) {
     1179            /*
     1180             * If the beastie has continued, shift the Job from the stopped
     1181             * list to the running one (or re-stop it if concurrency is
     1182             * exceeded) and go and get another child.
     1183             */
     1184            if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) {
     1185#ifdef USE_PIPES
     1186                if (usePipes && job->node != lastNode) {
     1187                    MESSAGE(out, job->node);
     1188                    lastNode = job->node;
     1189                }
     1190#endif
     1191                (void) fprintf(out, "*** Continued\n");
     1192            }
     1193            if (!(job->flags & JOB_CONTINUING)) {
     1194                if (DEBUG(JOB)) {
     1195                    (void) fprintf(stdout,
     1196                                   "Warning: process %d was not continuing.\n",
     1197                                   job->pid);
     1198                    (void) fflush(stdout);
     1199                }
     1200#ifdef SIGCONT
    9121201#ifdef notdef
    913                 /*
    914                  * We don't really want to restart a job from scratch just
    915                  * because it continued, especially not without killing the
    916                  * continuing process!  That's why this is ifdef'ed out.
    917                  * FD - 9/17/90
    918                  */
    919                 JobRestart(job);
    920 #endif
    921             }
    922             job->flags &= ~JOB_CONTINUING;
    923             Lst_AtEnd(jobs, (ClientData)job);
    924             nJobs += 1;
    925             if (!(job->flags & JOB_REMOTE)) {
    926                 if (DEBUG(JOB)) {
    927                     (void) fprintf(stdout,
    928                                    "Process %d is continuing locally.\n",
    929                                    job->pid);
    930                     (void) fflush(stdout);
    931                 }
    932                 nLocal += 1;
    933             }
    934             if (nJobs == maxJobs) {
    935                 jobFull = TRUE;
    936                 if (DEBUG(JOB)) {
    937                     (void) fprintf(stdout, "Job queue is full.\n");
    938                     (void) fflush(stdout);
    939                 }
    940             }
    941             (void) fflush(out);
    942             return;
    943         } else {
    944             if (usePipes && job->node != lastNode) {
    945                 MESSAGE(out, job->node);
    946                 lastNode = job->node;
    947             }
    948             (void) fprintf(out, "*** Signal %d\n", WTERMSIG(*status));
    949         }
    950 
    951         (void) fflush(out);
     1202                /*
     1203                 * We don't really want to restart a job from scratch just
     1204                 * because it continued, especially not without killing the
     1205                 * continuing process!  That's why this is ifdef'ed out.
     1206                 * FD - 9/17/90
     1207                 */
     1208                JobRestart(job);
     1209#endif
     1210#endif
     1211            }
     1212            job->flags &= ~JOB_CONTINUING;
     1213            Lst_AtEnd(jobs, (ClientData)job);
     1214            nJobs += 1;
     1215            if (!(job->flags & JOB_REMOTE)) {
     1216                if (DEBUG(JOB)) {
     1217                    (void) fprintf(stdout,
     1218                                   "Process %d is continuing locally.\n",
     1219                                   job->pid);
     1220                    (void) fflush(stdout);
     1221                }
     1222                nLocal += 1;
     1223            }
     1224            if (nJobs == maxJobs) {
     1225                jobFull = TRUE;
     1226                if (DEBUG(JOB)) {
     1227                    (void) fprintf(stdout, "Job queue is full.\n");
     1228                    (void) fflush(stdout);
     1229                }
     1230            }
     1231            (void) fflush(out);
     1232            return;
     1233        } else {
     1234#ifdef USE_PIPES
     1235            if (usePipes && job->node != lastNode) {
     1236                MESSAGE(out, job->node);
     1237                lastNode = job->node;
     1238            }
     1239#endif
     1240            (void) fprintf(out, "*** Signal %d\n", WTERMSIG(*status));
     1241        }
     1242
     1243        (void) fflush(out);
    9521244    }
    9531245
     
    9581250     */
    9591251    if (compatMake && (WIFEXITED(*status) &&
    960         !Lst_IsAtEnd(job->node->commands))) {
    961         switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) {
    962         case JOB_RUNNING:
    963             done = FALSE;
    964             break;
    965         case JOB_ERROR:
    966             done = TRUE;
    967             W_SETEXITSTATUS(status, 1);
    968             break;
    969         case JOB_FINISHED:
    970             /*
    971              * If we got back a JOB_FINISHED code, JobStart has already
    972              * called Make_Update and freed the job descriptor. We set
    973              * done to false here to avoid fake cycles and double frees.
    974              * JobStart needs to do the update so we can proceed up the
    975              * graph when given the -n flag..
    976              */
    977             done = FALSE;
    978             break;
    979         }
     1252        !Lst_IsAtEnd(job->node->commands))) {
     1253        switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) {
     1254        case JOB_RUNNING:
     1255            done = FALSE;
     1256            break;
     1257        case JOB_ERROR:
     1258            done = TRUE;
     1259            W_SETEXITSTATUS(status, 1);
     1260            break;
     1261        case JOB_FINISHED:
     1262            /*
     1263             * If we got back a JOB_FINISHED code, JobStart has already
     1264             * called Make_Update and freed the job descriptor. We set
     1265             * done to false here to avoid fake cycles and double frees.
     1266             * JobStart needs to do the update so we can proceed up the
     1267             * graph when given the -n flag..
     1268             */
     1269            done = FALSE;
     1270            break;
     1271        }
    9801272    } else {
    981         done = TRUE;
     1273        done = TRUE;
    9821274    }
    9831275
    9841276
    9851277    if (done &&
    986         (aborting != ABORT_ERROR) &&
    987         (aborting != ABORT_INTERRUPT) &&
    988         (*status == 0))
     1278        (aborting != ABORT_ERROR) &&
     1279        (aborting != ABORT_INTERRUPT) &&
     1280        (*status == 0))
    9891281    {
    990         /*
    991         * As long as we aren't aborting and the job didn't return a non-zero
    992         * status that we shouldn't ignore, we call Make_Update to update
    993         * the parents. In addition, any saved commands for the node are placed
    994         * on the .END target.
    995         */
    996         if (job->tailCmds != NILLNODE) {
    997             Lst_ForEachFrom(job->node->commands, job->tailCmds,
    998                              JobSaveCommand,
    999                             (ClientData)job->node);
    1000         }
    1001         job->node->made = MADE;
    1002         Make_Update(job->node);
    1003         efree((Address)job);
     1282        /*
     1283        * As long as we aren't aborting and the job didn't return a non-zero
     1284        * status that we shouldn't ignore, we call Make_Update to update
     1285        * the parents. In addition, any saved commands for the node are placed
     1286        * on the .END target.
     1287        */
     1288        if (job->tailCmds != NILLNODE) {
     1289            Lst_ForEachFrom(job->node->commands, job->tailCmds,
     1290                             JobSaveCommand,
     1291                            (ClientData)job->node);
     1292        }
     1293        job->node->made = MADE;
     1294        Make_Update(job->node);
     1295        efree((Address)job);
    10041296    } else if (*status != 0) {
    1005         errors += 1;
    1006         efree((Address)job);
    1007     }
    1008 
     1297        errors += 1;
     1298        efree((Address)job);
     1299    }
     1300
     1301#ifdef SIGCONT
    10091302    JobRestartJobs();
     1303#endif
    10101304
    10111305    /*
     
    10131307     */
    10141308    if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) {
    1015         /*
    1016         * If we found any errors in this batch of children and the -k flag
    1017         * wasn't given, we set the aborting flag so no more jobs get
    1018         * started.
    1019         */
    1020         aborting = ABORT_ERROR;
     1309        /*
     1310        * If we found any errors in this batch of children and the -k flag
     1311        * wasn't given, we set the aborting flag so no more jobs get
     1312        * started.
     1313        */
     1314        aborting = ABORT_ERROR;
    10211315    }
    10221316
    10231317    if ((aborting == ABORT_ERROR) && Job_Empty())
    1024         /*
    1025          * If we are aborting and the job table is now empty, we finish.
    1026          */
    1027         Finish(errors);
     1318        /*
     1319         * If we are aborting and the job table is now empty, we finish.
     1320         */
     1321        Finish(errors);
     1322#endif /* USE_KLIB */
    10281323}
    10291324
     
    10311326 *-----------------------------------------------------------------------
    10321327 * Job_Touch --
    1033  *      Touch the given target. Called by JobStart when the -t flag was
    1034  *      given
     1328 *      Touch the given target. Called by JobStart when the -t flag was
     1329 *      given
    10351330 *
    10361331 * Results:
    1037  *      None
     1332 *      None
    10381333 *
    10391334 * Side Effects:
    1040  *      The data modification of the file is changed. In addition, if the
    1041  *      file did not exist, it is created.
     1335 *      The data modification of the file is changed. In addition, if the
     1336 *      file did not exist, it is created.
    10421337 *-----------------------------------------------------------------------
    10431338 */
    10441339void
    10451340Job_Touch(gn, silent)
    1046     GNode         *gn;          /* the node of the file to touch */
    1047     Boolean       silent;       /* TRUE if should not print messages */
     1341    GNode         *gn;          /* the node of the file to touch */
     1342    Boolean       silent;       /* TRUE if should not print messages */
    10481343{
    1049     int           streamID;     /* ID of stream opened to do the touch */
    1050     struct utimbuf times;       /* Times for utime() call */
     1344    int           streamID;     /* ID of stream opened to do the touch */
     1345    struct utimbuf times;       /* Times for utime() call */
    10511346
    10521347    if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
    1053         /*
    1054         * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets
    1055         * and, as such, shouldn't really be created.
    1056         */
    1057         return;
     1348        /*
     1349        * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets
     1350        * and, as such, shouldn't really be created.
     1351        */
     1352        return;
    10581353    }
    10591354
    10601355    if (!silent) {
    1061         (void) fprintf(stdout, "touch %s\n", gn->name);
    1062         (void) fflush(stdout);
     1356        (void) fprintf(stdout, "touch %s\n", gn->name);
     1357        (void) fflush(stdout);
    10631358    }
    10641359
    10651360    if (noExecute) {
    1066         return;
     1361        return;
    10671362    }
    10681363
    10691364#ifdef USE_ARCHIVES
    10701365    if (gn->type & OP_ARCHV) {
    1071         Arch_Touch(gn);
     1366        Arch_Touch(gn);
    10721367    } else if (gn->type & OP_LIB) {
    1073         Arch_TouchLib(gn);
     1368        Arch_TouchLib(gn);
    10741369    } else {
    10751370#else
     
    10771372#endif
    10781373
    1079         char    *file = gn->path ? gn->path : gn->name;
    1080 
    1081         times.actime = times.modtime = now;
    1082         if (utime(file, &times) < 0){
    1083             streamID = open(file, O_RDWR | O_CREAT, 0666);
    1084 
    1085             if (streamID >= 0) {
    1086                 char    c;
    1087 
    1088                 /*
    1089                 * Read and write a byte to the file to change the
    1090                 * modification time, then close the file.
    1091                 */
    1092                 if (read(streamID, &c, 1) == 1) {
    1093                     (void) lseek(streamID, 0L, SEEK_SET);
    1094                     (void) write(streamID, &c, 1);
    1095                 }
    1096 
    1097                 (void) close(streamID);
    1098             } else {
    1099                 (void) fprintf(stdout, "*** couldn't touch %s: %s",
    1100                                file, strerror(errno));
    1101                 (void) fflush(stdout);
    1102             }
    1103         }
     1374        char    *file = gn->path ? gn->path : gn->name;
     1375
     1376        times.actime = times.modtime = now;
     1377        if (utime(file, &times) < 0){
     1378            streamID = open(file, O_RDWR | O_CREAT, 0666);
     1379
     1380            if (streamID >= 0) {
     1381                char    c;
     1382
     1383                /*
     1384                * Read and write a byte to the file to change the
     1385                * modification time, then close the file.
     1386                */
     1387                if (read(streamID, &c, 1) == 1) {
     1388                    (void) lseek(streamID, 0L, SEEK_SET);
     1389                    (void) write(streamID, &c, 1);
     1390                }
     1391
     1392                (void) close(streamID);
     1393            } else {
     1394                (void) fprintf(stdout, "*** couldn't touch %s: %s",
     1395                               file, strerror(errno));
     1396                (void) fflush(stdout);
     1397            }
     1398        }
    11041399    }
    11051400}
     
    11081403 *-----------------------------------------------------------------------
    11091404 * Job_CheckCommands --
    1110  *      Make sure the given node has all the commands it needs.
     1405 *      Make sure the given node has all the commands it needs.
    11111406 *
    11121407 * Results:
    1113  *      TRUE if the commands list is/was ok.
     1408 *      TRUE if the commands list is/was ok.
    11141409 *
    11151410 * Side Effects:
    1116  *      The node will have commands from the .DEFAULT rule added to it
    1117  *      if it needs them.
     1411 *      The node will have commands from the .DEFAULT rule added to it
     1412 *      if it needs them.
    11181413 *-----------------------------------------------------------------------
    11191414 */
    11201415Boolean
    11211416Job_CheckCommands(gn, abortProc)
    1122     GNode          *gn;             /* The target whose commands need
    1123                                      * verifying */
    1124     void        (*abortProc) __P((char *, ...));
    1125                         /* Function to abort with message */
     1417    GNode          *gn;             /* The target whose commands need
     1418                                     * verifying */
     1419    void        (*abortProc) __P((char *, ...));
     1420                        /* Function to abort with message */
    11261421{
    11271422    if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands)
     
    11311426        )
    11321427    {
    1133         /*
    1134         * No commands. Look for .DEFAULT rule from which we might infer
    1135         * commands
    1136         */
    1137         if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) {
    1138             char *p1;
    1139             /*
    1140              * Make only looks for a .DEFAULT if the node was never the
    1141              * target of an operator, so that's what we do too. If
    1142              * a .DEFAULT was given, we substitute its commands for gn's
    1143              * commands and set the IMPSRC variable to be the target's name
    1144              * The DEFAULT node acts like a transformation rule, in that
    1145              * gn also inherits any attributes or sources attached to
    1146              * .DEFAULT itself.
    1147              */
    1148             Make_HandleUse(DEFAULT, gn);
    1149             Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn);
    1150             efree(p1);
    1151         } else if (Dir_MTime(gn) == 0) {
    1152             /*
    1153              * The node wasn't the target of an operator we have no .DEFAULT
    1154              * rule to go on and the target doesn't already exist. There's
    1155              * nothing more we can do for this branch. If the -k flag wasn't
    1156              * given, we stop in our tracks, otherwise we just don't update
    1157              * this node's parents so they never get examined.
    1158              */
    1159             static const char msg[] = MAKE_NAME ": don't know how to make";
    1160 
    1161             if (gn->type & OP_OPTIONAL) {
    1162                 (void) fprintf(stdout, "%s %s(ignored)\n", msg, gn->name);
    1163                 (void) fflush(stdout);
    1164             } else if (keepgoing) {
    1165                 (void) fprintf(stdout, "%s %s(continuing)\n", msg, gn->name);
    1166                 (void) fflush(stdout);
    1167                 return FALSE;
    1168             } else {
     1428        /*
     1429        * No commands. Look for .DEFAULT rule from which we might infer
     1430        * commands
     1431        */
     1432        if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) {
     1433            char *p1;
     1434            /*
     1435             * Make only looks for a .DEFAULT if the node was never the
     1436             * target of an operator, so that's what we do too. If
     1437             * a .DEFAULT was given, we substitute its commands for gn's
     1438             * commands and set the IMPSRC variable to be the target's name
     1439             * The DEFAULT node acts like a transformation rule, in that
     1440             * gn also inherits any attributes or sources attached to
     1441             * .DEFAULT itself.
     1442             */
     1443            Make_HandleUse(DEFAULT, gn);
     1444            Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn);
     1445            efree(p1);
     1446        } else if (Dir_MTime(gn) == 0) {
     1447            /*
     1448             * The node wasn't the target of an operator we have no .DEFAULT
     1449             * rule to go on and the target doesn't already exist. There's
     1450             * nothing more we can do for this branch. If the -k flag wasn't
     1451             * given, we stop in our tracks, otherwise we just don't update
     1452             * this node's parents so they never get examined.
     1453             */
     1454            static const char msg[] = MAKE_NAME ": don't know how to make";
     1455
     1456            if (gn->type & OP_OPTIONAL) {
     1457                (void) fprintf(stdout, "%s %s(ignored)\n", msg, gn->name);
     1458                (void) fflush(stdout);
     1459            } else if (keepgoing) {
     1460                (void) fprintf(stdout, "%s %s(continuing)\n", msg, gn->name);
     1461                (void) fflush(stdout);
     1462                return FALSE;
     1463            } else {
    11691464#if OLD_JOKE
    1170                 if (strcmp(gn->name,"love") == 0)
    1171                     (*abortProc)("Not war.");
     1465                if (strcmp(gn->name,"love") == 0)
     1466                    (*abortProc)("Not war.");
    11721467#if defined(NMAKE) || defined(KMK)
    11731468                else if (strcmp(gn->name,"fire") == 0)
    1174                     (*abortProc)("No match.");
     1469                    (*abortProc)("No match.");
    11751470#endif
    11761471                else
    11771472#endif
    1178                     (*abortProc)("%s %s. Stop", msg, gn->name);
    1179                 return FALSE;
    1180             }
    1181         }
     1473                    (*abortProc)("%s %s. Stop", msg, gn->name);
     1474                return FALSE;
     1475            }
     1476        }
    11821477    }
    11831478    return TRUE;
     
    11871482 *-----------------------------------------------------------------------
    11881483 * JobLocalInput --
    1189  *      Handle a pipe becoming readable. Callback function for Rmt_Watch
     1484 *      Handle a pipe becoming readable. Callback function for Rmt_Watch
    11901485 *
    11911486 * Results:
    1192  *      None
     1487 *      None
    11931488 *
    11941489 * Side Effects:
    1195  *      JobDoOutput is called.
     1490 *      JobDoOutput is called.
    11961491 *
    11971492 *-----------------------------------------------------------------------
     
    12001495static void
    12011496JobLocalInput(stream, job)
    1202     int     stream;     /* Stream that's ready (ignored) */
    1203     Job     *job;       /* Job to which the stream belongs */
     1497    int     stream;     /* Stream that's ready (ignored) */
     1498    Job     *job;       /* Job to which the stream belongs */
    12041499{
    12051500    JobDoOutput(job, FALSE);
     
    12101505 *-----------------------------------------------------------------------
    12111506 * JobExec --
    1212  *      Execute the shell for the given job. Called from JobStart and
    1213  *      JobRestart.
     1507 *      Execute the shell for the given job. Called from JobStart and
     1508 *      JobRestart.
    12141509 *
    12151510 * Results:
    1216  *      None.
     1511 *      None.
    12171512 *
    12181513 * Side Effects:
    1219  *      A shell is executed, outputs is altered and the Job structure added
    1220  *      to the job table.
     1514 *      A shell is executed, outputs is altered and the Job structure added
     1515 *      to the job table.
    12211516 *
    12221517 *-----------------------------------------------------------------------
     
    12241519static void
    12251520JobExec(job, argv)
    1226     Job           *job;         /* Job to execute */
    1227     char          **argv;
     1521    Job           *job;         /* Job to execute */
     1522    char          **argv;
    12281523{
    1229     int           cpid;         /* ID of new child */
     1524#ifdef USE_KLIB
     1525    int           cpid;         /* ID of new child */
     1526    int           rc;
     1527
     1528    if (DEBUG(JOB))
     1529    {
     1530        int       i;
     1531        fprintf(stdout, "Running %s %sly\n", job->node->name,
     1532                job->flags&JOB_REMOTE?"remote":"local");
     1533        fprintf(stdout, "\tCommand: ");
     1534        for (i = 0; argv[i] != NULL; i++)
     1535            fprintf(stdout, "%s ", argv[i]);
     1536        fprintf(stdout, "\n");
     1537        fflush(stdout);
     1538    }
     1539
     1540    /*
     1541     * Some jobs produce no output and it's disconcerting to have
     1542     * no feedback of their running (since they produce no output, the
     1543     * banner with their name in it never appears). This is an attempt to
     1544     * provide that feedback, even if nothing follows it.
     1545     */
     1546    if (    lastNode != job->node
     1547        &&  (job->flags & JOB_FIRST)
     1548        && !(job->flags & JOB_SILENT)
     1549         )
     1550    {
     1551        MESSAGE(stdout, job->node);
     1552        lastNode = job->node;
     1553    }
     1554
     1555    /*
     1556     * Create process with assigned output+stderr pipe.
     1557     */
     1558    if (job->cmdFILE)
     1559        fseek(job->cmdFILE, 0, SEEK_SET);
     1560    rc = kProcCreate(argv,
     1561                     NULL,
     1562                     NULL,
     1563                     NULL,
     1564                     KPROCCREATE_FLAGS_SPAWN,
     1565                     job->cmdFILE ? FILENO(job->cmdFILE) : KFILE_NULL,
     1566                     usePipes ? job->outPipe : job->outFd, /* stdout */
     1567                     usePipes ? job->outPipe : job->outFd, /* stderr */
     1568                     &cpid,
     1569                     NULL);
     1570    if (!rc)
     1571    {
     1572        job->pid = cpid;
     1573
     1574#ifdef USE_PIPES
     1575        if (usePipes && (job->flags & JOB_FIRST) )
     1576        {
     1577            /*
     1578             * The first time a job is run for a node, we set the current
     1579             * position in the buffer to the beginning and mark another
     1580             * stream to watch in the outputs mask
     1581             */
     1582            job->curPos = 0;
     1583            FD_SET(job->inPipe, &outputs);
     1584        }
     1585#endif /* USE_PIPES */
     1586
     1587        if (job->flags & JOB_REMOTE) {
     1588            job->rmtID = 0;
     1589        } else {
     1590            nLocal += 1;
     1591            /*
     1592             * XXX: Used to not happen if REMOTE. Why?
     1593             */
     1594            if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
     1595                fclose(job->cmdFILE);
     1596                job->cmdFILE = NULL;
     1597            }
     1598        }
     1599
     1600        /*
     1601         * Now the job is actually running, add it to the table.
     1602         */
     1603        nJobs += 1;
     1604        (void) Lst_AtEnd(jobs, (ClientData)job);
     1605        if (nJobs == maxJobs)
     1606        {
     1607            jobFull = TRUE;
     1608        }
     1609    }
     1610    else
     1611        Punt("Cannot start child (%d)", rc);
     1612
     1613
     1614
     1615#else /* Don't use kLib */
     1616    int           cpid;         /* ID of new child */
    12301617
    12311618    if (DEBUG(JOB)) {
    1232         int       i;
    1233 
    1234         (void) fprintf(stdout, "Running %s %sly\n", job->node->name,
    1235                        job->flags&JOB_REMOTE?"remote":"local");
    1236         (void) fprintf(stdout, "\tCommand: ");
    1237         for (i = 0; argv[i] != NULL; i++) {
    1238             (void) fprintf(stdout, "%s ", argv[i]);
    1239         }
    1240         (void) fprintf(stdout, "\n");
    1241         (void) fflush(stdout);
     1619        int       i;
     1620
     1621        (void) fprintf(stdout, "Running %s %sly\n", job->node->name,
     1622                       job->flags&JOB_REMOTE?"remote":"local");
     1623        (void) fprintf(stdout, "\tCommand: ");
     1624        for (i = 0; argv[i] != NULL; i++) {
     1625            (void) fprintf(stdout, "%s ", argv[i]);
     1626        }
     1627        (void) fprintf(stdout, "\n");
     1628        (void) fflush(stdout);
    12421629    }
    12431630
     
    12491636     */
    12501637    if ((lastNode != job->node) && (job->flags & JOB_FIRST) &&
    1251         !(job->flags & JOB_SILENT)) {
    1252         MESSAGE(stdout, job->node);
    1253         lastNode = job->node;
     1638        !(job->flags & JOB_SILENT)) {
     1639        MESSAGE(stdout, job->node);
     1640        lastNode = job->node;
    12541641    }
    12551642
    12561643#ifdef RMT_NO_EXEC
    12571644    if (job->flags & JOB_REMOTE) {
    1258         goto jobExecFinish;
     1645        goto jobExecFinish;
    12591646    }
    12601647#endif /* RMT_NO_EXEC */
     
    12651652    if ((cpid = vfork()) == -1) {
    12661653#endif
    1267         Punt("Cannot fork");
     1654        Punt("Cannot fork");
    12681655    } else if (cpid == 0) {
    12691656
    1270         /*
    1271         * Must duplicate the input stream down to the child's input and
    1272         * reset it to the beginning (again). Since the stream was marked
    1273         * close-on-exec, we must clear that bit in the new input.
    1274         */
    1275         if (dup2(FILENO(job->cmdFILE), 0) == -1)
    1276             Punt("Cannot dup2: %s", strerror(errno));
    1277         (void) fcntl(0, F_SETFD, 0);
    1278         (void) lseek(0, 0, SEEK_SET);
    1279 
    1280         if (usePipes) {
    1281             /*
    1282              * Set up the child's output to be routed through the pipe
    1283              * we've created for it.
    1284              */
    1285             if (dup2(job->outPipe, 1) == -1)
    1286                 Punt("Cannot dup2: %s", strerror(errno));
    1287         } else {
    1288             /*
    1289              * We're capturing output in a file, so we duplicate the
    1290              * descriptor to the temporary file into the standard
    1291              * output.
    1292              */
    1293             if (dup2(job->outFd, 1) == -1)
    1294                 Punt("Cannot dup2: %s", strerror(errno));
    1295         }
    1296         /*
    1297         * The output channels are marked close on exec. This bit was
    1298         * duplicated by the dup2 (on some systems), so we have to clear
    1299         * it before routing the shell's error output to the same place as
    1300         * its standard output.
    1301         */
    1302         (void) fcntl(1, F_SETFD, 0);
    1303         if (dup2(1, 2) == -1)
    1304             Punt("Cannot dup2: %s", strerror(errno));
     1657        /*
     1658        * Must duplicate the input stream down to the child's input and
     1659        * reset it to the beginning (again). Since the stream was marked
     1660        * close-on-exec, we must clear that bit in the new input.
     1661        */
     1662        if (dup2(FILENO(job->cmdFILE), 0) == -1)
     1663            Punt("Cannot dup2: %s", strerror(errno));
     1664        (void) fcntl(0, F_SETFD, 0);
     1665        (void) lseek(0, 0, SEEK_SET);
     1666
     1667        if (usePipes) {
     1668            /*
     1669             * Set up the child's output to be routed through the pipe
     1670             * we've created for it.
     1671             */
     1672            if (dup2(job->outPipe, STDOUT_FILENO) == -1)
     1673                Punt("Cannot dup2: %s", strerror(errno));
     1674        } else {
     1675            /*
     1676             * We're capturing output in a file, so we duplicate the
     1677             * descriptor to the temporary file into the standard
     1678             * output.
     1679             */
     1680            if (dup2(job->outFd, STDOUT_FILENO) == -1)
     1681                Punt("Cannot dup2: %s", strerror(errno));
     1682        }
     1683        /*
     1684        * The output channels are marked close on exec. This bit was
     1685        * duplicated by the dup2 (on some systems), so we have to clear
     1686        * it before routing the shell's error output to the same place as
     1687        * its standard output.
     1688        */
     1689        (void) fcntl(1, F_SETFD, 0);
     1690        if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
     1691            Punt("Cannot dup2: %s", strerror(errno));
    13051692
    13061693#ifdef USE_PGRP
    1307         /*
    1308         * We want to switch the child into a different process family so
    1309         * we can kill it and all its descendants in one fell swoop,
    1310         * by killing its process family, but not commit suicide.
    1311         */
     1694        /*
     1695        * We want to switch the child into a different process family so
     1696        * we can kill it and all its descendants in one fell swoop,
     1697        * by killing its process family, but not commit suicide.
     1698        */
    13121699# if defined(SYSV)
    1313         (void) setsid();
     1700        (void) setsid();
    13141701# else
    1315         (void) setpgid(0, getpid());
     1702        (void) setpgid(0, getpid());
    13161703# endif
    13171704#endif /* USE_PGRP */
    13181705
    13191706#ifdef REMOTE
    1320         if (job->flags & JOB_REMOTE) {
    1321             Rmt_Exec(shellPath, argv, FALSE);
    1322         } else
     1707        if (job->flags & JOB_REMOTE) {
     1708            Rmt_Exec(shellPath, argv, FALSE);
     1709        } else
    13231710#endif /* REMOTE */
    13241711#ifdef KMK
    1325            (void) execv(argv[0], argv);
     1712           (void) execv(argv[0], argv);
    13261713#else
    1327            (void) execv(shellPath, argv);
    1328 #endif
    1329 
    1330         (void) write(2, "Could not execute shell\n",
    1331                      sizeof("Could not execute shell"));
    1332         _exit(1);
     1714           (void) execv(shellPath, argv);
     1715#endif
     1716
     1717        (void) write(2, "Could not execute shell\n",
     1718                     sizeof("Could not execute shell"));
     1719        _exit(1);
    13331720    } else {
    13341721#ifdef REMOTE
    1335         long omask = sigblock(sigmask(SIGCHLD));
    1336 #endif
    1337         job->pid = cpid;
    1338 
    1339         if (usePipes && (job->flags & JOB_FIRST) ) {
    1340             /*
    1341              * The first time a job is run for a node, we set the current
    1342              * position in the buffer to the beginning and mark another
    1343              * stream to watch in the outputs mask
    1344              */
    1345             job->curPos = 0;
     1722        long omask = sigblock(sigmask(SIGCHLD));
     1723#endif
     1724        job->pid = cpid;
     1725
     1726#ifdef USE_PIPES
     1727        if (usePipes && (job->flags & JOB_FIRST) ) {
     1728            /*
     1729             * The first time a job is run for a node, we set the current
     1730             * position in the buffer to the beginning and mark another
     1731             * stream to watch in the outputs mask
     1732             */
     1733            job->curPos = 0;
    13461734
    13471735#ifdef RMT_WILL_WATCH
    1348             Rmt_Watch(job->inPipe, JobLocalInput, job);
     1736            Rmt_Watch(job->inPipe, JobLocalInput, job);
    13491737#else
    1350             FD_SET(job->inPipe, &outputs);
     1738            FD_SET(job->inPipe, &outputs);
    13511739#endif /* RMT_WILL_WATCH */
    1352         }
    1353 
    1354         if (job->flags & JOB_REMOTE) {
     1740        }
     1741#endif /* USE_PIPES */
     1742
     1743        if (job->flags & JOB_REMOTE) {
    13551744#ifndef REMOTE
    1356             job->rmtID = 0;
     1745            job->rmtID = 0;
    13571746#else
    1358             job->rmtID = Rmt_LastID(job->pid);
     1747            job->rmtID = Rmt_LastID(job->pid);
    13591748#endif /* REMOTE */
    1360         } else {
    1361             nLocal += 1;
    1362             /*
    1363              * XXX: Used to not happen if REMOTE. Why?
    1364              */
    1365             if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
    1366                 (void) fclose(job->cmdFILE);
    1367                 job->cmdFILE = NULL;
    1368             }
    1369         }
     1749        } else {
     1750            nLocal += 1;
     1751            /*
     1752             * XXX: Used to not happen if REMOTE. Why?
     1753             */
     1754            if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
     1755                (void) fclose(job->cmdFILE);
     1756                job->cmdFILE = NULL;
     1757            }
     1758        }
    13701759#ifdef REMOTE
    1371         (void) sigsetmask(omask);
     1760        (void) sigsetmask(omask);
    13721761#endif
    13731762    }
     
    13821771    (void) Lst_AtEnd(jobs, (ClientData)job);
    13831772    if (nJobs == maxJobs) {
    1384         jobFull = TRUE;
    1385     }
     1773        jobFull = TRUE;
     1774    }
     1775#endif /* USE_KLIB */
    13861776}
    13871777
     
    13901780 *-----------------------------------------------------------------------
    13911781 * JobMakeArgv --
    1392  *      Create the argv needed to execute the shell for a given job.
     1782 *      Create the argv needed to execute the shell for a given job.
    13931783 *
    13941784 *
     
    14011791static void
    14021792JobMakeArgv(job, argv)
    1403     Job           *job;
    1404     char          **argv;
     1793    Job           *job;
     1794    char          **argv;
    14051795{
    1406     int           argc;
    1407     static char   args[10];     /* For merged arguments */
    1408 
    1409 #ifndef _PATH_DEFSHELLDIR
    1410     /* @todo! */
    1411     argv[0] = "c:\\os2\\cmd.exe";
    1412     argc = 1;
    1413 #else
     1796#ifdef KMK
     1797    int           argc;
     1798
     1799    argv[0] = argv0;
     1800    argv[1] = "--kShell";
     1801    argc = 2;
     1802    if (!(job->flags & JOB_IGNERR))
     1803        argv[argc++] = "-e";
     1804    if (!(job->flags & JOB_SILENT))
     1805        argv[argc++] = "-v";
     1806    argv[argc] = NULL;
     1807
     1808#else /* not kMk */
     1809    int           argc;
     1810    static char   args[10];     /* For merged arguments */
     1811
    14141812    argv[0] = shellName;
    14151813    argc = 1;
    14161814
    14171815    if ((commandShell->exit && (*commandShell->exit != '-')) ||
    1418         (commandShell->echo && (*commandShell->echo != '-')))
     1816        (commandShell->echo && (*commandShell->echo != '-')))
    14191817    {
    1420         /*
    1421         * At least one of the flags doesn't have a minus before it, so
    1422         * merge them together. Have to do this because the *(&(@*#*&#$#
    1423         * Bourne shell thinks its second argument is a file to source.
    1424         * Grrrr. Note the ten-character limitation on the combined arguments.
    1425         */
    1426         (void)sprintf(args, "-%s%s",
    1427                       ((job->flags & JOB_IGNERR) ? "" :
    1428                        (commandShell->exit ? commandShell->exit : "")),
    1429                       ((job->flags & JOB_SILENT) ? "" :
    1430                        (commandShell->echo ? commandShell->echo : "")));
    1431 
    1432         if (args[1]) {
    1433             argv[argc] = args;
    1434             argc++;
    1435         }
     1818        /*
     1819        * At least one of the flags doesn't have a minus before it, so
     1820        * merge them together. Have to do this because the *(&(@*#*&#$#
     1821        * Bourne shell thinks its second argument is a file to source.
     1822        * Grrrr. Note the ten-character limitation on the combined arguments.
     1823        */
     1824        (void)sprintf(args, "-%s%s",
     1825                      ((job->flags & JOB_IGNERR) ? "" :
     1826                       (commandShell->exit ? commandShell->exit : "")),
     1827                      ((job->flags & JOB_SILENT) ? "" :
     1828                       (commandShell->echo ? commandShell->echo : "")));
     1829
     1830        if (args[1]) {
     1831            argv[argc] = args;
     1832            argc++;
     1833        }
    14361834    } else {
    1437         if (!(job->flags & JOB_IGNERR) && commandShell->exit) {
    1438             argv[argc] = commandShell->exit;
    1439             argc++;
    1440         }
    1441         if (!(job->flags & JOB_SILENT) && commandShell->echo) {
    1442             argv[argc] = commandShell->echo;
    1443             argc++;
    1444         }
     1835        if (!(job->flags & JOB_IGNERR) && commandShell->exit) {
     1836            argv[argc] = commandShell->exit;
     1837            argc++;
     1838        }
     1839        if (!(job->flags & JOB_SILENT) && commandShell->echo) {
     1840            argv[argc] = commandShell->echo;
     1841            argc++;
     1842        }
    14451843    }
    14461844    argv[argc] = NULL;
    1447 #endif
     1845#endif /* KMK */
    14481846}
    14491847
    14501848
     1849#ifdef SIGCONT
    14511850/*-
    14521851 *-----------------------------------------------------------------------
    14531852 * JobRestart --
    1454  *      Restart a job that stopped for some reason.
     1853 *      Restart a job that stopped for some reason.
    14551854 *
    14561855 * Results:
    1457  *      None.
     1856 *      None.
    14581857 *
    14591858 * Side Effects:
    1460  *      jobFull will be set if the job couldn't be run.
     1859 *      jobFull will be set if the job couldn't be run.
    14611860 *
    14621861 *-----------------------------------------------------------------------
     
    14641863static void
    14651864JobRestart(job)
    1466     Job           *job;         /* Job to restart */
     1865    Job           *job;         /* Job to restart */
    14671866{
    14681867#ifdef REMOTE
     
    14711870
    14721871    if (job->flags & JOB_REMIGRATE) {
    1473         if (
     1872        if (
    14741873#ifdef REMOTE
    1475             verboseRemigrates ||
    1476 #endif
    1477             DEBUG(JOB)) {
    1478            (void) fprintf(stdout, "*** remigrating %x(%s)\n",
    1479                            job->pid, job->node->name);
    1480            (void) fflush(stdout);
    1481         }
     1874            verboseRemigrates ||
     1875#endif
     1876            DEBUG(JOB)) {
     1877           (void) fprintf(stdout, "*** remigrating %x(%s)\n",
     1878                           job->pid, job->node->name);
     1879           (void) fflush(stdout);
     1880        }
    14821881
    14831882#ifdef REMOTE
    1484         if (!Rmt_ReExport(job->pid, job->node, &host)) {
    1485             if (verboseRemigrates || DEBUG(JOB)) {
    1486                 (void) fprintf(stdout, "*** couldn't migrate...\n");
    1487                 (void) fflush(stdout);
    1488             }
    1489 #endif
    1490             if (nLocal != maxLocal) {
    1491                 /*
    1492                 * Job cannot be remigrated, but there's room on the local
    1493                 * machine, so resume the job and note that another
    1494                 * local job has started.
    1495                 */
    1496                 if (
     1883        if (!Rmt_ReExport(job->pid, job->node, &host)) {
     1884            if (verboseRemigrates || DEBUG(JOB)) {
     1885                (void) fprintf(stdout, "*** couldn't migrate...\n");
     1886                (void) fflush(stdout);
     1887            }
     1888#endif
     1889            if (nLocal != maxLocal) {
     1890                /*
     1891                * Job cannot be remigrated, but there's room on the local
     1892                * machine, so resume the job and note that another
     1893                * local job has started.
     1894                */
     1895                if (
    14971896#ifdef REMOTE
    1498                     verboseRemigrates ||
    1499 #endif
    1500                     DEBUG(JOB)) {
    1501                     (void) fprintf(stdout, "*** resuming on local machine\n");
    1502                     (void) fflush(stdout);
    1503                 }
    1504                 KILL(job->pid, SIGCONT);
    1505                 nLocal +=1;
     1897                    verboseRemigrates ||
     1898#endif
     1899                    DEBUG(JOB)) {
     1900                    (void) fprintf(stdout, "*** resuming on local machine\n");
     1901                    (void) fflush(stdout);
     1902                }
     1903                KILL(job->pid, SIGCONT);
     1904                nLocal +=1;
    15061905#ifdef REMOTE
    1507                 job->flags &= ~(JOB_REMIGRATE|JOB_RESUME|JOB_REMOTE);
    1508                 job->flags |= JOB_CONTINUING;
     1906                job->flags &= ~(JOB_REMIGRATE|JOB_RESUME|JOB_REMOTE);
     1907                job->flags |= JOB_CONTINUING;
    15091908#else
    1510                 job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
    1511 #endif
    1512         } else {
    1513                 /*
    1514                 * Job cannot be restarted. Mark the table as full and
    1515                 * place the job back on the list of stopped jobs.
    1516                 */
    1517                 if (
     1909                job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
     1910#endif
     1911        } else {
     1912                /*
     1913                * Job cannot be restarted. Mark the table as full and
     1914                * place the job back on the list of stopped jobs.
     1915                */
     1916                if (
    15181917#ifdef REMOTE
    1519                     verboseRemigrates ||
    1520 #endif
    1521                     DEBUG(JOB)) {
    1522                    (void) fprintf(stdout, "*** holding\n");
    1523                    (void) fflush(stdout);
    1524                 }
    1525                 (void)Lst_AtFront(stoppedJobs, (ClientData)job);
    1526                 jobFull = TRUE;
    1527                 if (DEBUG(JOB)) {
    1528                    (void) fprintf(stdout, "Job queue is full.\n");
    1529                    (void) fflush(stdout);
    1530                 }
    1531                 return;
    1532             }
     1918                    verboseRemigrates ||
     1919#endif
     1920                    DEBUG(JOB)) {
     1921                   (void) fprintf(stdout, "*** holding\n");
     1922                   (void) fflush(stdout);
     1923                }
     1924                (void)Lst_AtFront(stoppedJobs, (ClientData)job);
     1925                jobFull = TRUE;
     1926                if (DEBUG(JOB)) {
     1927                   (void) fprintf(stdout, "Job queue is full.\n");
     1928                   (void) fflush(stdout);
     1929                }
     1930                return;
     1931            }
    15331932#ifdef REMOTE
    1534         } else {
    1535             /*
    1536              * Clear out the remigrate and resume flags. Set the continuing
    1537              * flag so we know later on that the process isn't exiting just
    1538              * because of a signal.
    1539              */
    1540             job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
    1541             job->flags |= JOB_CONTINUING;
    1542             job->rmtID = host;
    1543         }
    1544 #endif
    1545 
    1546         (void)Lst_AtEnd(jobs, (ClientData)job);
    1547         nJobs += 1;
    1548         if (nJobs == maxJobs) {
    1549             jobFull = TRUE;
    1550             if (DEBUG(JOB)) {
    1551                 (void) fprintf(stdout, "Job queue is full.\n");
    1552                 (void) fflush(stdout);
    1553             }
    1554         }
     1933        } else {
     1934            /*
     1935             * Clear out the remigrate and resume flags. Set the continuing
     1936             * flag so we know later on that the process isn't exiting just
     1937             * because of a signal.
     1938             */
     1939            job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
     1940            job->flags |= JOB_CONTINUING;
     1941            job->rmtID = host;
     1942        }
     1943#endif
     1944
     1945        (void)Lst_AtEnd(jobs, (ClientData)job);
     1946        nJobs += 1;
     1947        if (nJobs == maxJobs) {
     1948            jobFull = TRUE;
     1949            if (DEBUG(JOB)) {
     1950                (void) fprintf(stdout, "Job queue is full.\n");
     1951                (void) fflush(stdout);
     1952            }
     1953        }
    15551954    } else if (job->flags & JOB_RESTART) {
    1556         /*
    1557         * Set up the control arguments to the shell. This is based on the
    1558         * flags set earlier for this job. If the JOB_IGNERR flag is clear,
    1559         * the 'exit' flag of the commandShell is used to cause it to exit
    1560         * upon receiving an error. If the JOB_SILENT flag is clear, the
    1561         * 'echo' flag of the commandShell is used to get it to start echoing
    1562         * as soon as it starts processing commands.
    1563         */
    1564         char      *argv[4];
    1565 
    1566         JobMakeArgv(job, argv);
    1567 
    1568         if (DEBUG(JOB)) {
    1569             (void) fprintf(stdout, "Restarting %s...", job->node->name);
    1570             (void) fflush(stdout);
    1571         }
     1955        /*
     1956        * Set up the control arguments to the shell. This is based on the
     1957        * flags set earlier for this job. If the JOB_IGNERR flag is clear,
     1958        * the 'exit' flag of the commandShell is used to cause it to exit
     1959        * upon receiving an error. If the JOB_SILENT flag is clear, the
     1960        * 'echo' flag of the commandShell is used to get it to start echoing
     1961        * as soon as it starts processing commands.
     1962        */
     1963        char      *argv[4];
     1964
     1965        JobMakeArgv(job, argv);
     1966
     1967        if (DEBUG(JOB)) {
     1968            (void) fprintf(stdout, "Restarting %s...", job->node->name);
     1969            (void) fflush(stdout);
     1970        }
    15721971#ifdef REMOTE
    1573         if ((job->node->type&OP_NOEXPORT) ||
    1574             (nLocal < maxLocal && runLocalFirst)
     1972        if ((job->node->type&OP_NOEXPORT) ||
     1973            (nLocal < maxLocal && runLocalFirst)
    15751974# ifdef RMT_NO_EXEC
    1576             || !Rmt_Export(shellPath, argv, job)
     1975            || !Rmt_Export(shellPath, argv, job)
    15771976# else
    1578             || !Rmt_Begin(shellPath, argv, job->node)
     1977            || !Rmt_Begin(shellPath, argv, job->node)
    15791978# endif
    15801979#endif
    1581         {
    1582             if (((nLocal >= maxLocal) && !(job->flags & JOB_SPECIAL))) {
    1583                 /*
    1584                 * Can't be exported and not allowed to run locally -- put it
    1585                 * back on the hold queue and mark the table full
    1586                 */
    1587                 if (DEBUG(JOB)) {
    1588                     (void) fprintf(stdout, "holding\n");
    1589                     (void) fflush(stdout);
    1590                 }
    1591                 (void)Lst_AtFront(stoppedJobs, (ClientData)job);
    1592                 jobFull = TRUE;
    1593                 if (DEBUG(JOB)) {
    1594                     (void) fprintf(stdout, "Job queue is full.\n");
    1595                     (void) fflush(stdout);
    1596                 }
    1597                 return;
    1598             } else {
    1599                 /*
    1600                 * Job may be run locally.
    1601                 */
    1602                 if (DEBUG(JOB)) {
    1603                     (void) fprintf(stdout, "running locally\n");
    1604                     (void) fflush(stdout);
    1605                 }
    1606                 job->flags &= ~JOB_REMOTE;
    1607             }
    1608         }
     1980        {
     1981            if (((nLocal >= maxLocal) && !(job->flags & JOB_SPECIAL))) {
     1982                /*
     1983                * Can't be exported and not allowed to run locally -- put it
     1984                * back on the hold queue and mark the table full
     1985                */
     1986                if (DEBUG(JOB)) {
     1987                    (void) fprintf(stdout, "holding\n");
     1988                    (void) fflush(stdout);
     1989                }
     1990                (void)Lst_AtFront(stoppedJobs, (ClientData)job);
     1991                jobFull = TRUE;
     1992                if (DEBUG(JOB)) {
     1993                    (void) fprintf(stdout, "Job queue is full.\n");
     1994                    (void) fflush(stdout);
     1995                }
     1996                return;
     1997            } else {
     1998                /*
     1999                * Job may be run locally.
     2000                */
     2001                if (DEBUG(JOB)) {
     2002                    (void) fprintf(stdout, "running locally\n");
     2003                    (void) fflush(stdout);
     2004                }
     2005                job->flags &= ~JOB_REMOTE;
     2006            }
     2007        }
    16092008#ifdef REMOTE
    1610         else {
    1611             /*
    1612              * Can be exported. Hooray!
    1613              */
    1614             if (DEBUG(JOB)) {
    1615                 (void) fprintf(stdout, "exporting\n");
    1616                 (void) fflush(stdout);
    1617             }
    1618             job->flags |= JOB_REMOTE;
    1619         }
    1620 #endif
    1621         JobExec(job, argv);
     2009        else {
     2010            /*
     2011             * Can be exported. Hooray!
     2012             */
     2013            if (DEBUG(JOB)) {
     2014                (void) fprintf(stdout, "exporting\n");
     2015                (void) fflush(stdout);
     2016            }
     2017            job->flags |= JOB_REMOTE;
     2018        }
     2019#endif
     2020        JobExec(job, argv);
    16222021    } else {
    1623         /*
    1624         * The job has stopped and needs to be restarted. Why it stopped,
    1625         * we don't know...
    1626         */
    1627         if (DEBUG(JOB)) {
    1628            (void) fprintf(stdout, "Resuming %s...", job->node->name);
    1629            (void) fflush(stdout);
    1630         }
    1631         if (((job->flags & JOB_REMOTE) ||
    1632             (nLocal < maxLocal) ||
     2022        /*
     2023        * The job has stopped and needs to be restarted. Why it stopped,
     2024        * we don't know...
     2025        */
     2026        if (DEBUG(JOB)) {
     2027           (void) fprintf(stdout, "Resuming %s...", job->node->name);
     2028           (void) fflush(stdout);
     2029        }
     2030        if (((job->flags & JOB_REMOTE) ||
     2031            (nLocal < maxLocal) ||
    16332032#ifdef REMOTE
    1634             (((job->flags & JOB_SPECIAL) &&
    1635               (job->node->type & OP_NOEXPORT)) &&
    1636              (maxLocal == 0))) &&
     2033            (((job->flags & JOB_SPECIAL) &&
     2034              (job->node->type & OP_NOEXPORT)) &&
     2035             (maxLocal == 0))) &&
    16372036#else
    1638             ((job->flags & JOB_SPECIAL) &&
    1639              (maxLocal == 0))) &&
    1640 #endif
    1641            (nJobs != maxJobs))
    1642         {
    1643             /*
    1644              * If the job is remote, it's ok to resume it as long as the
    1645              * maximum concurrency won't be exceeded. If it's local and
    1646              * we haven't reached the local concurrency limit already (or the
    1647              * job must be run locally and maxLocal is 0), it's also ok to
    1648              * resume it.
    1649              */
    1650             Boolean error;
    1651             int status;
     2037            ((job->flags & JOB_SPECIAL) &&
     2038             (maxLocal == 0))) &&
     2039#endif
     2040           (nJobs != maxJobs))
     2041        {
     2042            /*
     2043             * If the job is remote, it's ok to resume it as long as the
     2044             * maximum concurrency won't be exceeded. If it's local and
     2045             * we haven't reached the local concurrency limit already (or the
     2046             * job must be run locally and maxLocal is 0), it's also ok to
     2047             * resume it.
     2048             */
     2049            Boolean error;
     2050            int status;
    16522051
    16532052#ifdef RMT_WANTS_SIGNALS
    1654             if (job->flags & JOB_REMOTE) {
    1655                 error = !Rmt_Signal(job, SIGCONT);
    1656             } else
    1657 #endif  /* RMT_WANTS_SIGNALS */
    1658                 error = (KILL(job->pid, SIGCONT) != 0);
    1659 
    1660             if (!error) {
    1661                 /*
    1662                 * Make sure the user knows we've continued the beast and
    1663                 * actually put the thing in the job table.
    1664                 */
    1665                 job->flags |= JOB_CONTINUING;
    1666                 W_SETTERMSIG(&status, SIGCONT);
    1667                 JobFinish(job, &status);
    1668 
    1669                 job->flags &= ~(JOB_RESUME|JOB_CONTINUING);
    1670                 if (DEBUG(JOB)) {
    1671                    (void) fprintf(stdout, "done\n");
    1672                    (void) fflush(stdout);
    1673                 }
    1674             } else {
    1675                 Error("couldn't resume %s: %s",
    1676                     job->node->name, strerror(errno));
    1677                 status = 0;
    1678                 W_SETEXITSTATUS(&status, 1);
    1679                 JobFinish(job, &status);
    1680             }
    1681         } else {
    1682             /*
    1683              * Job cannot be restarted. Mark the table as full and
    1684              * place the job back on the list of stopped jobs.
    1685              */
    1686             if (DEBUG(JOB)) {
    1687                 (void) fprintf(stdout, "table full\n");
    1688                 (void) fflush(stdout);
    1689             }
    1690             (void) Lst_AtFront(stoppedJobs, (ClientData)job);
    1691             jobFull = TRUE;
    1692             if (DEBUG(JOB)) {
    1693                 (void) fprintf(stdout, "Job queue is full.\n");
    1694                 (void) fflush(stdout);
    1695             }
    1696         }
     2053            if (job->flags & JOB_REMOTE) {
     2054                error = !Rmt_Signal(job, SIGCONT);
     2055            } else
     2056#endif  /* RMT_WANTS_SIGNALS */
     2057                error = (KILL(job->pid, SIGCONT) != 0);
     2058
     2059            if (!error) {
     2060                /*
     2061                * Make sure the user knows we've continued the beast and
     2062                * actually put the thing in the job table.
     2063                */
     2064                job->flags |= JOB_CONTINUING;
     2065                W_SETTERMSIG(&status, SIGCONT);
     2066                JobFinish(job, &status);
     2067
     2068                job->flags &= ~(JOB_RESUME|JOB_CONTINUING);
     2069                if (DEBUG(JOB)) {
     2070                   (void) fprintf(stdout, "done\n");
     2071                   (void) fflush(stdout);
     2072                }
     2073            } else {
     2074                Error("couldn't resume %s: %s",
     2075                    job->node->name, strerror(errno));
     2076                status = 0;
     2077                W_SETEXITSTATUS(&status, 1);
     2078                JobFinish(job, &status);
     2079            }
     2080        } else {
     2081            /*
     2082             * Job cannot be restarted. Mark the table as full and
     2083             * place the job back on the list of stopped jobs.
     2084             */
     2085            if (DEBUG(JOB)) {
     2086                (void) fprintf(stdout, "table full\n");
     2087                (void) fflush(stdout);
     2088            }
     2089            (void) Lst_AtFront(stoppedJobs, (ClientData)job);
     2090            jobFull = TRUE;
     2091            if (DEBUG(JOB)) {
     2092                (void) fprintf(stdout, "Job queue is full.\n");
     2093                (void) fflush(stdout);
     2094            }
     2095        }
    16972096    }
    16982097}
     2098#endif
    16992099
    17002100/*-
    17012101 *-----------------------------------------------------------------------
    17022102 * JobStart  --
    1703  *      Start a target-creation process going for the target described
    1704  *      by the graph node gn.
     2103 *      Start a target-creation process going for the target described
     2104 *      by the graph node gn.
    17052105 *
    17062106 * Results:
    1707  *      JOB_ERROR if there was an error in the commands, JOB_FINISHED
    1708  *      if there isn't actually anything left to do for the job and
    1709  *      JOB_RUNNING if the job has been started.
     2107 *      JOB_ERROR if there was an error in the commands, JOB_FINISHED
     2108 *      if there isn't actually anything left to do for the job and
     2109 *      JOB_RUNNING if the job has been started.
    17102110 *
    17112111 * Side Effects:
    1712  *      A new Job node is created and added to the list of running
    1713  *      jobs. PMake is forked and a child shell created.
     2112 *      A new Job node is created and added to the list of running
     2113 *      jobs. PMake is forked and a child shell created.
    17142114 *-----------------------------------------------------------------------
    17152115 */
    17162116static int
    17172117JobStart(gn, flags, previous)
    1718     GNode         *gn;        /* target to create */
    1719     int            flags;      /* flags for the job to override normal ones.
    1720                                * e.g. JOB_SPECIAL or JOB_IGNDOTS */
    1721     Job           *previous;  /* The previous Job structure for this node,
    1722                                * if any. */
     2118    GNode         *gn;        /* target to create */
     2119    int            flags;      /* flags for the job to override normal ones.
     2120                               * e.g. JOB_SPECIAL or JOB_IGNDOTS */
     2121    Job           *previous;  /* The previous Job structure for this node,
     2122                               * if any. */
    17232123{
    17242124    register Job  *job;       /* new job descriptor */
    1725     char          *argv[4];   /* Argument vector to shell */
    1726     Boolean       cmdsOK;     /* true if the nodes commands were all right */
    1727     Boolean       local;      /* Set true if the job was run locally */
    1728     Boolean       noExec;     /* Set true if we decide not to run the job */
    1729     int           tfd;        /* File descriptor for temp file */
     2125    char          *argv[4];   /* Argument vector to shell */
     2126    Boolean       cmdsOK;     /* true if the nodes commands were all right */
     2127    Boolean       local;      /* Set true if the job was run locally */
     2128    Boolean       noExec;     /* Set true if we decide not to run the job */
     2129    int           tfd;        /* File descriptor for temp file */
    17302130
    17312131    if (previous != NULL) {
    1732         previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
    1733         job = previous;
     2132        previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
     2133        job = previous;
    17342134    } else {
    1735         job = (Job *) emalloc(sizeof(Job));
    1736         if (job == NULL) {
    1737             Punt("JobStart out of memory");
    1738         }
    1739         flags |= JOB_FIRST;
     2135        job = (Job *) emalloc(sizeof(Job));
     2136        if (job == NULL) {
     2137            Punt("JobStart out of memory");
     2138        }
     2139        flags |= JOB_FIRST;
    17402140    }
    17412141
     
    17502150    job->flags = 0;
    17512151    if (Targ_Ignore(gn)) {
    1752         job->flags |= JOB_IGNERR;
     2152        job->flags |= JOB_IGNERR;
    17532153    }
    17542154    if (Targ_Silent(gn)) {
    1755         job->flags |= JOB_SILENT;
     2155        job->flags |= JOB_SILENT;
    17562156    }
    17572157    job->flags |= flags;
     
    17622162     */
    17632163    if (!compatMake && job->flags & JOB_FIRST) {
    1764         cmdsOK = Job_CheckCommands(gn, Error);
     2164        cmdsOK = Job_CheckCommands(gn, Error);
    17652165    } else {
    1766         cmdsOK = TRUE;
     2166        cmdsOK = TRUE;
    17672167    }
    17682168
     
    17742174     */
    17752175    if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) {
    1776         /*
    1777         * We're serious here, but if the commands were bogus, we're
    1778         * also dead...
    1779         */
    1780         if (!cmdsOK) {
    1781             DieHorribly();
    1782         }
    1783 
    1784         (void) strcpy(tfile, TMPPAT);
    1785         if ((tfd = mkstemp(tfile)) == -1)
    1786             Punt("Cannot create temp file: %s", strerror(errno));
    1787         job->cmdFILE = fdopen(tfd, "w+");
    1788         eunlink(tfile);
    1789         if (job->cmdFILE == NULL) {
    1790             close(tfd);
    1791             Punt("Could not open %s", tfile);
    1792         }
    1793         (void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
    1794         /*
    1795         * Send the commands to the command file, flush all its buffers then
    1796         * rewind and remove the thing.
    1797         */
    1798         noExec = FALSE;
    1799 
    1800         /*
    1801         * used to be backwards; replace when start doing multiple commands
    1802         * per shell.
    1803         */
    1804         if (compatMake) {
    1805             /*
    1806              * Be compatible: If this is the first time for this node,
    1807              * verify its commands are ok and open the commands list for
    1808              * sequential access by later invocations of JobStart.
    1809              * Once that is done, we take the next command off the list
    1810              * and print it to the command file. If the command was an
    1811              * ellipsis, note that there's nothing more to execute.
    1812              */
    1813             if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){
    1814                 cmdsOK = FALSE;
    1815             } else {
    1816                 LstNode ln = Lst_Next(gn->commands);
    1817 
    1818                 if ((ln == NILLNODE) ||
    1819                     JobPrintCommand((ClientData) Lst_Datum(ln),
    1820                                     (ClientData) job))
    1821                 {
    1822                     noExec = TRUE;
    1823                     Lst_Close(gn->commands);
    1824                 }
    1825                 if (noExec && !(job->flags & JOB_FIRST)) {
    1826                     /*
    1827                      * If we're not going to execute anything, the job
    1828                      * is done and we need to close down the various
    1829                      * file descriptors we've opened for output, then
    1830                      * call JobDoOutput to catch the final characters or
    1831                      * send the file to the screen... Note that the i/o streams
    1832                      * are only open if this isn't the first job.
    1833                      * Note also that this could not be done in
    1834                      * Job_CatchChildren b/c it wasn't clear if there were
    1835                      * more commands to execute or not...
    1836                      */
    1837                     JobClose(job);
    1838                 }
    1839             }
    1840         } else {
    1841             /*
    1842              * We can do all the commands at once. hooray for sanity
    1843              */
    1844             numCommands = 0;
    1845             Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job);
    1846 
    1847             /*
    1848              * If we didn't print out any commands to the shell script,
    1849              * there's not much point in executing the shell, is there?
    1850              */
    1851             if (numCommands == 0) {
    1852                 noExec = TRUE;
    1853             }
    1854         }
     2176        /*
     2177        * We're serious here, but if the commands were bogus, we're
     2178        * also dead...
     2179        */
     2180        if (!cmdsOK) {
     2181            DieHorribly();
     2182        }
     2183
     2184        (void) strcpy(tfile, TMPPAT);
     2185        if ((tfd = mkstemp(tfile)) == -1)
     2186            Punt("Cannot create temp file: %s", strerror(errno));
     2187        job->cmdFILE = fdopen(tfd, "w+");
     2188        eunlink(tfile);
     2189        if (job->cmdFILE == NULL) {
     2190            close(tfd);
     2191            Punt("Could not open %s", tfile);
     2192        }
     2193        (void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
     2194        /*
     2195        * Send the commands to the command file, flush all its buffers then
     2196        * rewind and remove the thing.
     2197        */
     2198        noExec = FALSE;
     2199
     2200        /*
     2201        * used to be backwards; replace when start doing multiple commands
     2202        * per shell.
     2203        */
     2204        if (compatMake) {
     2205            /*
     2206             * Be compatible: If this is the first time for this node,
     2207             * verify its commands are ok and open the commands list for
     2208             * sequential access by later invocations of JobStart.
     2209             * Once that is done, we take the next command off the list
     2210             * and print it to the command file. If the command was an
     2211             * ellipsis, note that there's nothing more to execute.
     2212             */
     2213            if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){
     2214                cmdsOK = FALSE;
     2215            } else {
     2216                LstNode ln = Lst_Next(gn->commands);
     2217
     2218                if ((ln == NILLNODE) ||
     2219                    JobPrintCommand((ClientData) Lst_Datum(ln),
     2220                                    (ClientData) job))
     2221                {
     2222                    noExec = TRUE;
     2223                    Lst_Close(gn->commands);
     2224                }
     2225                if (noExec && !(job->flags & JOB_FIRST)) {
     2226                    /*
     2227                     * If we're not going to execute anything, the job
     2228                     * is done and we need to close down the various
     2229                     * file descriptors we've opened for output, then
     2230                     * call JobDoOutput to catch the final characters or
     2231                     * send the file to the screen... Note that the i/o streams
     2232                     * are only open if this isn't the first job.
     2233                     * Note also that this could not be done in
     2234                     * Job_CatchChildren b/c it wasn't clear if there were
     2235                     * more commands to execute or not...
     2236                     */
     2237                    JobClose(job);
     2238                }
     2239            }
     2240        } else {
     2241            /*
     2242             * We can do all the commands at once. hooray for sanity
     2243             */
     2244            numCommands = 0;
     2245            Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job);
     2246
     2247            /*
     2248             * If we didn't print out any commands to the shell script,
     2249             * there's not much point in executing the shell, is there?
     2250             */
     2251            if (numCommands == 0) {
     2252                noExec = TRUE;
     2253            }
     2254        }
    18552255    } else if (noExecute) {
    1856         /*
    1857         * Not executing anything -- just print all the commands to stdout
    1858         * in one fell swoop. This will still set up job->tailCmds correctly.
    1859         */
    1860         if (lastNode != gn) {
    1861             MESSAGE(stdout, gn);
    1862             lastNode = gn;
    1863         }
    1864         job->cmdFILE = stdout;
    1865         /*
    1866         * Only print the commands if they're ok, but don't die if they're
    1867         * not -- just let the user know they're bad and keep going. It
    1868         * doesn't do any harm in this case and may do some good.
    1869         */
    1870         if (cmdsOK) {
    1871             Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job);
    1872         }
    1873         /*
    1874         * Don't execute the shell, thank you.
    1875         */
    1876         noExec = TRUE;
     2256        /*
     2257        * Not executing anything -- just print all the commands to stdout
     2258        * in one fell swoop. This will still set up job->tailCmds correctly.
     2259        */
     2260        if (lastNode != gn) {
     2261            MESSAGE(stdout, gn);
     2262            lastNode = gn;
     2263        }
     2264        job->cmdFILE = stdout;
     2265        /*
     2266        * Only print the commands if they're ok, but don't die if they're
     2267        * not -- just let the user know they're bad and keep going. It
     2268        * doesn't do any harm in this case and may do some good.
     2269        */
     2270        if (cmdsOK) {
     2271            Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job);
     2272        }
     2273        /*
     2274        * Don't execute the shell, thank you.
     2275        */
     2276        noExec = TRUE;
    18772277    } else {
    1878         /*
    1879         * Just touch the target and note that no shell should be executed.
    1880         * Set cmdFILE to stdout to make life easier. Check the commands, too,
    1881         * but don't die if they're no good -- it does no harm to keep working
    1882         * up the graph.
    1883         */
    1884         job->cmdFILE = stdout;
    1885         Job_Touch(gn, job->flags&JOB_SILENT);
    1886         noExec = TRUE;
     2278        /*
     2279        * Just touch the target and note that no shell should be executed.
     2280        * Set cmdFILE to stdout to make life easier. Check the commands, too,
     2281        * but don't die if they're no good -- it does no harm to keep working
     2282        * up the graph.
     2283        */
     2284        job->cmdFILE = stdout;
     2285        Job_Touch(gn, job->flags&JOB_SILENT);
     2286        noExec = TRUE;
    18872287    }
    18882288
     
    18912291     */
    18922292    if (noExec) {
    1893         /*
    1894         * Unlink and close the command file if we opened one
    1895         */
    1896         if (job->cmdFILE != stdout) {
    1897             if (job->cmdFILE != NULL)
    1898                 (void) fclose(job->cmdFILE);
    1899         } else {
    1900              (void) fflush(stdout);
    1901         }
    1902 
    1903         /*
    1904         * We only want to work our way up the graph if we aren't here because
    1905         * the commands for the job were no good.
    1906         */
    1907         if (cmdsOK) {
    1908             if (aborting == 0) {
    1909                 if (job->tailCmds != NILLNODE) {
    1910                     Lst_ForEachFrom(job->node->commands, job->tailCmds,
    1911                                     JobSaveCommand,
    1912                                    (ClientData)job->node);
    1913                 }
    1914                 job->node->made = MADE;
    1915                 Make_Update(job->node);
    1916             }
    1917             efree((Address)job);
    1918             return(JOB_FINISHED);
    1919         } else {
    1920             efree((Address)job);
    1921             return(JOB_ERROR);
    1922         }
     2293        /*
     2294        * Unlink and close the command file if we opened one
     2295        */
     2296        if (job->cmdFILE != stdout) {
     2297            if (job->cmdFILE != NULL)
     2298                (void) fclose(job->cmdFILE);
     2299        } else {
     2300             (void) fflush(stdout);
     2301        }
     2302
     2303        /*
     2304        * We only want to work our way up the graph if we aren't here because
     2305        * the commands for the job were no good.
     2306        */
     2307        if (cmdsOK) {
     2308            if (aborting == 0) {
     2309                if (job->tailCmds != NILLNODE) {
     2310                    Lst_ForEachFrom(job->node->commands, job->tailCmds,
     2311                                    JobSaveCommand,
     2312                                   (ClientData)job->node);
     2313                }
     2314                job->node->made = MADE;
     2315                Make_Update(job->node);
     2316            }
     2317            efree((Address)job);
     2318            return(JOB_FINISHED);
     2319        } else {
     2320            efree((Address)job);
     2321            return(JOB_ERROR);
     2322        }
    19232323    } else {
    1924         (void) fflush(job->cmdFILE);
     2324        (void) fflush(job->cmdFILE);
    19252325    }
    19262326
     
    19372337     */
    19382338    if (!compatMake || (job->flags & JOB_FIRST)) {
    1939         if (usePipes) {
    1940             int fd[2];
    1941             if (pipe(fd) == -1)
    1942                 Punt("Cannot create pipe: %s", strerror(errno));
    1943             job->inPipe = fd[0];
    1944             job->outPipe = fd[1];
    1945             (void) fcntl(job->inPipe, F_SETFD, 1);
    1946             (void) fcntl(job->outPipe, F_SETFD, 1);
    1947         } else {
    1948             (void) fprintf(stdout, "Remaking `%s'\n", gn->name);
    1949             (void) fflush(stdout);
    1950             (void) strcpy(job->outFile, TMPPAT);
    1951             if ((job->outFd = mkstemp(job->outFile)) == -1)
    1952                 Punt("cannot create temp file: %s", strerror(errno));
    1953             (void) fcntl(job->outFd, F_SETFD, 1);
    1954         }
     2339#ifdef USE_PIPES
     2340        if (usePipes) {
     2341            int fd[2];
     2342            if (pipe(fd) == -1)
     2343                Punt("Cannot create pipe: %s", strerror(errno));
     2344            job->inPipe = fd[0];
     2345            job->outPipe = fd[1];
     2346            (void) fcntl(job->inPipe, F_SETFD, 1);
     2347            (void) fcntl(job->outPipe, F_SETFD, 1);
     2348        }
     2349        else
     2350#endif /* USE_PIPES */
     2351        {
     2352            (void) fprintf(stdout, "Remaking `%s'\n", gn->name);
     2353            (void) fflush(stdout);
     2354            (void) strcpy(job->outFile, TMPPAT);
     2355            if ((job->outFd = mkstemp(job->outFile)) == -1)
     2356                Punt("cannot create temp file: %s", strerror(errno));
     2357            (void) fcntl(job->outFd, F_SETFD, 1);
     2358        }
    19552359    }
    19562360
     
    19582362    if (!(gn->type & OP_NOEXPORT) && !(runLocalFirst && nLocal < maxLocal)) {
    19592363#ifdef RMT_NO_EXEC
    1960         local = !Rmt_Export(shellPath, argv, job);
     2364        local = !Rmt_Export(shellPath, argv, job);
    19612365#else
    1962         local = !Rmt_Begin(shellPath, argv, job->node);
     2366        local = !Rmt_Begin(shellPath, argv, job->node);
    19632367#endif /* RMT_NO_EXEC */
    1964         if (!local) {
    1965             job->flags |= JOB_REMOTE;
    1966         }
     2368        if (!local) {
     2369            job->flags |= JOB_REMOTE;
     2370        }
    19672371    } else
    19682372#endif
    1969         local = TRUE;
     2373        local = TRUE;
    19702374
    19712375    if (local && (((nLocal >= maxLocal) &&
    1972         !(job->flags & JOB_SPECIAL) &&
     2376        !(job->flags & JOB_SPECIAL) &&
    19732377#ifdef REMOTE
    1974         (!(gn->type & OP_NOEXPORT) || (maxLocal != 0))
     2378        (!(gn->type & OP_NOEXPORT) || (maxLocal != 0))
    19752379#else
    1976         (maxLocal != 0)
    1977 #endif
    1978         )))
     2380        (maxLocal != 0)
     2381#endif
     2382        )))
    19792383    {
    1980         /*
    1981         * The job can only be run locally, but we've hit the limit of
    1982         * local concurrency, so put the job on hold until some other job
    1983         * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END)
    1984         * may be run locally even when the local limit has been reached
    1985         * (e.g. when maxLocal == 0), though they will be exported if at
    1986         * all possible. In addition, any target marked with .NOEXPORT will
    1987         * be run locally if maxLocal is 0.
    1988         */
    1989         jobFull = TRUE;
    1990 
    1991         if (DEBUG(JOB)) {
    1992            (void) fprintf(stdout, "Can only run job locally.\n");
    1993            (void) fflush(stdout);
    1994         }
    1995         job->flags |= JOB_RESTART;
    1996         (void) Lst_AtEnd(stoppedJobs, (ClientData)job);
     2384        /*
     2385        * The job can only be run locally, but we've hit the limit of
     2386        * local concurrency, so put the job on hold until some other job
     2387        * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END)
     2388        * may be run locally even when the local limit has been reached
     2389        * (e.g. when maxLocal == 0), though they will be exported if at
     2390        * all possible. In addition, any target marked with .NOEXPORT will
     2391        * be run locally if maxLocal is 0.
     2392        */
     2393        jobFull = TRUE;
     2394
     2395        if (DEBUG(JOB)) {
     2396           (void) fprintf(stdout, "Can only run job locally.\n");
     2397           (void) fflush(stdout);
     2398        }
     2399        job->flags |= JOB_RESTART;
     2400        (void) Lst_AtEnd(stoppedJobs, (ClientData)job);
    19972401    } else {
    1998         if ((nLocal >= maxLocal) && local) {
    1999             /*
    2000              * If we're running this job locally as a special case (see above),
    2001              * at least say the table is full.
    2002              */
    2003             jobFull = TRUE;
    2004             if (DEBUG(JOB)) {
    2005                 (void) fprintf(stdout, "Local job queue is full.\n");
    2006                 (void) fflush(stdout);
    2007             }
    2008         }
    2009         JobExec(job, argv);
     2402        if ((nLocal >= maxLocal) && local) {
     2403            /*
     2404             * If we're running this job locally as a special case (see above),
     2405             * at least say the table is full.
     2406             */
     2407            jobFull = TRUE;
     2408            if (DEBUG(JOB)) {
     2409                (void) fprintf(stdout, "Local job queue is full.\n");
     2410                (void) fflush(stdout);
     2411            }
     2412        }
     2413        JobExec(job, argv);
    20102414    }
    20112415    return(JOB_RUNNING);
     
    20222426    #ifndef KMK /* @Todo */
    20232427    if (commandShell->noPrint) {
    2024         ecp = Str_FindSubstring(cp, commandShell->noPrint);
    2025         while (ecp != NULL) {
    2026             if (cp != ecp) {
    2027                 *ecp = '\0';
    2028                 if (msg && job->node != lastNode) {
    2029                     MESSAGE(stdout, job->node);
    2030                     lastNode = job->node;
    2031                 }
    2032                 /*
    2033                 * The only way there wouldn't be a newline after
    2034                 * this line is if it were the last in the buffer.
    2035                 * however, since the non-printable comes after it,
    2036                 * there must be a newline, so we don't print one.
    2037                 */
    2038                 (void) fprintf(stdout, "%s", cp);
    2039                 (void) fflush(stdout);
    2040             }
    2041             cp = ecp + commandShell->noPLen;
    2042             if (cp != endp) {
    2043                 /*
    2044                 * Still more to print, look again after skipping
    2045                 * the whitespace following the non-printable
    2046                 * command....
    2047                 */
    2048                 cp++;
    2049                 while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
    2050                     cp++;
    2051                 }
    2052                 ecp = Str_FindSubstring(cp, commandShell->noPrint);
    2053             } else {
    2054                 return cp;
    2055             }
    2056         }
     2428        ecp = Str_FindSubstring(cp, commandShell->noPrint);
     2429        while (ecp != NULL) {
     2430            if (cp != ecp) {
     2431                *ecp = '\0';
     2432                if (msg && job->node != lastNode) {
     2433                    MESSAGE(stdout, job->node);
     2434                    lastNode = job->node;
     2435                }
     2436                /*
     2437                * The only way there wouldn't be a newline after
     2438                * this line is if it were the last in the buffer.
     2439                * however, since the non-printable comes after it,
     2440                * there must be a newline, so we don't print one.
     2441                */
     2442                (void) fprintf(stdout, "%s", cp);
     2443                (void) fflush(stdout);
     2444            }
     2445            cp = ecp + commandShell->noPLen;
     2446            if (cp != endp) {
     2447                /*
     2448                * Still more to print, look again after skipping
     2449                * the whitespace following the non-printable
     2450                * command....
     2451                */
     2452                cp++;
     2453                while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
     2454                    cp++;
     2455                }
     2456                ecp = Str_FindSubstring(cp, commandShell->noPrint);
     2457            } else {
     2458                return cp;
     2459            }
     2460        }
    20572461    }
    20582462    #endif /*!KMK*/
     
    20632467 *-----------------------------------------------------------------------
    20642468 * JobDoOutput  --
    2065  *      This function is called at different times depending on
    2066  *      whether the user has specified that output is to be collected
    2067  *      via pipes or temporary files. In the former case, we are called
    2068  *      whenever there is something to read on the pipe. We collect more
    2069  *      output from the given job and store it in the job's outBuf. If
    2070  *      this makes up a line, we print it tagged by the job's identifier,
    2071  *      as necessary.
    2072  *      If output has been collected in a temporary file, we open the
    2073  *      file and read it line by line, transfering it to our own
    2074  *      output channel until the file is empty. At which point we
    2075  *      remove the temporary file.
    2076  *      In both cases, however, we keep our figurative eye out for the
    2077  *      'noPrint' line for the shell from which the output came. If
    2078  *      we recognize a line, we don't print it. If the command is not
    2079  *      alone on the line (the character after it is not \0 or \n), we
    2080  *      do print whatever follows it.
     2469 *      This function is called at different times depending on
     2470 *      whether the user has specified that output is to be collected
     2471 *      via pipes or temporary files. In the former case, we are called
     2472 *      whenever there is something to read on the pipe. We collect more
     2473 *      output from the given job and store it in the job's outBuf. If
     2474 *      this makes up a line, we print it tagged by the job's identifier,
     2475 *      as necessary.
     2476 *      If output has been collected in a temporary file, we open the
     2477 *      file and read it line by line, transfering it to our own
     2478 *      output channel until the file is empty. At which point we
     2479 *      remove the temporary file.
     2480 *      In both cases, however, we keep our figurative eye out for the
     2481 *      'noPrint' line for the shell from which the output came. If
     2482 *      we recognize a line, we don't print it. If the command is not
     2483 *      alone on the line (the character after it is not \0 or \n), we
     2484 *      do print whatever follows it.
    20812485 *
    20822486 * Results:
    2083  *      None
     2487 *      None
    20842488 *
    20852489 * Side Effects:
    2086  *      curPos may be shifted as may the contents of outBuf.
     2490 *      curPos may be shifted as may the contents of outBuf.
    20872491 *-----------------------------------------------------------------------
    20882492 */
    20892493STATIC void
    20902494JobDoOutput(job, finish)
    2091     register Job   *job;          /* the job whose output needs printing */
    2092     Boolean        finish;        /* TRUE if this is the last time we'll be
    2093                                    * called for this job */
     2495    register Job   *job;          /* the job whose output needs printing */
     2496    Boolean        finish;        /* TRUE if this is the last time we'll be
     2497                                   * called for this job */
    20942498{
    20952499    Boolean       gotNL = FALSE;  /* true if got a newline */
    2096     Boolean       fbuf;           /* true if our buffer filled up */
    2097     register int  nr;             /* number of bytes read */
    2098     register int  i;              /* auxiliary index into outBuf */
    2099     register int  max;            /* limit for i (end of current data) */
    2100     int           nRead;          /* (Temporary) number of bytes read */
    2101 
    2102     FILE          *oFILE;         /* Stream pointer to shell's output file */
     2500    Boolean       fbuf;           /* true if our buffer filled up */
     2501    register int  nr;             /* number of bytes read */
     2502    register int  i;              /* auxiliary index into outBuf */
     2503    register int  max;            /* limit for i (end of current data) */
     2504    int           nRead;          /* (Temporary) number of bytes read */
     2505
     2506    FILE          *oFILE;         /* Stream pointer to shell's output file */
    21032507    char          inLine[132];
    21042508
    21052509
     2510#ifdef USE_PIPES
    21062511    if (usePipes) {
    2107         /*
    2108         * Read as many bytes as will fit in the buffer.
    2109         */
     2512        /*
     2513        * Read as many bytes as will fit in the buffer.
     2514        */
    21102515end_loop:
    2111         gotNL = FALSE;
    2112         fbuf = FALSE;
    2113 
    2114         nRead = read(job->inPipe, &job->outBuf[job->curPos],
    2115                          JOB_BUFSIZE - job->curPos);
    2116         if (nRead < 0) {
    2117             if (DEBUG(JOB)) {
    2118                 perror("JobDoOutput(piperead)");
    2119             }
    2120             nr = 0;
    2121         } else {
    2122             nr = nRead;
    2123         }
    2124 
    2125         /*
    2126          * If we hit the end-of-file (the job is dead), we must flush its
    2127          * remaining output, so pretend we read a newline if there's any
    2128          * output remaining in the buffer.
    2129          * Also clear the 'finish' flag so we stop looping.
    2130          */
    2131         if ((nr == 0) && (job->curPos != 0)) {
    2132             job->outBuf[job->curPos] = '\n';
    2133             nr = 1;
    2134             finish = FALSE;
    2135         } else if (nr == 0) {
    2136             finish = FALSE;
    2137         }
    2138 
    2139         /*
    2140          * Look for the last newline in the bytes we just got. If there is
    2141          * one, break out of the loop with 'i' as its index and gotNL set
    2142          * TRUE.
    2143          */
    2144         max = job->curPos + nr;
    2145         for (i = job->curPos + nr - 1; i >= job->curPos; i--) {
    2146             if (job->outBuf[i] == '\n') {
    2147                 gotNL = TRUE;
    2148                 break;
    2149             } else if (job->outBuf[i] == '\0') {
    2150                 /*
    2151                  * Why?
    2152                  */
    2153                 job->outBuf[i] = ' ';
    2154             }
    2155         }
    2156 
    2157         if (!gotNL) {
    2158             job->curPos += nr;
    2159             if (job->curPos == JOB_BUFSIZE) {
    2160                 /*
    2161                  * If we've run out of buffer space, we have no choice
    2162                  * but to print the stuff. sigh.
    2163                  */
    2164                 fbuf = TRUE;
    2165                 i = job->curPos;
    2166             }
    2167         }
    2168         if (gotNL || fbuf) {
    2169             /*
    2170              * Need to send the output to the screen. Null terminate it
    2171              * first, overwriting the newline character if there was one.
    2172              * So long as the line isn't one we should filter (according
    2173              * to the shell description), we print the line, preceeded
    2174              * by a target banner if this target isn't the same as the
    2175              * one for which we last printed something.
    2176              * The rest of the data in the buffer are then shifted down
    2177              * to the start of the buffer and curPos is set accordingly.
    2178              */
    2179             job->outBuf[i] = '\0';
    2180             if (i >= job->curPos) {
    2181                 char *cp;
    2182 
    2183                 cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE);
    2184 
    2185                 /*
    2186                  * There's still more in that thar buffer. This time, though,
    2187                  * we know there's no newline at the end, so we add one of
    2188                  * our own efree will.
    2189                  */
    2190                 if (*cp != '\0') {
    2191                     if (job->node != lastNode) {
    2192                         MESSAGE(stdout, job->node);
    2193                         lastNode = job->node;
    2194                     }
    2195                     (void) fprintf(stdout, "%s%s", cp, gotNL ? "\n" : "");
    2196                     (void) fflush(stdout);
    2197                 }
    2198             }
    2199             if (i < max - 1) {
    2200                 /* shift the remaining characters down */
    2201                 (void) memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1));
    2202                 job->curPos = max - (i + 1);
    2203 
    2204             } else {
    2205                 /*
    2206                  * We have written everything out, so we just start over
    2207                  * from the start of the buffer. No copying. No nothing.
    2208                  */
    2209                 job->curPos = 0;
    2210             }
    2211         }
    2212         if (finish) {
    2213             /*
    2214              * If the finish flag is true, we must loop until we hit
    2215              * end-of-file on the pipe. This is guaranteed to happen
    2216              * eventually since the other end of the pipe is now closed
    2217              * (we closed it explicitly and the child has exited). When
    2218              * we do get an EOF, finish will be set FALSE and we'll fall
    2219              * through and out.
    2220              */
    2221             goto end_loop;
    2222         }
    2223     } else {
    2224         /*
    2225          * We've been called to retrieve the output of the job from the
    2226          * temporary file where it's been squirreled away. This consists of
    2227          * opening the file, reading the output line by line, being sure not
    2228          * to print the noPrint line for the shell we used, then close and
    2229          * remove the temporary file. Very simple.
    2230          *
    2231          * Change to read in blocks and do FindSubString type things as for
    2232          * pipes? That would allow for "@echo -n..."
    2233          */
    2234         oFILE = fopen(job->outFile, "r");
    2235         if (oFILE != NULL) {
    2236             (void) fprintf(stdout, "Results of making %s:\n", job->node->name);
    2237             (void) fflush(stdout);
    2238             while (fgets(inLine, sizeof(inLine), oFILE) != NULL) {
    2239                 register char   *cp, *endp, *oendp;
    2240 
    2241                 cp = inLine;
    2242                 oendp = endp = inLine + strlen(inLine);
    2243                 if (endp[-1] == '\n') {
    2244                     *--endp = '\0';
    2245                 }
    2246                 cp = JobOutput(job, inLine, endp, FALSE);
    2247 
    2248                 /*
    2249                  * There's still more in that thar buffer. This time, though,
    2250                  * we know there's no newline at the end, so we add one of
    2251                  * our own efree will.
    2252                  */
    2253                 (void) fprintf(stdout, "%s", cp);
    2254                 (void) fflush(stdout);
    2255                 if (endp != oendp) {
    2256                     (void) fprintf(stdout, "\n");
    2257                     (void) fflush(stdout);
    2258                 }
    2259             }
    2260             (void) fclose(oFILE);
    2261             (void) eunlink(job->outFile);
    2262         }
     2516        gotNL = FALSE;
     2517        fbuf = FALSE;
     2518
     2519        nRead = read(job->inPipe, &job->outBuf[job->curPos],
     2520                         JOB_BUFSIZE - job->curPos);
     2521        if (nRead < 0) {
     2522            if (DEBUG(JOB)) {
     2523                perror("JobDoOutput(piperead)");
     2524            }
     2525            nr = 0;
     2526        } else {
     2527            nr = nRead;
     2528        }
     2529
     2530        /*
     2531         * If we hit the end-of-file (the job is dead), we must flush its
     2532         * remaining output, so pretend we read a newline if there's any
     2533         * output remaining in the buffer.
     2534         * Also clear the 'finish' flag so we stop looping.
     2535         */
     2536        if ((nr == 0) && (job->curPos != 0)) {
     2537            job->outBuf[job->curPos] = '\n';
     2538            nr = 1;
     2539            finish = FALSE;
     2540        } else if (nr == 0) {
     2541            finish = FALSE;
     2542        }
     2543
     2544        /*
     2545         * Look for the last newline in the bytes we just got. If there is
     2546         * one, break out of the loop with 'i' as its index and gotNL set
     2547         * TRUE.
     2548         */
     2549        max = job->curPos + nr;
     2550        for (i = job->curPos + nr - 1; i >= job->curPos; i--) {
     2551            if (job->outBuf[i] == '\n') {
     2552                gotNL = TRUE;
     2553                break;
     2554            } else if (job->outBuf[i] == '\0') {
     2555                /*
     2556                 * Why?
     2557                 */
     2558                job->outBuf[i] = ' ';
     2559            }
     2560        }
     2561
     2562        if (!gotNL) {
     2563            job->curPos += nr;
     2564            if (job->curPos == JOB_BUFSIZE) {
     2565                /*
     2566                 * If we've run out of buffer space, we have no choice
     2567                 * but to print the stuff. sigh.
     2568                 */
     2569                fbuf = TRUE;
     2570                i = job->curPos;
     2571            }
     2572        }
     2573        if (gotNL || fbuf) {
     2574            /*
     2575             * Need to send the output to the screen. Null terminate it
     2576             * first, overwriting the newline character if there was one.
     2577             * So long as the line isn't one we should filter (according
     2578             * to the shell description), we print the line, preceeded
     2579             * by a target banner if this target isn't the same as the
     2580             * one for which we last printed something.
     2581             * The rest of the data in the buffer are then shifted down
     2582             * to the start of the buffer and curPos is set accordingly.
     2583             */
     2584            job->outBuf[i] = '\0';
     2585            if (i >= job->curPos) {
     2586                char *cp;
     2587
     2588                cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE);
     2589
     2590                /*
     2591                 * There's still more in that thar buffer. This time, though,
     2592                 * we know there's no newline at the end, so we add one of
     2593                 * our own efree will.
     2594                 */
     2595                if (*cp != '\0') {
     2596                    if (job->node != lastNode) {
     2597                        MESSAGE(stdout, job->node);
     2598                        lastNode = job->node;
     2599                    }
     2600                    (void) fprintf(stdout, "%s%s", cp, gotNL ? "\n" : "");
     2601                    (void) fflush(stdout);
     2602                }
     2603            }
     2604            if (i < max - 1) {
     2605                /* shift the remaining characters down */
     2606                (void) memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1));
     2607                job->curPos = max - (i + 1);
     2608
     2609            } else {
     2610                /*
     2611                 * We have written everything out, so we just start over
     2612                 * from the start of the buffer. No copying. No nothing.
     2613                 */
     2614                job->curPos = 0;
     2615            }
     2616        }
     2617        if (finish) {
     2618            /*
     2619             * If the finish flag is true, we must loop until we hit
     2620             * end-of-file on the pipe. This is guaranteed to happen
     2621             * eventually since the other end of the pipe is now closed
     2622             * (we closed it explicitly and the child has exited). When
     2623             * we do get an EOF, finish will be set FALSE and we'll fall
     2624             * through and out.
     2625             */
     2626            goto end_loop;
     2627        }
     2628    }
     2629    else
     2630#endif /* USE_PIPES */
     2631    {
     2632        /*
     2633         * We've been called to retrieve the output of the job from the
     2634         * temporary file where it's been squirreled away. This consists of
     2635         * opening the file, reading the output line by line, being sure not
     2636         * to print the noPrint line for the shell we used, then close and
     2637         * remove the temporary file. Very simple.
     2638         *
     2639         * Change to read in blocks and do FindSubString type things as for
     2640         * pipes? That would allow for "@echo -n..."
     2641         */
     2642        oFILE = fopen(job->outFile, "r");
     2643        if (oFILE != NULL) {
     2644            (void) fprintf(stdout, "Results of making %s:\n", job->node->name);
     2645            (void) fflush(stdout);
     2646            while (fgets(inLine, sizeof(inLine), oFILE) != NULL) {
     2647                register char   *cp, *endp, *oendp;
     2648
     2649                cp = inLine;
     2650                oendp = endp = inLine + strlen(inLine);
     2651                if (endp[-1] == '\n') {
     2652                    *--endp = '\0';
     2653                }
     2654                cp = JobOutput(job, inLine, endp, FALSE);
     2655
     2656                /*
     2657                 * There's still more in that thar buffer. This time, though,
     2658                 * we know there's no newline at the end, so we add one of
     2659                 * our own efree will.
     2660                 */
     2661                (void) fprintf(stdout, "%s", cp);
     2662                (void) fflush(stdout);
     2663                if (endp != oendp) {
     2664                    (void) fprintf(stdout, "\n");
     2665                    (void) fflush(stdout);
     2666                }
     2667            }
     2668            (void) fclose(oFILE);
     2669            (void) eunlink(job->outFile);
     2670        }
    22632671    }
    22642672}
     
    22672675 *-----------------------------------------------------------------------
    22682676 * Job_CatchChildren --
    2269  *      Handle the exit of a child. Called from Make_Make.
     2677 *      Handle the exit of a child. Called from Make_Make.
    22702678 *
    22712679 * Results:
    2272  *      none.
     2680 *      none.
    22732681 *
    22742682 * Side Effects:
    2275  *      The job descriptor is removed from the list of children.
     2683 *      The job descriptor is removed from the list of children.
    22762684 *
    22772685 * Notes:
    2278  *      We do waits, blocking or not, according to the wisdom of our
    2279  *      caller, until there are no more children to report. For each
    2280  *      job, call JobFinish to finish things off. This will take care of
    2281  *      putting jobs on the stoppedJobs queue.
     2686 *      We do waits, blocking or not, according to the wisdom of our
     2687 *      caller, until there are no more children to report. For each
     2688 *      job, call JobFinish to finish things off. This will take care of
     2689 *      putting jobs on the stoppedJobs queue.
    22822690 *
    22832691 *-----------------------------------------------------------------------
     
    22852693void
    22862694Job_CatchChildren(block)
    2287     Boolean       block;        /* TRUE if should block on the wait. */
     2695    Boolean       block;        /* TRUE if should block on the wait. */
    22882696{
    2289     int           pid;          /* pid of dead child */
    2290     register Job  *job;         /* job descriptor for dead child */
    2291     LstNode       jnode;        /* list element for finding job */
    2292     int           status;       /* Exit/termination status */
     2697#ifdef USE_KLIB
     2698    int           pid;          /* pid of dead child */
     2699    register Job *job;          /* job descriptor for dead child */
     2700    LstNode       jnode;        /* list element for finding job */
     2701    KPROCRES      status;       /* Exit/termination status */
    22932702
    22942703    /*
     
    22962705     */
    22972706    if (nLocal == 0) {
    2298         return;
     2707        return;
     2708    }
     2709
     2710    while (!kProcWait(KPID_NULL, KPROCWAIT_FLAGS_NOWAIT, &status, &pid))
     2711    {
     2712        if (DEBUG(JOB)) {
     2713            (void) fprintf(stdout, "Process %d exited or stopped.\n", pid);
     2714            (void) fflush(stdout);
     2715        }
     2716
     2717        jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid);
     2718        if (jnode == NILLNODE) {
     2719            Error("Child (%d) not in table?", pid);
     2720            continue;
     2721        } else {
     2722            job = (Job *) Lst_Datum(jnode);
     2723            (void) Lst_Remove(jobs, jnode);
     2724            nJobs -= 1;
     2725            if (jobFull && DEBUG(JOB)) {
     2726                (void) fprintf(stdout, "Job queue is no longer full.\n");
     2727                (void) fflush(stdout);
     2728            }
     2729            jobFull = FALSE;
     2730            nLocal -= 1;
     2731        }
     2732        JobFinish(job, &status);
     2733    }
     2734
     2735#else /* Don't Use kLib */
     2736    int           pid;          /* pid of dead child */
     2737    register Job  *job;         /* job descriptor for dead child */
     2738    LstNode       jnode;        /* list element for finding job */
     2739    int           status;       /* Exit/termination status */
     2740
     2741    /*
     2742     * Don't even bother if we know there's no one around.
     2743     */
     2744    if (nLocal == 0) {
     2745        return;
    22992746    }
    23002747
    23012748    while ((pid = waitpid((pid_t) -1, &status,
    2302                           (block?0:WNOHANG)|WUNTRACED)) > 0)
     2749                          (block?0:WNOHANG)|WUNTRACED)) > 0)
    23032750    {
    2304         if (DEBUG(JOB)) {
    2305             (void) fprintf(stdout, "Process %d exited or stopped.\n", pid);
    2306             (void) fflush(stdout);
    2307         }
    2308 
    2309 
    2310         jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid);
    2311 
    2312         if (jnode == NILLNODE) {
    2313             if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) {
    2314                 jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid);
    2315                 if (jnode == NILLNODE) {
    2316                     Error("Resumed child (%d) not in table", pid);
    2317                     continue;
    2318                 }
    2319                 job = (Job *)Lst_Datum(jnode);
    2320                 (void) Lst_Remove(stoppedJobs, jnode);
    2321             } else {
    2322                 Error("Child (%d) not in table?", pid);
    2323                 continue;
    2324             }
    2325         } else {
    2326             job = (Job *) Lst_Datum(jnode);
    2327             (void) Lst_Remove(jobs, jnode);
    2328             nJobs -= 1;
    2329             if (jobFull && DEBUG(JOB)) {
    2330                 (void) fprintf(stdout, "Job queue is no longer full.\n");
    2331                 (void) fflush(stdout);
    2332             }
    2333             jobFull = FALSE;
     2751        if (DEBUG(JOB)) {
     2752            (void) fprintf(stdout, "Process %d exited or stopped.\n", pid);
     2753            (void) fflush(stdout);
     2754        }
     2755
     2756
     2757        jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid);
     2758
     2759        if (jnode == NILLNODE) {
     2760            if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) {
     2761                jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid);
     2762                if (jnode == NILLNODE) {
     2763                    Error("Resumed child (%d) not in table", pid);
     2764                    continue;
     2765                }
     2766                job = (Job *)Lst_Datum(jnode);
     2767                (void) Lst_Remove(stoppedJobs, jnode);
     2768            } else {
     2769                Error("Child (%d) not in table?", pid);
     2770                continue;
     2771            }
     2772        } else {
     2773            job = (Job *) Lst_Datum(jnode);
     2774            (void) Lst_Remove(jobs, jnode);
     2775            nJobs -= 1;
     2776            if (jobFull && DEBUG(JOB)) {
     2777                (void) fprintf(stdout, "Job queue is no longer full.\n");
     2778                (void) fflush(stdout);
     2779            }
     2780            jobFull = FALSE;
    23342781#ifdef REMOTE
    2335             if (!(job->flags & JOB_REMOTE)) {
    2336                 if (DEBUG(JOB)) {
    2337                     (void) fprintf(stdout,
    2338                                    "Job queue has one fewer local process.\n");
    2339                     (void) fflush(stdout);
    2340                 }
    2341                 nLocal -= 1;
    2342             }
     2782            if (!(job->flags & JOB_REMOTE)) {
     2783                if (DEBUG(JOB)) {
     2784                    (void) fprintf(stdout,
     2785                                   "Job queue has one fewer local process.\n");
     2786                    (void) fflush(stdout);
     2787                }
     2788                nLocal -= 1;
     2789            }
    23432790#else
    2344             nLocal -= 1;
    2345 #endif
    2346         }
    2347 
    2348         JobFinish(job, &status);
    2349     }
     2791            nLocal -= 1;
     2792#endif
     2793        }
     2794
     2795        JobFinish(job, &status);
     2796    }
     2797#endif /* USE_KLIB */
    23502798}
    23512799
     
    23532801 *-----------------------------------------------------------------------
    23542802 * Job_CatchOutput --
    2355  *      Catch the output from our children, if we're using
    2356  *      pipes do so. Otherwise just block time until we get a
    2357  *      signal (most likely a SIGCHLD) since there's no point in
    2358  *      just spinning when there's nothing to do and the reaping
    2359  *      of a child can wait for a while.
     2803 *      Catch the output from our children, if we're using
     2804 *      pipes do so. Otherwise just block time until we get a
     2805 *      signal (most likely a SIGCHLD) since there's no point in
     2806 *      just spinning when there's nothing to do and the reaping
     2807 *      of a child can wait for a while.
    23602808 *
    23612809 * Results:
    2362  *      None
     2810 *      None
    23632811 *
    23642812 * Side Effects:
    2365  *      Output is read from pipes if we're piping.
     2813 *      Output is read from pipes if we're piping.
    23662814 * -----------------------------------------------------------------------
    23672815 */
     
    23692817Job_CatchOutput()
    23702818{
    2371     int                   nfds;
    2372     struct timeval        timeout;
    2373     fd_set                readfds;
    2374     register LstNode      ln;
    2375     register Job          *job;
     2819    int                   nfds;
     2820    struct timeval        timeout;
     2821    fd_set                readfds;
     2822    register LstNode      ln;
     2823    register Job          *job;
    23762824#ifdef RMT_WILL_WATCH
    2377     int                   pnJobs;       /* Previous nJobs */
     2825    int                   pnJobs;       /* Previous nJobs */
    23782826#endif
    23792827
     
    23992847     */
    24002848    while (nJobs != 0 && pnJobs == nJobs) {
    2401         Rmt_Wait();
     2849        Rmt_Wait();
    24022850    }
    24032851#else
     2852#ifdef USE_PIPES
    24042853    if (usePipes) {
    2405         readfds = outputs;
    2406         timeout.tv_sec = SEL_SEC;
    2407         timeout.tv_usec = SEL_USEC;
    2408 
    2409         if ((nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0,
    2410                            (fd_set *) 0, &timeout)) <= 0)
    2411             return;
    2412         else {
    2413             if (Lst_Open(jobs) == FAILURE) {
    2414                 Punt("Cannot open job table");
    2415             }
    2416             while (nfds && (ln = Lst_Next(jobs)) != NILLNODE) {
    2417                 job = (Job *) Lst_Datum(ln);
    2418                 if (FD_ISSET(job->inPipe, &readfds)) {
    2419                     JobDoOutput(job, FALSE);
    2420                     nfds -= 1;
    2421                 }
    2422             }
    2423             Lst_Close(jobs);
    2424         }
    2425     }
     2854        readfds = outputs;
     2855        timeout.tv_sec = SEL_SEC;
     2856        timeout.tv_usec = SEL_USEC;
     2857
     2858        if ((nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0,
     2859                           (fd_set *) 0, &timeout)) <= 0)
     2860            return;
     2861        else {
     2862            if (Lst_Open(jobs) == FAILURE) {
     2863                Punt("Cannot open job table");
     2864            }
     2865            while (nfds && (ln = Lst_Next(jobs)) != NILLNODE) {
     2866                job = (Job *) Lst_Datum(ln);
     2867                if (FD_ISSET(job->inPipe, &readfds)) {
     2868                    JobDoOutput(job, FALSE);
     2869                    nfds -= 1;
     2870                }
     2871            }
     2872            Lst_Close(jobs);
     2873        }
     2874    }
     2875#endif /* USE_PIPES */
    24262876#endif /* RMT_WILL_WATCH */
    24272877}
     
    24302880 *-----------------------------------------------------------------------
    24312881 * Job_Make --
    2432  *      Start the creation of a target. Basically a front-end for
    2433  *      JobStart used by the Make module.
     2882 *      Start the creation of a target. Basically a front-end for
     2883 *      JobStart used by the Make module.
    24342884 *
    24352885 * Results:
    2436  *      None.
     2886 *      None.
    24372887 *
    24382888 * Side Effects:
    2439  *      Another job is started.
     2889 *      Another job is started.
    24402890 *
    24412891 *-----------------------------------------------------------------------
     
    24512901 *-----------------------------------------------------------------------
    24522902 * Job_Init --
    2453  *      Initialize the process module
     2903 *      Initialize the process module
    24542904 *
    24552905 * Results:
    2456  *      none
     2906 *      none
    24572907 *
    24582908 * Side Effects:
    2459  *      lists and counters are initialized
     2909 *      lists and counters are initialized
    24602910 *-----------------------------------------------------------------------
    24612911 */
     
    24632913Job_Init(maxproc, maxlocal)
    24642914    int           maxproc;  /* the greatest number of jobs which may be
    2465                              * running at one time */
    2466     int           maxlocal; /* the greatest number of local jobs which may
    2467                              * be running at once. */
     2915                             * running at one time */
     2916    int           maxlocal; /* the greatest number of local jobs which may
     2917                             * be running at once. */
    24682918{
    24692919    GNode         *begin;     /* node for commands to do at the very start */
    24702920
    2471     jobs =        Lst_Init(FALSE);
     2921    jobs =        Lst_Init(FALSE);
     2922#ifdef SIGCONT
    24722923    stoppedJobs = Lst_Init(FALSE);
    2473     maxJobs =     maxproc;
    2474     maxLocal =    maxlocal;
    2475     nJobs =       0;
    2476     nLocal =      0;
    2477     jobFull =     FALSE;
    2478 
    2479     aborting =    0;
    2480     errors =      0;
    2481 
    2482     lastNode =    NILGNODE;
     2924#endif
     2925    maxJobs =     maxproc;
     2926    maxLocal =    maxlocal;
     2927    nJobs =       0;
     2928    nLocal =      0;
     2929    jobFull =     FALSE;
     2930
     2931    aborting =    0;
     2932    errors =      0;
     2933
     2934    lastNode =    NILGNODE;
    24832935
    24842936    if (maxJobs == 1 || beVerbose == 0
    24852937#ifdef REMOTE
    2486         || noMessages
    2487 #endif
    2488                      ) {
    2489         /*
    2490         * If only one job can run at a time, there's no need for a banner,
    2491         * no is there?
    2492         */
    2493         targFmt = "";
     2938        || noMessages
     2939#endif
     2940                     ) {
     2941        /*
     2942        * If only one job can run at a time, there's no need for a banner,
     2943        * no is there?
     2944        */
     2945        targFmt = "";
    24942946    } else {
    2495         targFmt = TARG_FMT;
     2947        targFmt = TARG_FMT;
    24962948    }
    24972949
    24982950#ifndef KMK
    24992951    if (shellPath == NULL) {
    2500         /*
    2501         * The user didn't specify a shell to use, so we are using the
    2502         * default one... Both the absolute path and the last component
    2503         * must be set. The last component is taken from the 'name' field
    2504         * of the default shell description pointed-to by commandShell.
    2505         * All default shells are located in _PATH_DEFSHELLDIR.
    2506         */
    2507         shellName = commandShell->name;
    2508         shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
     2952        /*
     2953        * The user didn't specify a shell to use, so we are using the
     2954        * default one... Both the absolute path and the last component
     2955        * must be set. The last component is taken from the 'name' field
     2956        * of the default shell description pointed-to by commandShell.
     2957        * All default shells are located in _PATH_DEFSHELLDIR.
     2958        */
     2959        shellName = commandShell->name;
     2960        shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
    25092961    }
    25102962
    25112963    if (commandShell->exit == NULL) {
    2512         commandShell->exit = "";
     2964        commandShell->exit = "";
    25132965    }
    25142966    if (commandShell->echo == NULL) {
    2515         commandShell->echo = "";
     2967        commandShell->echo = "";
    25162968    }
    25172969#endif
     
    25222974     */
    25232975    if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
    2524         (void) signal(SIGINT, JobPassSig);
    2525     }
     2976        (void) signal(SIGINT, JobPassSig);
     2977    }
     2978#ifdef SIGHUP  /* not all systems supports this signal */
    25262979    if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
    2527         (void) signal(SIGHUP, JobPassSig);
    2528     }
     2980        (void) signal(SIGHUP, JobPassSig);
     2981    }
     2982#endif
     2983#ifdef SIGQUIT /* not all systems supports this signal */
    25292984    if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
    2530         (void) signal(SIGQUIT, JobPassSig);
    2531     }
     2985        (void) signal(SIGQUIT, JobPassSig);
     2986    }
     2987#endif
    25322988    if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
    2533         (void) signal(SIGTERM, JobPassSig);
     2989        (void) signal(SIGTERM, JobPassSig);
    25342990    }
    25352991    /*
     
    25412997#if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP)
    25422998    if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) {
    2543         (void) signal(SIGTSTP, JobPassSig);
     2999        (void) signal(SIGTSTP, JobPassSig);
    25443000    }
    25453001    if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) {
    2546         (void) signal(SIGTTOU, JobPassSig);
     3002        (void) signal(SIGTTOU, JobPassSig);
    25473003    }
    25483004    if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) {
    2549         (void) signal(SIGTTIN, JobPassSig);
     3005        (void) signal(SIGTTIN, JobPassSig);
    25503006    }
    25513007    if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) {
    2552         (void) signal(SIGWINCH, JobPassSig);
     3008        (void) signal(SIGWINCH, JobPassSig);
    25533009    }
    25543010#endif
     
    25573013
    25583014    if (begin != NILGNODE) {
    2559         JobStart(begin, JOB_SPECIAL, (Job *)0);
    2560         while (nJobs) {
    2561             Job_CatchOutput();
     3015        JobStart(begin, JOB_SPECIAL, (Job *)0);
     3016        while (nJobs) {
     3017            Job_CatchOutput();
    25623018#ifndef RMT_WILL_WATCH
    2563             Job_CatchChildren(!usePipes);
     3019            Job_CatchChildren(!usePipes);
    25643020#endif /* RMT_WILL_WATCH */
    2565         }
     3021        }
    25663022    }
    25673023    postCommands = Targ_FindNode(".END", TARG_CREATE);
     
    25713027 *-----------------------------------------------------------------------
    25723028 * Job_Full --
    2573  *      See if the job table is full. It is considered full if it is OR
    2574  *      if we are in the process of aborting OR if we have
    2575  *      reached/exceeded our local quota. This prevents any more jobs
    2576  *      from starting up.
     3029 *      See if the job table is full. It is considered full if it is OR
     3030 *      if we are in the process of aborting OR if we have
     3031 *      reached/exceeded our local quota. This prevents any more jobs
     3032 *      from starting up.
    25773033 *
    25783034 * Results:
    2579  *      TRUE if the job table is full, FALSE otherwise
     3035 *      TRUE if the job table is full, FALSE otherwise
    25803036 * Side Effects:
    2581  *      None.
     3037 *      None.
    25823038 *-----------------------------------------------------------------------
    25833039 */
     
    25913047 *-----------------------------------------------------------------------
    25923048 * Job_Empty --
    2593  *      See if the job table is empty.  Because the local concurrency may
    2594  *      be set to 0, it is possible for the job table to become empty,
    2595  *      while the list of stoppedJobs remains non-empty. In such a case,
    2596  *      we want to restart as many jobs as we can.
     3049 *      See if the job table is empty.  Because the local concurrency may
     3050 *      be set to 0, it is possible for the job table to become empty,
     3051 *      while the list of stoppedJobs remains non-empty. In such a case,
     3052 *      we want to restart as many jobs as we can.
    25973053 *
    25983054 * Results:
    2599  *      TRUE if it is. FALSE if it ain't.
     3055 *      TRUE if it is. FALSE if it ain't.
    26003056 *
    26013057 * Side Effects:
    2602  *      None.
     3058 *      None.
    26033059 *
    26043060 * -----------------------------------------------------------------------
     
    26083064{
    26093065    if (nJobs == 0) {
    2610         if (!Lst_IsEmpty(stoppedJobs) && !aborting) {
    2611             /*
    2612              * The job table is obviously not full if it has no jobs in
    2613              * it...Try and restart the stopped jobs.
    2614              */
    2615             jobFull = FALSE;
    2616             JobRestartJobs();
    2617             return(FALSE);
    2618         } else {
    2619             return(TRUE);
    2620         }
     3066#ifdef SIGCONT
     3067        if (!Lst_IsEmpty(stoppedJobs) && !aborting) {
     3068            /*
     3069             * The job table is obviously not full if it has no jobs in
     3070             * it...Try and restart the stopped jobs.
     3071             */
     3072            jobFull = FALSE;
     3073            JobRestartJobs();
     3074            return(FALSE);
     3075        }
     3076#else
     3077        return(TRUE);
     3078#endif
    26213079    } else {
    2622         return(FALSE);
     3080        return(FALSE);
    26233081    }
    26243082}
     
    26283086 *-----------------------------------------------------------------------
    26293087 * JobMatchShell --
    2630  *      Find a matching shell in 'shells' given its final component.
     3088 *      Find a matching shell in 'shells' given its final component.
    26313089 *
    26323090 * Results:
    2633  *      A pointer to the Shell structure.
     3091 *      A pointer to the Shell structure.
    26343092 *
    26353093 * Side Effects:
    2636  *      None.
     3094 *      None.
    26373095 *
    26383096 *-----------------------------------------------------------------------
     
    26403098static Shell *
    26413099JobMatchShell(name)
    2642     char          *name;      /* Final component of shell path */
     3100    char          *name;      /* Final component of shell path */
    26433101{
    2644     register Shell *sh;       /* Pointer into shells table */
    2645     Shell          *match;    /* Longest-matching shell */
     3102    register Shell *sh;       /* Pointer into shells table */
     3103    Shell          *match;    /* Longest-matching shell */
    26463104    register char *cp1,
    2647                   *cp2;
    2648     char          *eoname;
     3105                  *cp2;
     3106    char          *eoname;
    26493107
    26503108    eoname = name + strlen(name);
     
    26533111
    26543112    for (sh = shells; sh->name != NULL; sh++) {
    2655         for (cp1 = eoname - strlen(sh->name), cp2 = sh->name;
    2656              *cp1 != '\0' && *cp1 == *cp2;
    2657              cp1++, cp2++) {
    2658                 continue;
    2659         }
    2660         if (*cp1 != *cp2) {
    2661             continue;
    2662         } else if (match == NULL || strlen(match->name) < strlen(sh->name)) {
    2663            match = sh;
    2664         }
     3113        for (cp1 = eoname - strlen(sh->name), cp2 = sh->name;
     3114             *cp1 != '\0' && *cp1 == *cp2;
     3115             cp1++, cp2++) {
     3116                continue;
     3117        }
     3118        if (*cp1 != *cp2) {
     3119            continue;
     3120        } else if (match == NULL || strlen(match->name) < strlen(sh->name)) {
     3121           match = sh;
     3122        }
    26653123    }
    26663124    return(match == NULL ? sh : match);
     
    26723130 *-----------------------------------------------------------------------
    26733131 * Job_ParseShell --
    2674  *      Parse a shell specification and set up commandShell, shellPath
    2675  *      and shellName appropriately.
     3132 *      Parse a shell specification and set up commandShell, shellPath
     3133 *      and shellName appropriately.
    26763134 *
    26773135 * Results:
    2678  *      FAILURE if the specification was incorrect.
     3136 *      FAILURE if the specification was incorrect.
    26793137 *
    26803138 * Side Effects:
    2681  *      commandShell points to a Shell structure (either predefined or
    2682  *      created from the shell spec), shellPath is the full path of the
    2683  *      shell described by commandShell, while shellName is just the
    2684  *      final component of shellPath.
     3139 *      commandShell points to a Shell structure (either predefined or
     3140 *      created from the shell spec), shellPath is the full path of the
     3141 *      shell described by commandShell, while shellName is just the
     3142 *      final component of shellPath.
    26853143 *
    26863144 * Notes:
    2687  *      A shell specification consists of a .SHELL target, with dependency
    2688  *      operator, followed by a series of blank-separated words. Double
    2689  *      quotes can be used to use blanks in words. A backslash escapes
    2690  *      anything (most notably a double-quote and a space) and
    2691  *      provides the functionality it does in C. Each word consists of
    2692  *      keyword and value separated by an equal sign. There should be no
    2693  *      unnecessary spaces in the word. The keywords are as follows:
    2694  *          name            Name of shell.
    2695  *          path            Location of shell. Overrides "name" if given
    2696  *          quiet           Command to turn off echoing.
    2697  *          echo            Command to turn echoing on
    2698  *          filter          Result of turning off echoing that shouldn't be
    2699  *                          printed.
    2700  *          echoFlag        Flag to turn echoing on at the start
    2701  *          errFlag         Flag to turn error checking on at the start
    2702  *          hasErrCtl       True if shell has error checking control
    2703  *          check           Command to turn on error checking if hasErrCtl
    2704  *                          is TRUE or template of command to echo a command
    2705  *                          for which error checking is off if hasErrCtl is
    2706  *                          FALSE.
    2707  *          ignore          Command to turn off error checking if hasErrCtl
    2708  *                          is TRUE or template of command to execute a
    2709  *                          command so as to ignore any errors it returns if
    2710  *                          hasErrCtl is FALSE.
     3145 *      A shell specification consists of a .SHELL target, with dependency
     3146 *      operator, followed by a series of blank-separated words. Double
     3147 *      quotes can be used to use blanks in words. A backslash escapes
     3148 *      anything (most notably a double-quote and a space) and
     3149 *      provides the functionality it does in C. Each word consists of
     3150 *      keyword and value separated by an equal sign. There should be no
     3151 *      unnecessary spaces in the word. The keywords are as follows:
     3152 *          name            Name of shell.
     3153 *          path            Location of shell. Overrides "name" if given
     3154 *          quiet           Command to turn off echoing.
     3155 *          echo            Command to turn echoing on
     3156 *          filter          Result of turning off echoing that shouldn't be
     3157 *                          printed.
     3158 *          echoFlag        Flag to turn echoing on at the start
     3159 *          errFlag         Flag to turn error checking on at the start
     3160 *          hasErrCtl       True if shell has error checking control
     3161 *          check           Command to turn on error checking if hasErrCtl
     3162 *                          is TRUE or template of command to echo a command
     3163 *                          for which error checking is off if hasErrCtl is
     3164 *                          FALSE.
     3165 *          ignore          Command to turn off error checking if hasErrCtl
     3166 *                          is TRUE or template of command to execute a
     3167 *                          command so as to ignore any errors it returns if
     3168 *                          hasErrCtl is FALSE.
    27113169 *
    27123170 *-----------------------------------------------------------------------
     
    27143172ReturnStatus
    27153173Job_ParseShell(line)
    2716     char          *line;  /* The shell spec */
     3174    char          *line;  /* The shell spec */
    27173175{
    2718     char          **words;
    2719     int           wordCount;
     3176    char          **words;
     3177    int           wordCount;
    27203178    register char **argv;
    27213179    register int  argc;
    2722     char          *path;
    2723     Shell         newShell;
    2724     Boolean       fullSpec = FALSE;
     3180    char          *path;
     3181    Shell         newShell;
     3182    Boolean       fullSpec = FALSE;
    27253183
    27263184    while (isspace(*line)) {
    2727         line++;
     3185        line++;
    27283186    }
    27293187    words = brk_string(line, &wordCount, TRUE);
     
    27353193     */
    27363194    for (path = NULL, argc = wordCount - 1, argv = words + 1;
    2737         argc != 0;
    2738         argc--, argv++) {
    2739              if (strncmp(*argv, "path=", 5) == 0) {
    2740                 path = &argv[0][5];
    2741              } else if (strncmp(*argv, "name=", 5) == 0) {
    2742                 newShell.name = &argv[0][5];
    2743              } else {
    2744                 if (strncmp(*argv, "quiet=", 6) == 0) {
    2745                      newShell.echoOff = &argv[0][6];
    2746                 } else if (strncmp(*argv, "echo=", 5) == 0) {
    2747                      newShell.echoOn = &argv[0][5];
    2748                 } else if (strncmp(*argv, "filter=", 7) == 0) {
    2749                      newShell.noPrint = &argv[0][7];
    2750                      newShell.noPLen = strlen(newShell.noPrint);
    2751                 } else if (strncmp(*argv, "echoFlag=", 9) == 0) {
    2752                      newShell.echo = &argv[0][9];
    2753                 } else if (strncmp(*argv, "errFlag=", 8) == 0) {
    2754                      newShell.exit = &argv[0][8];
    2755                 } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) {
    2756                      char c = argv[0][10];
    2757                      newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
    2758                                            (c != 'T') && (c != 't'));
    2759                 } else if (strncmp(*argv, "check=", 6) == 0) {
    2760                      newShell.errCheck = &argv[0][6];
    2761                 } else if (strncmp(*argv, "ignore=", 7) == 0) {
    2762                      newShell.ignErr = &argv[0][7];
    2763                 } else {
    2764                      Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
    2765                                   *argv);
    2766                      return(FAILURE);
    2767                 }
    2768                 fullSpec = TRUE;
    2769              }
     3195        argc != 0;
     3196        argc--, argv++) {
     3197             if (strncmp(*argv, "path=", 5) == 0) {
     3198                path = &argv[0][5];
     3199             } else if (strncmp(*argv, "name=", 5) == 0) {
     3200                newShell.name = &argv[0][5];
     3201             } else {
     3202                if (strncmp(*argv, "quiet=", 6) == 0) {
     3203                     newShell.echoOff = &argv[0][6];
     3204                } else if (strncmp(*argv, "echo=", 5) == 0) {
     3205                     newShell.echoOn = &argv[0][5];
     3206                } else if (strncmp(*argv, "filter=", 7) == 0) {
     3207                     newShell.noPrint = &argv[0][7];
     3208                     newShell.noPLen = strlen(newShell.noPrint);
     3209                } else if (strncmp(*argv, "echoFlag=", 9) == 0) {
     3210                     newShell.echo = &argv[0][9];
     3211                } else if (strncmp(*argv, "errFlag=", 8) == 0) {
     3212                     newShell.exit = &argv[0][8];
     3213                } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) {
     3214                     char c = argv[0][10];
     3215                     newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
     3216                                           (c != 'T') && (c != 't'));
     3217                } else if (strncmp(*argv, "check=", 6) == 0) {
     3218                     newShell.errCheck = &argv[0][6];
     3219                } else if (strncmp(*argv, "ignore=", 7) == 0) {
     3220                     newShell.ignErr = &argv[0][7];
     3221                } else {
     3222                     Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
     3223                                  *argv);
     3224                     return(FAILURE);
     3225                }
     3226                fullSpec = TRUE;
     3227             }
    27703228    }
    27713229
    27723230    if (path == NULL) {
    2773         /*
    2774         * If no path was given, the user wants one of the pre-defined shells,
    2775         * yes? So we find the one s/he wants with the help of JobMatchShell
    2776         * and set things up the right way. shellPath will be set up by
    2777         * Job_Init.
    2778         */
    2779         if (newShell.name == NULL) {
    2780             Parse_Error(PARSE_FATAL, "Neither path nor name specified");
    2781             return(FAILURE);
    2782         } else {
    2783             commandShell = JobMatchShell(newShell.name);
    2784             shellName = newShell.name;
    2785         }
     3231        /*
     3232        * If no path was given, the user wants one of the pre-defined shells,
     3233        * yes? So we find the one s/he wants with the help of JobMatchShell
     3234        * and set things up the right way. shellPath will be set up by
     3235        * Job_Init.
     3236        */
     3237        if (newShell.name == NULL) {
     3238            Parse_Error(PARSE_FATAL, "Neither path nor name specified");
     3239            return(FAILURE);
     3240        } else {
     3241            commandShell = JobMatchShell(newShell.name);
     3242            shellName = newShell.name;
     3243        }
    27863244    } else {
    2787         /*
    2788         * The user provided a path. If s/he gave nothing else (fullSpec is
    2789         * FALSE), try and find a matching shell in the ones we know of.
    2790         * Else we just take the specification at its word and copy it
    2791         * to a new location. In either case, we need to record the
    2792         * path the user gave for the shell.
    2793         */
    2794         shellPath = path;
    2795         path = strrchr(path, '/');
    2796         if (path == NULL) {
    2797             path = shellPath;
    2798         } else {
    2799             path += 1;
    2800         }
    2801         if (newShell.name != NULL) {
    2802             shellName = newShell.name;
    2803         } else {
    2804             shellName = path;
    2805         }
    2806         if (!fullSpec) {
    2807             commandShell = JobMatchShell(shellName);
    2808         } else {
    2809             commandShell = (Shell *) emalloc(sizeof(Shell));
    2810             *commandShell = newShell;
    2811         }
     3245        /*
     3246        * The user provided a path. If s/he gave nothing else (fullSpec is
     3247        * FALSE), try and find a matching shell in the ones we know of.
     3248        * Else we just take the specification at its word and copy it
     3249        * to a new location. In either case, we need to record the
     3250        * path the user gave for the shell.
     3251        */
     3252        shellPath = path;
     3253        path = strrchr(path, '/');
     3254        if (path == NULL) {
     3255            path = shellPath;
     3256        } else {
     3257            path += 1;
     3258        }
     3259        if (newShell.name != NULL) {
     3260            shellName = newShell.name;
     3261        } else {
     3262            shellName = path;
     3263        }
     3264        if (!fullSpec) {
     3265            commandShell = JobMatchShell(shellName);
     3266        } else {
     3267            commandShell = (Shell *) emalloc(sizeof(Shell));
     3268            *commandShell = newShell;
     3269        }
    28123270    }
    28133271
    28143272    if (commandShell->echoOn && commandShell->echoOff) {
    2815         commandShell->hasEchoCtl = TRUE;
     3273        commandShell->hasEchoCtl = TRUE;
    28163274    }
    28173275
    28183276    if (!commandShell->hasErrCtl) {
    2819         if (commandShell->errCheck == NULL) {
    2820             commandShell->errCheck = "";
    2821         }
    2822         if (commandShell->ignErr == NULL) {
    2823             commandShell->ignErr = "%s\n";
    2824         }
     3277        if (commandShell->errCheck == NULL) {
     3278            commandShell->errCheck = "";
     3279        }
     3280        if (commandShell->ignErr == NULL) {
     3281            commandShell->ignErr = "%s\n";
     3282        }
    28253283    }
    28263284
     
    28373295 *-----------------------------------------------------------------------
    28383296 * JobInterrupt --
    2839  *      Handle the receipt of an interrupt.
     3297 *      Handle the receipt of an interrupt.
    28403298 *
    28413299 * Results:
    2842  *      None
     3300 *      None
    28433301 *
    28443302 * Side Effects:
    2845  *      All children are killed. Another job will be started if the
    2846  *      .INTERRUPT target was given.
     3303 *      All children are killed. Another job will be started if the
     3304 *      .INTERRUPT target was given.
    28473305 *-----------------------------------------------------------------------
    28483306 */
    28493307static void
    28503308JobInterrupt(runINTERRUPT, signo)
    2851     int     runINTERRUPT;       /* Non-zero if commands for the .INTERRUPT
    2852                                 * target should be executed */
    2853     int     signo;              /* signal received */
     3309    int     runINTERRUPT;       /* Non-zero if commands for the .INTERRUPT
     3310                                * target should be executed */
     3311    int     signo;              /* signal received */
    28543312{
    2855     LstNode       ln;           /* element in job table */
    2856     Job           *job = NULL;  /* job descriptor in that element */
    2857     GNode         *interrupt;   /* the node describing the .INTERRUPT target */
     3313    LstNode       ln;           /* element in job table */
     3314    Job           *job = NULL;  /* job descriptor in that element */
     3315    GNode         *interrupt;   /* the node describing the .INTERRUPT target */
    28583316
    28593317    aborting = ABORT_INTERRUPT;
     
    28613319   (void) Lst_Open(jobs);
    28623320    while ((ln = Lst_Next(jobs)) != NILLNODE) {
    2863         job = (Job *) Lst_Datum(ln);
    2864 
    2865         if (!Targ_Precious(job->node)) {
    2866             char        *file = (job->node->path == NULL ?
    2867                                 job->node->name :
    2868                                 job->node->path);
    2869             if (!noExecute && eunlink(file) != -1) {
    2870                 Error("*** %s removed", file);
    2871             }
    2872         }
     3321        job = (Job *) Lst_Datum(ln);
     3322
     3323        if (!Targ_Precious(job->node)) {
     3324            char        *file = (job->node->path == NULL ?
     3325                                job->node->name :
     3326                                job->node->path);
     3327            if (!noExecute && eunlink(file) != -1) {
     3328                Error("*** %s removed", file);
     3329            }
     3330        }
    28733331#ifdef RMT_WANTS_SIGNALS
    2874         if (job->flags & JOB_REMOTE) {
    2875             /*
    2876              * If job is remote, let the Rmt module do the killing.
    2877              */
    2878             if (!Rmt_Signal(job, signo)) {
    2879                 /*
    2880                 * If couldn't kill the thing, finish it out now with an
    2881                 * error code, since no exit report will come in likely.
    2882                 */
    2883                 int status;
    2884 
    2885                 status.w_status = 0;
    2886                 status.w_retcode = 1;
    2887                 JobFinish(job, &status);
    2888             }
    2889         } else if (job->pid) {
    2890             KILL(job->pid, signo);
    2891         }
     3332        if (job->flags & JOB_REMOTE) {
     3333            /*
     3334             * If job is remote, let the Rmt module do the killing.
     3335             */
     3336            if (!Rmt_Signal(job, signo)) {
     3337                /*
     3338                * If couldn't kill the thing, finish it out now with an
     3339                * error code, since no exit report will come in likely.
     3340                */
     3341                int status;
     3342
     3343                status.w_status = 0;
     3344                status.w_retcode = 1;
     3345                JobFinish(job, &status);
     3346            }
     3347        } else if (job->pid) {
     3348            KILL(job->pid, signo);
     3349        }
    28923350#else
    2893         if (job->pid) {
    2894             if (DEBUG(JOB)) {
    2895                 (void) fprintf(stdout,
    2896                                "JobInterrupt passing signal to child %d.\n",
    2897                                job->pid);
    2898                 (void) fflush(stdout);
    2899             }
    2900             KILL(job->pid, signo);
    2901         }
     3351        if (job->pid) {
     3352            if (DEBUG(JOB)) {
     3353                (void) fprintf(stdout,
     3354                               "JobInterrupt passing signal to child %d.\n",
     3355                               job->pid);
     3356                (void) fflush(stdout);
     3357            }
     3358            KILL(job->pid, signo);
     3359        }
    29023360#endif /* RMT_WANTS_SIGNALS */
    29033361    }
     
    29063364   (void)Lst_Open(stoppedJobs);
    29073365    while ((ln = Lst_Next(stoppedJobs)) != NILLNODE) {
    2908         job = (Job *) Lst_Datum(ln);
    2909 
    2910         if (job->flags & JOB_RESTART) {
    2911             if (DEBUG(JOB)) {
    2912                 (void) fprintf(stdout, "%s%s",
    2913                                "JobInterrupt skipping job on stopped queue",
    2914                                "-- it was waiting to be restarted.\n");
    2915                 (void) fflush(stdout);
    2916             }
    2917             continue;
    2918         }
    2919         if (!Targ_Precious(job->node)) {
    2920             char        *file = (job->node->path == NULL ?
    2921                                 job->node->name :
    2922                                 job->node->path);
    2923             if (eunlink(file) == 0) {
    2924                 Error("*** %s removed", file);
    2925             }
    2926         }
    2927         /*
    2928         * Resume the thing so it will take the signal.
    2929         */
    2930         if (DEBUG(JOB)) {
    2931             (void) fprintf(stdout,
    2932                            "JobInterrupt passing CONT to stopped child %d.\n",
    2933                            job->pid);
    2934             (void) fflush(stdout);
    2935         }
    2936         KILL(job->pid, SIGCONT);
     3366        job = (Job *) Lst_Datum(ln);
     3367
     3368        if (job->flags & JOB_RESTART) {
     3369            if (DEBUG(JOB)) {
     3370                (void) fprintf(stdout, "%s%s",
     3371                               "JobInterrupt skipping job on stopped queue",
     3372                               "-- it was waiting to be restarted.\n");
     3373                (void) fflush(stdout);
     3374            }
     3375            continue;
     3376        }
     3377        if (!Targ_Precious(job->node)) {
     3378            char        *file = (job->node->path == NULL ?
     3379                                job->node->name :
     3380                                job->node->path);
     3381            if (eunlink(file) == 0) {
     3382                Error("*** %s removed", file);
     3383            }
     3384        }
     3385        /*
     3386        * Resume the thing so it will take the signal.
     3387        */
     3388        if (DEBUG(JOB)) {
     3389            (void) fprintf(stdout,
     3390                           "JobInterrupt passing CONT to stopped child %d.\n",
     3391                           job->pid);
     3392            (void) fflush(stdout);
     3393        }
     3394        KILL(job->pid, SIGCONT);
    29373395#ifdef RMT_WANTS_SIGNALS
    2938         if (job->flags & JOB_REMOTE) {
    2939             /*
    2940              * If job is remote, let the Rmt module do the killing.
    2941              */
    2942             if (!Rmt_Signal(job, SIGINT)) {
    2943                 /*
    2944                 * If couldn't kill the thing, finish it out now with an
    2945                 * error code, since no exit report will come in likely.
    2946                 */
    2947                 int status;
    2948                 status.w_status = 0;
    2949                 status.w_retcode = 1;
    2950                 JobFinish(job, &status);
    2951             }
    2952         } else if (job->pid) {
    2953             if (DEBUG(JOB)) {
    2954                 (void) fprintf(stdout,
    2955                        "JobInterrupt passing interrupt to stopped child %d.\n",
    2956                                job->pid);
    2957                 (void) fflush(stdout);
    2958             }
    2959             KILL(job->pid, SIGINT);
    2960         }
     3396        if (job->flags & JOB_REMOTE) {
     3397            /*
     3398             * If job is remote, let the Rmt module do the killing.
     3399             */
     3400            if (!Rmt_Signal(job, SIGINT)) {
     3401                /*
     3402                * If couldn't kill the thing, finish it out now with an
     3403                * error code, since no exit report will come in likely.
     3404                */
     3405                int status;
     3406                status.w_status = 0;
     3407                status.w_retcode = 1;
     3408                JobFinish(job, &status);
     3409            }
     3410        } else if (job->pid) {
     3411            if (DEBUG(JOB)) {
     3412                (void) fprintf(stdout,
     3413                       "JobInterrupt passing interrupt to stopped child %d.\n",
     3414                               job->pid);
     3415                (void) fflush(stdout);
     3416            }
     3417            KILL(job->pid, SIGINT);
     3418        }
    29613419#endif /* RMT_WANTS_SIGNALS */
    29623420    }
    2963 #endif
    29643421    Lst_Close(stoppedJobs);
     3422#endif
    29653423
    29663424    if (runINTERRUPT && !touchFlag) {
    2967         interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
    2968         if (interrupt != NILGNODE) {
    2969             ignoreErrors = FALSE;
    2970 
    2971             JobStart(interrupt, JOB_IGNDOTS, (Job *)0);
    2972             while (nJobs) {
    2973                 Job_CatchOutput();
     3425        interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
     3426        if (interrupt != NILGNODE) {
     3427            ignoreErrors = FALSE;
     3428
     3429            JobStart(interrupt, JOB_IGNDOTS, (Job *)0);
     3430            while (nJobs) {
     3431                Job_CatchOutput();
    29743432#ifndef RMT_WILL_WATCH
    2975                 Job_CatchChildren(!usePipes);
     3433                Job_CatchChildren(!usePipes);
    29763434#endif /* RMT_WILL_WATCH */
    2977             }
    2978         }
     3435            }
     3436        }
    29793437    }
    29803438}
     
    29833441 *-----------------------------------------------------------------------
    29843442 * Job_End --
    2985  *      Do final processing such as the running of the commands
    2986  *      attached to the .END target.
     3443 *      Do final processing such as the running of the commands
     3444 *      attached to the .END target.
    29873445 *
    29883446 * Results:
    2989  *      Number of errors reported.
     3447 *      Number of errors reported.
    29903448 *-----------------------------------------------------------------------
    29913449 */
     
    29943452{
    29953453    if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) {
    2996         if (errors) {
    2997             Error("Errors reported so .END ignored");
    2998         } else {
    2999             JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL);
    3000 
    3001             while (nJobs) {
    3002                 Job_CatchOutput();
     3454        if (errors) {
     3455            Error("Errors reported so .END ignored");
     3456        } else {
     3457            JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL);
     3458
     3459            while (nJobs) {
     3460                Job_CatchOutput();
    30033461#ifndef RMT_WILL_WATCH
    3004                 Job_CatchChildren(!usePipes);
     3462                Job_CatchChildren(!usePipes);
    30053463#endif /* RMT_WILL_WATCH */
    3006             }
    3007         }
     3464            }
     3465        }
    30083466    }
    30093467    return(errors);
     
    30133471 *-----------------------------------------------------------------------
    30143472 * Job_Wait --
    3015  *      Waits for all running jobs to finish and returns. Sets 'aborting'
    3016  *      to ABORT_WAIT to prevent other jobs from starting.
     3473 *      Waits for all running jobs to finish and returns. Sets 'aborting'
     3474 *      to ABORT_WAIT to prevent other jobs from starting.
    30173475 *
    30183476 * Results:
    3019  *      None.
     3477 *      None.
    30203478 *
    30213479 * Side Effects:
    3022  *      Currently running jobs finish.
     3480 *      Currently running jobs finish.
    30233481 *
    30243482 *-----------------------------------------------------------------------
     
    30293487    aborting = ABORT_WAIT;
    30303488    while (nJobs != 0) {
    3031         Job_CatchOutput();
     3489        Job_CatchOutput();
    30323490#ifndef RMT_WILL_WATCH
    3033         Job_CatchChildren(!usePipes);
     3491        Job_CatchChildren(!usePipes);
    30343492#endif /* RMT_WILL_WATCH */
    30353493    }
     
    30403498 *-----------------------------------------------------------------------
    30413499 * Job_AbortAll --
    3042  *      Abort all currently running jobs without handling output or anything.
    3043  *      This function is to be called only in the event of a major
    3044  *      error. Most definitely NOT to be called from JobInterrupt.
     3500 *      Abort all currently running jobs without handling output or anything.
     3501 *      This function is to be called only in the event of a major
     3502 *      error. Most definitely NOT to be called from JobInterrupt.
    30453503 *
    30463504 * Results:
    3047  *      None
     3505 *      None
    30483506 *
    30493507 * Side Effects:
    3050  *      All children are killed, not just the firstborn
     3508 *      All children are killed, not just the firstborn
    30513509 *-----------------------------------------------------------------------
    30523510 */
     
    30543512Job_AbortAll()
    30553513{
    3056     LstNode             ln;     /* element in job table */
    3057     Job                 *job;   /* the job descriptor in that element */
    3058     int                 foo;
     3514#ifdef USE_KLIB
     3515    LstNode             ln;     /* element in job table */
     3516    Job                *job;    /* the job descriptor in that element */
     3517    KPROCRES            res;
    30593518
    30603519    aborting = ABORT_ERROR;
    30613520
     3521    if (nJobs)
     3522    {
     3523        Lst_Open(jobs);
     3524        while ((ln = Lst_Next(jobs)) != NILLNODE)
     3525        {
     3526            job = (Job *) Lst_Datum(ln);
     3527
     3528            /*
     3529             * kill the child process with increasingly drastic signals to make
     3530             * darn sure it's dead.
     3531             */
     3532            kProcKill(job->pid, KPROCKILL_FLAGS_TREE | KPROCKILL_FLAGS_TYPE_INT);
     3533            kProcKill(job->pid, KPROCKILL_FLAGS_TREE | KPROCKILL_FLAGS_TYPE_KILL);
     3534        }
     3535    }
     3536
     3537    /*
     3538     * Catch as many children as want to report in at first, then give up
     3539     */
     3540    do
     3541    {
     3542        kThrdYield();
     3543    } while (!kProcWait(KPID_NULL, KPROCWAIT_FLAGS_NOWAIT, &res, NULL)); /** @todo checkout this call */
     3544
     3545#else /* Don't use kLib */
     3546    LstNode             ln;     /* element in job table */
     3547    Job                 *job;   /* the job descriptor in that element */
     3548    int                 foo;
     3549
     3550    aborting = ABORT_ERROR;
     3551
    30623552    if (nJobs) {
    30633553
    3064         (void) Lst_Open(jobs);
    3065         while ((ln = Lst_Next(jobs)) != NILLNODE) {
    3066             job = (Job *) Lst_Datum(ln);
    3067 
    3068             /*
    3069              * kill the child process with increasingly drastic signals to make
    3070              * darn sure it's dead.
    3071              */
     3554        (void) Lst_Open(jobs);
     3555        while ((ln = Lst_Next(jobs)) != NILLNODE) {
     3556            job = (Job *) Lst_Datum(ln);
     3557
     3558            /*
     3559             * kill the child process with increasingly drastic signals to make
     3560             * darn sure it's dead.
     3561             */
    30723562#ifdef RMT_WANTS_SIGNALS
    3073             if (job->flags & JOB_REMOTE) {
    3074                 Rmt_Signal(job, SIGINT);
    3075                 Rmt_Signal(job, SIGKILL);
    3076             } else {
    3077                 KILL(job->pid, SIGINT);
    3078                 KILL(job->pid, SIGKILL);
    3079             }
     3563            if (job->flags & JOB_REMOTE) {
     3564                Rmt_Signal(job, SIGINT);
     3565                Rmt_Signal(job, SIGKILL);
     3566            } else {
     3567                KILL(job->pid, SIGINT);
     3568                KILL(job->pid, SIGKILL);
     3569            }
    30803570#else
    3081             KILL(job->pid, SIGINT);
    3082             KILL(job->pid, SIGKILL);
     3571            KILL(job->pid, SIGINT);
     3572            KILL(job->pid, SIGKILL);
    30833573#endif /* RMT_WANTS_SIGNALS */
    3084         }
     3574        }
    30853575    }
    30863576
     
    30893579     */
    30903580    while (waitpid((pid_t) -1, &foo, WNOHANG) > 0)
    3091         continue;
     3581        continue;
     3582#endif /* USE_KLIB */
    30923583}
    30933584
     
    30963587 *-----------------------------------------------------------------------
    30973588 * JobFlagForMigration --
    3098  *      Handle the eviction of a child. Called from RmtStatusChange.
    3099  *      Flags the child as remigratable and then suspends it.
     3589 *      Handle the eviction of a child. Called from RmtStatusChange.
     3590 *      Flags the child as remigratable and then suspends it.
    31003591 *
    31013592 * Results:
    3102  *      none.
     3593 *      none.
    31033594 *
    31043595 * Side Effects:
    3105  *      The job descriptor is flagged for remigration.
     3596 *      The job descriptor is flagged for remigration.
    31063597 *
    31073598 *-----------------------------------------------------------------------
     
    31093600void
    31103601JobFlagForMigration(hostID)
    3111     int           hostID;       /* ID of host we used, for matching children. */
     3602    int           hostID;       /* ID of host we used, for matching children. */
    31123603{
    3113     register Job  *job;         /* job descriptor for dead child */
    3114     LstNode       jnode;        /* list element for finding job */
     3604    register Job  *job;         /* job descriptor for dead child */
     3605    LstNode       jnode;        /* list element for finding job */
    31153606
    31163607    if (DEBUG(JOB)) {
    3117         (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID);
    3118         (void) fflush(stdout);
     3608        (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID);
     3609        (void) fflush(stdout);
    31193610    }
    31203611    jnode = Lst_Find(jobs, (ClientData)hostID, JobCmpRmtID);
    31213612
    31223613    if (jnode == NILLNODE) {
    3123         jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID);
    3124                 if (jnode == NILLNODE) {
    3125                     if (DEBUG(JOB)) {
    3126                         Error("Evicting host(%d) not in table", hostID);
    3127                     }
    3128                     return;
    3129                 }
     3614        jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID);
     3615                if (jnode == NILLNODE) {
     3616                    if (DEBUG(JOB)) {
     3617                        Error("Evicting host(%d) not in table", hostID);
     3618                    }
     3619                    return;
     3620                }
    31303621    }
    31313622    job = (Job *) Lst_Datum(jnode);
    31323623
    31333624    if (DEBUG(JOB)) {
    3134         (void) fprintf(stdout,
    3135                        "JobFlagForMigration(%d) found job '%s'.\n", hostID,
    3136                        job->node->name);
    3137         (void) fflush(stdout);
     3625        (void) fprintf(stdout,
     3626                       "JobFlagForMigration(%d) found job '%s'.\n", hostID,
     3627                       job->node->name);
     3628        (void) fflush(stdout);
    31383629    }
    31393630
     
    31463637
    31473638
     3639#ifdef SIGCONT
    31483640/*-
    31493641 *-----------------------------------------------------------------------
    31503642 * JobRestartJobs --
    3151  *      Tries to restart stopped jobs if there are slots available.
    3152  *      Note that this tries to restart them regardless of pending errors.
    3153  *      It's not good to leave stopped jobs lying around!
     3643 *      Tries to restart stopped jobs if there are slots available.
     3644 *      Note that this tries to restart them regardless of pending errors.
     3645 *      It's not good to leave stopped jobs lying around!
    31543646 *
    31553647 * Results:
    3156  *      None.
     3648 *      None.
    31573649 *
    31583650 * Side Effects:
    3159  *      Resumes(and possibly migrates) jobs.
     3651 *      Resumes(and possibly migrates) jobs.
    31603652 *
    31613653 *-----------------------------------------------------------------------
     
    31653657{
    31663658    while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
    3167         if (DEBUG(JOB)) {
    3168             (void) fprintf(stdout,
    3169                        "Job queue is not full. Restarting a stopped job.\n");
    3170             (void) fflush(stdout);
    3171         }
    3172         JobRestart((Job *)Lst_DeQueue(stoppedJobs));
     3659        if (DEBUG(JOB)) {
     3660            (void) fprintf(stdout,
     3661                       "Job queue is not full. Restarting a stopped job.\n");
     3662            (void) fflush(stdout);
     3663        }
     3664        JobRestart((Job *)Lst_DeQueue(stoppedJobs));
    31733665    }
    31743666}
     3667#endif
Note: See TracChangeset for help on using the changeset viewer.