BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.bin / make / job.c
index 269412f..166fd97 100644 (file)
@@ -1,17 +1,43 @@
 /*
 /*
- * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
- * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1988, 1989, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  * Copyright (c) 1989 by Berkeley Softworks
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Adam de Boor.
  *
  * Copyright (c) 1989 by Berkeley Softworks
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Adam de Boor.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)job.c      5.19 (Berkeley) %G%";
+static char sccsid[] = "@(#)job.c      8.3 (Berkeley) 4/28/95";
 #endif /* not lint */
 
 /*-
 #endif /* not lint */
 
 /*-
@@ -71,17 +97,16 @@ static char sccsid[] = "@(#)job.c   5.19 (Berkeley) %G%";
  */
 
 #include <sys/types.h>
  */
 
 #include <sys/types.h>
+#include <sys/signal.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <sys/wait.h>
-
-#include <errno.h>
 #include <fcntl.h>
 #include <fcntl.h>
-#include <signal.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdio.h>
 #include <string.h>
-
+#include <signal.h>
 #include "make.h"
 #include "hash.h"
 #include "dir.h"
 #include "make.h"
 #include "hash.h"
 #include "dir.h"
@@ -176,10 +201,10 @@ static char       *shellPath = (char *) NULL,       /* full pathname of
 
 static int     maxJobs;        /* The most children we can run at once */
 static int     maxLocal;       /* The most local ones we can have */
 
 static int     maxJobs;        /* The most children we can run at once */
 static int     maxLocal;       /* The most local ones we can have */
-static int             nJobs;          /* The number of children currently running */
-static int     nLocal;         /* The number of local children */
-static Lst             jobs;           /* The structures that describe them */
-static Boolean jobFull;        /* Flag to tell when the job table is full. It
+int            nJobs;          /* The number of children currently running */
+int            nLocal;         /* The number of local children */
+Lst            jobs;           /* The structures that describe them */
+Boolean                jobFull;        /* Flag to tell when the job table is full. It
                                 * is set TRUE when (1) the total number of
                                 * running jobs equals the maximum allowed or
                                 * (2) a job can only be run locally, but
                                 * is set TRUE when (1) the total number of
                                 * running jobs equals the maximum allowed or
                                 * (2) a job can only be run locally, but
@@ -189,9 +214,9 @@ static fd_set       outputs;        /* Set of descriptors of pipes connected to
                                 * the output channels of children */
 #endif
 
                                 * the output channels of children */
 #endif
 
-static GNode           *lastNode;      /* The node for which output was most recently
+GNode          *lastNode;      /* The node for which output was most recently
                                 * produced. */
                                 * produced. */
-static char            *targFmt;       /* Format string to use to head output from a
+char           *targFmt;       /* Format string to use to head output from a
                                 * job when it's not the most-recent job heard
                                 * from */
 #define TARG_FMT  "--- %s ---\n" /* Default format */
                                 * job when it's not the most-recent job heard
                                 * from */
 #define TARG_FMT  "--- %s ---\n" /* Default format */
@@ -202,7 +227,7 @@ static char         *targFmt;       /* Format string to use to head output from a
  * been migrated home, the job is placed on the stoppedJobs queue to be run
  * when the next job finishes. 
  */
  * been migrated home, the job is placed on the stoppedJobs queue to be run
  * when the next job finishes. 
  */
-static Lst    stoppedJobs;     /* Lst of Job structures describing
+Lst            stoppedJobs;    /* Lst of Job structures describing
                                 * jobs that were stopped due to concurrency
                                 * limits or migration home */
 
                                 * jobs that were stopped due to concurrency
                                 * limits or migration home */
 
@@ -217,11 +242,11 @@ static Lst    stoppedJobs;        /* Lst of Job structures describing
 # endif
 #endif
 
 # endif
 #endif
 
-static int JobCondPassSig __P((Job *, int));
+static int JobCondPassSig __P((ClientData, ClientData));
 static void JobPassSig __P((int));
 static void JobPassSig __P((int));
-static int JobCmpPid __P((Job *, int));
-static int JobPrintCommand __P((char *, Job *));
-static int JobSaveCommand __P((char *, GNode *));
+static int JobCmpPid __P((ClientData, ClientData));
+static int JobPrintCommand __P((ClientData, ClientData));
+static int JobSaveCommand __P((ClientData, ClientData));
 static void JobFinish __P((Job *, union wait));
 static void JobExec __P((Job *, char **));
 static void JobMakeArgv __P((Job *, char **));
 static void JobFinish __P((Job *, union wait));
 static void JobExec __P((Job *, char **));
 static void JobMakeArgv __P((Job *, char **));
@@ -246,10 +271,12 @@ static void JobInterrupt __P((int));
  *-----------------------------------------------------------------------
  */
 static int
  *-----------------------------------------------------------------------
  */
 static int
-JobCondPassSig(job, signo)
-    Job                *job;       /* Job to biff */
-    int                signo;      /* Signal to send it */
+JobCondPassSig(jobp, signop)
+    ClientData         jobp;       /* Job to biff */
+    ClientData         signop;     /* Signal to send it */
 {
 {
+    Job        *job = (Job *) jobp;
+    int        signo = *(int *) signop;
 #ifdef RMT_WANTS_SIGNALS
     if (job->flags & JOB_REMOTE) {
        (void)Rmt_Signal(job, signo);
 #ifdef RMT_WANTS_SIGNALS
     if (job->flags & JOB_REMOTE) {
        (void)Rmt_Signal(job, signo);
@@ -286,7 +313,7 @@ JobPassSig(signo)
 {
     int            mask;
     
 {
     int            mask;
     
-    Lst_ForEach(jobs, JobCondPassSig, (ClientData)signo);
+    Lst_ForEach(jobs, JobCondPassSig, (ClientData)(long)signo);
 
     /*
      * Deal with proper cleanup based on the signal received. We only run
 
     /*
      * Deal with proper cleanup based on the signal received. We only run
@@ -318,7 +345,8 @@ JobPassSig(signo)
 
     kill(getpid(), signo);
 
 
     kill(getpid(), signo);
 
-    Lst_ForEach(jobs, JobCondPassSig, (ClientData)SIGCONT);
+    signo = SIGCONT;
+    Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
 
     sigsetmask(mask);
     signal(signo, JobPassSig);
 
     sigsetmask(mask);
     signal(signo, JobPassSig);
@@ -341,10 +369,10 @@ JobPassSig(signo)
  */
 static int
 JobCmpPid (job, pid)
  */
 static int
 JobCmpPid (job, pid)
-    int             pid;       /* process id desired */
-    Job            *job;       /* job to examine */
+    ClientData        job;     /* job to examine */
+    ClientData        pid;     /* process id desired */
 {
 {
-    return (pid - job->pid);
+    return ( *(int *) pid - ((Job *) job)->pid);
 }
 
 /*-
 }
 
 /*-
@@ -375,9 +403,9 @@ JobCmpPid (job, pid)
  *-----------------------------------------------------------------------
  */
 static int
  *-----------------------------------------------------------------------
  */
 static int
-JobPrintCommand (cmd, job)
-    char         *cmd;             /* command string to print */
-    Job           *job;                    /* job for which to print it */
+JobPrintCommand (cmdp, jobp)
+    ClientData    cmdp;                    /* command string to print */
+    ClientData    jobp;                    /* job for which to print it */
 {
     Boolean      noSpecials;       /* true if we shouldn't worry about
                                     * inserting special commands into
 {
     Boolean      noSpecials;       /* true if we shouldn't worry about
                                     * inserting special commands into
@@ -391,6 +419,8 @@ JobPrintCommand (cmd, job)
                                     * command */
     char         *cmdStart;        /* Start of expanded command */
     LstNode      cmdNode;          /* Node for replacing the command */
                                     * command */
     char         *cmdStart;        /* Start of expanded command */
     LstNode      cmdNode;          /* Node for replacing the command */
+    char         *cmd = (char *) cmdp;
+    Job           *job = (Job *) jobp; 
 
     noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
 
 
     noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
 
@@ -430,6 +460,9 @@ JobPrintCommand (cmd, job)
        cmd++;
     }
 
        cmd++;
     }
 
+    while (isspace((unsigned char) *cmd))
+       cmd++;
+
     if (shutUp) {
        if (! (job->flags & JOB_SILENT) && !noSpecials &&
            commandShell->hasEchoCtl) {
     if (shutUp) {
        if (! (job->flags & JOB_SILENT) && !noSpecials &&
            commandShell->hasEchoCtl) {
@@ -527,11 +560,11 @@ JobPrintCommand (cmd, job)
  */
 static int
 JobSaveCommand (cmd, gn)
  */
 static int
 JobSaveCommand (cmd, gn)
-    char    *cmd;
-    GNode   *gn;
+    ClientData   cmd;
+    ClientData   gn;
 {
 {
-    cmd = Var_Subst (NULL, cmd, gn, FALSE);
-    (void)Lst_AtEnd (postCommands->commands, (ClientData)cmd);
+    cmd = (ClientData) Var_Subst (NULL, (char *) cmd, (GNode *) gn, FALSE);
+    (void)Lst_AtEnd (postCommands->commands, cmd);
     return (0);
 }
 
     return (0);
 }
 
@@ -875,7 +908,7 @@ Boolean
 Job_CheckCommands (gn, abortProc)
     GNode          *gn;                    /* The target whose commands need
                                     * verifying */
 Job_CheckCommands (gn, abortProc)
     GNode          *gn;                    /* The target whose commands need
                                     * verifying */
-    void         (*abortProc) __P((const char *, ...));   
+    void         (*abortProc) __P((char *, ...));   
                        /* Function to abort with message */
 {
     if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
                        /* Function to abort with message */
 {
     if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
@@ -885,6 +918,7 @@ Job_CheckCommands (gn, abortProc)
         * commands 
         */
        if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) {
         * commands 
         */
        if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) {
+           char *p1;
            /*
             * Make only looks for a .DEFAULT if the node was never the
             * target of an operator, so that's what we do too. If
            /*
             * Make only looks for a .DEFAULT if the node was never the
             * target of an operator, so that's what we do too. If
@@ -895,7 +929,9 @@ Job_CheckCommands (gn, abortProc)
             * .DEFAULT itself.
             */
            Make_HandleUse(DEFAULT, gn);
             * .DEFAULT itself.
             */
            Make_HandleUse(DEFAULT, gn);
-           Var_Set (IMPSRC, Var_Value (TARGET, gn), gn);
+           Var_Set (IMPSRC, Var_Value (TARGET, gn, &p1), gn);
+           if (p1)
+               free(p1);
        } else if (Dir_MTime (gn) == 0) {
            /*
             * The node wasn't the target of an operator we have no .DEFAULT
        } else if (Dir_MTime (gn) == 0) {
            /*
             * The node wasn't the target of an operator we have no .DEFAULT
@@ -1332,7 +1368,7 @@ JobRestart(job)
 static int
 JobStart (gn, flags, previous)
     GNode         *gn;       /* target to create */
 static int
 JobStart (gn, flags, previous)
     GNode         *gn;       /* target to create */
-    short        flags;      /* flags for the job to override normal ones.
+    int                   flags;      /* flags for the job to override normal ones.
                               * e.g. JOB_SPECIAL or JOB_IGNDOTS */
     Job          *previous;  /* The previous Job structure for this node,
                               * if any. */
                               * e.g. JOB_SPECIAL or JOB_IGNDOTS */
     Job          *previous;  /* The previous Job structure for this node,
                               * if any. */
@@ -1920,11 +1956,11 @@ Job_CatchChildren (block)
            printf("Process %d exited or stopped.\n", pid);
            
 
            printf("Process %d exited or stopped.\n", pid);
            
 
-       jnode = Lst_Find (jobs, (ClientData)pid, JobCmpPid);
+       jnode = Lst_Find (jobs, (ClientData)&pid, JobCmpPid);
 
        if (jnode == NILLNODE) {
            if (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) {
 
        if (jnode == NILLNODE) {
            if (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) {
-               jnode = Lst_Find(stoppedJobs, (ClientData)pid, JobCmpPid);
+               jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid);
                if (jnode == NILLNODE) {
                    Error("Resumed child (%d) not in table", pid);
                    continue;
                if (jnode == NILLNODE) {
                    Error("Resumed child (%d) not in table", pid);
                    continue;
@@ -2323,7 +2359,7 @@ Job_ParseShell (line)
     while (isspace (*line)) {
        line++;
     }
     while (isspace (*line)) {
        line++;
     }
-    words = brk_string (line, &wordCount);
+    words = brk_string (line, &wordCount, TRUE);
 
     memset ((Address)&newShell, 0, sizeof(newShell));
     
 
     memset ((Address)&newShell, 0, sizeof(newShell));
     
@@ -2461,7 +2497,9 @@ JobInterrupt (runINTERRUPT)
            char        *file = (job->node->path == (char *)NULL ?
                                 job->node->name :
                                 job->node->path);
            char        *file = (job->node->path == (char *)NULL ?
                                 job->node->name :
                                 job->node->path);
-           if (unlink (file) == 0) {
+           struct stat st;
+           if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) && 
+               unlink(file) != -1) {
                Error ("*** %s removed", file);
            }
        }
                Error ("*** %s removed", file);
            }
        }