from christos@netbsd:
authorderaadt <deraadt@openbsd.org>
Thu, 14 Dec 1995 03:23:26 +0000 (03:23 +0000)
committerderaadt <deraadt@openbsd.org>
Thu, 14 Dec 1995 03:23:26 +0000 (03:23 +0000)
Minor:
    - ${.PREFIX} should never contain a full pathname
    - Fixed gcc -Wall warnings
Major:
    - compatMake is now FALSE. This means that we are now running in
      full pmake mode:
          * rules on dependency lines can be executed in parallel and or
            out of sequence:

            foo: bar baz

            can fire the rule for baz before the rule for bar is fired.
            To enforce bar to be fired before baz, another rule needs to be
            added. [bar: baz]
          * adjacent shell commands in a target are now executed by a single
            invocation of the shell, not one invocation of the shell per line
      (compatMake can be turned off using the -B flag)
    - The -j flag now works... I.e. make -j 4 will fork up to four jobs in
      parallel when it can. The target name is printed before each burst
      of output caused by the target execution as '--- target ---', when j > 1
    - I have changed all the Makefiles so that they work with make -j N, and
      I have tested the whole netbsd by:
          'make -j 4 cleandir; make -j 4 depend; make -j 4; make -j 4 install'
    - I have not compiled or tested this version of make with -DREMOTE.
- Turn compat mode on by default. It gets turned off when the -j without
  the -B flag is specified. [Thus you can use -j 1 to turn it off].
- Fix malloc -> emalloc as Gordon noted.
Updates for POSIX/SVR4 compiling:
arch.c:          Don't require ranlib stuff. Not everybody has it.
dir.c:           SunOS-4 != Solaris; change #ifdef sun to #if sun && !__svr4__
job.c, compat.c: Don't use 'union wait', use int and the W*() macros.
main.c:          Check for uname() == -1; some unames return > 0...
util.c, job.c:   Add signal() with BSD semantics for svr4, don't use bsd
                 sigmask and friends.

from cgd@netbsd:
pull in make.h.  (PAlloc() now uses emalloc(), which is prototyped in
make.h.  If the prototype is not in scope on the Alpha, I see lots
of "cast to pointer from integer of different size" warnings.)

14 files changed:
usr.bin/make/arch.c
usr.bin/make/bit.h
usr.bin/make/compat.c
usr.bin/make/dir.c
usr.bin/make/extern.h
usr.bin/make/job.c
usr.bin/make/lst.lib/lstInt.h
usr.bin/make/main.c
usr.bin/make/make.1
usr.bin/make/nonints.h
usr.bin/make/parse.c
usr.bin/make/suff.c
usr.bin/make/util.c
usr.bin/make/var.c

index 47ac51d..89a84be 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: arch.c,v 1.9 1995/06/14 15:18:46 christos Exp $        */
+/*     $NetBSD: arch.c,v 1.11 1995/11/22 17:39:53 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)arch.c     5.7 (Berkeley) 12/28/90";
 #else
-static char rcsid[] = "$NetBSD: arch.c,v 1.9 1995/06/14 15:18:46 christos Exp $";
+static char rcsid[] = "$NetBSD: arch.c,v 1.11 1995/11/22 17:39:53 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -100,7 +100,9 @@ static char rcsid[] = "$NetBSD: arch.c,v 1.9 1995/06/14 15:18:46 christos Exp $"
 #include    <sys/param.h>
 #include    <ctype.h>
 #include    <ar.h>
+#ifndef __svr4__
 #include    <ranlib.h>
+#endif
 #include    <stdio.h>
 #include    <stdlib.h>
 #include    "make.h"
@@ -492,7 +494,7 @@ ArchStatMember (archive, member, hash)
                strncpy(copy, member, AR_MAX_NAME_LEN);
                copy[AR_MAX_NAME_LEN] = '\0';
            }
-           if (he = Hash_FindEntry (&ar->members, copy))
+           if ((he = Hash_FindEntry (&ar->members, copy)) != NULL)
                return ((struct ar_hdr *) Hash_GetValue (he));
            return ((struct ar_hdr *) NULL);
        }
@@ -1031,6 +1033,7 @@ Arch_LibOODate (gn)
     } else if ((gn->mtime > now) || (gn->mtime < gn->cmtime)) {
        oodate = TRUE;
     } else {
+#ifdef RANLIBMAG
        struct ar_hdr   *arhPtr;    /* Header for __.SYMDEF */
        int             modTimeTOC; /* The table-of-contents's mod time */
 
@@ -1052,6 +1055,9 @@ Arch_LibOODate (gn)
            }
            oodate = TRUE;
        }
+#else
+       oodata = FALSE;
+#endif
     }
     return (oodate);
 }
index 34cc4da..d1b08a3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: bit.h,v 1.4 1995/06/14 15:18:49 christos Exp $ */
+/*     $NetBSD: bit.h,v 1.5 1995/11/08 02:30:53 christos Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -64,7 +64,7 @@
        (Bit_NumInts(numBits) * sizeof(int))
 
 #define Bit_Alloc(numBits, bitArrayPtr)        \
-        bitArrayPtr = (int *)malloc((unsigned)Bit_NumBytes(numBits)); \
+        bitArrayPtr = (int *) emalloc((unsigned)Bit_NumBytes(numBits)); \
         Bit_Zero((numBits), (bitArrayPtr))
 
 #define Bit_Free(bitArrayPtr)  \
index c2c7815..394ed30 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: compat.c,v 1.11 1995/09/27 18:44:38 jtc Exp $  */
+/*     $NetBSD: compat.c,v 1.13 1995/11/22 17:40:00 christos Exp $     */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)compat.c   5.7 (Berkeley) 3/1/91";
 #else
-static char rcsid[] = "$NetBSD: compat.c,v 1.11 1995/09/27 18:44:38 jtc Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.13 1995/11/22 17:40:00 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -111,10 +111,8 @@ CompatInterrupt (signo)
     if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
        char      *p1;
        char      *file = Var_Value (TARGET, curTarg, &p1);
-       struct stat st;
 
-       if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) && 
-           unlink(file) != -1) {
+       if (!noExecute && eunlink(file) != -1) {
            printf ("*** %s removed\n", file);
        }
        if (p1)
@@ -157,7 +155,7 @@ CompatRunCommand (cmdp, gnp)
     register char *cp;
     Boolean      silent,       /* Don't print command */
                  errCheck;     /* Check errors */
-    union wait           reason;       /* Reason for child's death */
+    int          reason;       /* Reason for child's death */
     int                  status;       /* Description of child's death */
     int                  cpid;         /* Child actually found */
     ReturnStatus  stat;                /* Status of fork */
@@ -298,7 +296,7 @@ CompatRunCommand (cmdp, gnp)
      */
     while (1) {
 
-       while ((stat = wait((int *)&reason)) != cpid) {
+       while ((stat = wait(&reason)) != cpid) {
            if (stat == -1 && errno != EINTR) {
                break;
            }
@@ -306,14 +304,14 @@ CompatRunCommand (cmdp, gnp)
        
        if (stat > -1) {
            if (WIFSTOPPED(reason)) {
-               status = reason.w_stopval;              /* stopped */
+               status = WSTOPSIG(reason);              /* stopped */
            } else if (WIFEXITED(reason)) {
-               status = reason.w_retcode;              /* exited */
+               status = WEXITSTATUS(reason);           /* exited */
                if (status != 0) {
                    printf ("*** Error code %d", status);
                }
            } else {
-               status = reason.w_termsig;              /* signaled */
+               status = WTERMSIG(reason);              /* signaled */
                printf ("*** Signal %d", status);
            } 
 
index 83c22a0..abb30fe 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dir.c,v 1.8 1995/06/14 15:19:07 christos Exp $ */
+/*     $NetBSD: dir.c,v 1.9 1995/11/22 17:40:05 christos Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)dir.c      5.6 (Berkeley) 12/28/90";
 #else
-static char rcsid[] = "$NetBSD: dir.c,v 1.8 1995/06/14 15:19:07 christos Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.9 1995/11/22 17:40:05 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -1065,7 +1065,7 @@ Dir_AddDir (path, name)
            (void)readdir(d);
            
            while ((dp = readdir (d)) != (struct dirent *) NULL) {
-#ifdef sun
+#if defined(sun) && !defined(__svr4__)
                /*
                 * The sun directory library doesn't check for a 0 inode
                 * (0-inode slots just take up space), so we have to do
@@ -1074,7 +1074,7 @@ Dir_AddDir (path, name)
                if (dp->d_fileno == 0) {
                    continue;
                }
-#endif /* sun */
+#endif /* sun && !__svr4__ */
                (void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL);
            }
            (void) closedir (d);
index e333389..c719a2c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: nonints.h,v 1.6 1995/06/14 15:19:45 christos Exp $     */
+/*     $NetBSD: nonints.h,v 1.7 1995/11/02 23:55:00 christos Exp $     */
 
 /*-
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -73,6 +73,7 @@ int PrintAddr __P((ClientData, ClientData));
 void Finish __P((int));
 char *emalloc __P((size_t));
 void enomem __P((void));
+int eunlink __P((const char *));
 
 /* parse.c */
 void Parse_Error __P((int, char *, ...));
index 85fb435..f6b9dda 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: job.c,v 1.11 1995/09/27 18:44:40 jtc Exp $     */
+/*     $NetBSD: job.c,v 1.13 1995/11/22 17:40:09 christos Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)job.c      5.15 (Berkeley) 3/1/91";
 #else
-static char rcsid[] = "$NetBSD: job.c,v 1.11 1995/09/27 18:44:40 jtc Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.13 1995/11/22 17:40:09 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -118,6 +118,12 @@ static char rcsid[] = "$NetBSD: job.c,v 1.11 1995/09/27 18:44:40 jtc Exp $";
 #include "dir.h"
 #include "job.h"
 #include "pathnames.h"
+#ifdef REMOTE
+#include "rmt.h"
+# define STATIC 
+#else
+# define STATIC static
+#endif
 
 extern int  errno;
 
@@ -130,6 +136,11 @@ static int         aborting = 0;       /* why is the make aborting? */
 #define ABORT_INTERRUPT        2           /* Because it was interrupted */
 #define ABORT_WAIT     3           /* Waiting for jobs to finish */
 
+/* 
+ * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file
+ * is a char! So when we go above 127 we turn negative!
+ */
+#define FILENO(a) ((unsigned) fileno(a))
 
 /*
  * post-make command processing. The node postCommands is really just the
@@ -142,7 +153,6 @@ static int            numCommands;      /* The number of commands actually printed
                                     * for a target. Should this number be
                                     * 0, no shell will be executed. */
 
-
 /*
  * Return values from JobStart.
  */
@@ -182,17 +192,20 @@ static Shell    shells[] = {
 {
     "sh",
     TRUE, "set -", "set -v", "set -", 5,
+    TRUE, "set -e", "set +e",
+#ifdef OLDBOURNESHELL
     FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n",
+#endif
     "v", "e",
 },
     /*
      * UNKNOWN.
      */
 {
-    (char *)0,
-    FALSE, (char *)0, (char *)0, (char *)0, 0,
-    FALSE, (char *)0, (char *)0,
-    (char *)0, (char *)0,
+    (char *) 0,
+    FALSE, (char *) 0, (char *) 0, (char *) 0, 0,
+    FALSE, (char *) 0, (char *) 0,
+    (char *) 0, (char *) 0,
 }
 };
 static Shell   *commandShell = &shells[DEFSHELL];/* this is the shell to
@@ -200,17 +213,17 @@ static Shell      *commandShell = &shells[DEFSHELL];/* this is the shell to
                                                   * commands in the Makefile.
                                                   * It is set by the
                                                   * Job_ParseShell function */
-static char    *shellPath = (char *) NULL,       /* full pathname of
+static char    *shellPath = NULL,                /* full pathname of
                                                   * executable image */
                        *shellName;                       /* last component of shell */
 
 
 static int     maxJobs;        /* The most children we can run at once */
 static int     maxLocal;       /* The most local ones we can have */
-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
+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
                                 * 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
@@ -220,12 +233,21 @@ static fd_set     outputs;        /* Set of descriptors of pipes connected to
                                 * the output channels of children */
 #endif
 
-GNode          *lastNode;      /* The node for which output was most recently
+STATIC GNode           *lastNode;      /* The node for which output was most recently
                                 * produced. */
-char           *targFmt;       /* Format string to use to head output from a
+STATIC 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 */
+
+#ifdef REMOTE
+# define TARG_FMT  "--- %s at %s ---\n" /* Default format */
+# define MESSAGE(fp, gn) \
+       (void) fprintf(fp, targFmt, gn->name, gn->rem.hname);
+#else
+# define TARG_FMT  "--- %s ---\n" /* Default format */
+# define MESSAGE(fp, gn) \
+       (void) fprintf(fp, targFmt, gn->name);
+#endif
 
 /*
  * When JobStart attempts to run a job remotely but can't, and isn't allowed
@@ -233,34 +255,63 @@ 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. 
  */
-Lst            stoppedJobs;    /* Lst of Job structures describing
+STATIC Lst     stoppedJobs;    /* Lst of Job structures describing
                                 * jobs that were stopped due to concurrency
                                 * limits or migration home */
 
 
 #if defined(USE_PGRP) && defined(SYSV)
-#define KILL(pid,sig)  killpg (-(pid),(sig))
+# define KILL(pid, sig)                killpg(-(pid), (sig))
 #else
 # if defined(USE_PGRP)
-#define KILL(pid,sig)  killpg ((pid),(sig))
+#  define KILL(pid, sig)       killpg((pid), (sig))
 # else
-#define KILL(pid,sig)  kill ((pid),(sig))
+#  define KILL(pid, sig)       kill((pid), (sig))
 # endif
 #endif
 
+/* 
+ * Grmpf... There is no way to set bits of the wait structure
+ * anymore with the stupid W*() macros. I liked the union wait
+ * stuff much more. So, we devise our own macros... This is
+ * really ugly, use dramamine sparingly. You have been warned.
+ */
+#define W_SETMASKED(st, val, fun)                              \
+       {                                                       \
+               int sh = (int) ~0;                              \
+               int mask = fun(sh);                             \
+                                                               \
+               for (sh = 0; ((mask >> sh) & 1) == 0; sh++)     \
+                       continue;                               \
+               *(st) = (*(st) & ~mask) | ((val) << sh);        \
+       }
+
+#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG)
+#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS)
+
+
 static int JobCondPassSig __P((ClientData, ClientData));
 static void JobPassSig __P((int));
 static int JobCmpPid __P((ClientData, ClientData));
 static int JobPrintCommand __P((ClientData, ClientData));
 static int JobSaveCommand __P((ClientData, ClientData));
-static void JobFinish __P((Job *, union wait));
+static void JobClose __P((Job *));
+#ifdef REMOTE
+static int JobCmpRmtID __P((Job *, int));
+# ifdef RMT_WILL_WATCH
+static void JobLocalInput __P((int, Job *));
+# endif
+#else
+static void JobFinish __P((Job *, int *));
 static void JobExec __P((Job *, char **));
+#endif
 static void JobMakeArgv __P((Job *, char **));
 static void JobRestart __P((Job *));
 static int JobStart __P((GNode *, int, Job *));
 static void JobDoOutput __P((Job *, Boolean));
 static Shell *JobMatchShell __P((char *));
-static void JobInterrupt __P((int));
+static void JobInterrupt __P((int, int));
+static void JobRestartJobs __P((void));
 
 /*-
  *-----------------------------------------------------------------------
@@ -285,7 +336,7 @@ JobCondPassSig(jobp, signop)
     int        signo = *(int *) signop;
 #ifdef RMT_WANTS_SIGNALS
     if (job->flags & JOB_REMOTE) {
-       (void)Rmt_Signal(job, signo);
+       (void) Rmt_Signal(job, signo);
     } else {
        KILL(job->pid, signo);
     }
@@ -294,9 +345,15 @@ JobCondPassSig(jobp, signop)
      * Assume that sending the signal to job->pid will signal any remote
      * job as well.
      */
+    if (DEBUG(JOB)) {
+       (void) fprintf(stdout, 
+                      "JobCondPassSig passing signal %d to child %d.\n",
+                      signo, job->pid);
+       (void) fflush(stdout);
+    }
     KILL(job->pid, signo);
 #endif
-    return(0);
+    return 0;
 }
 
 /*-
@@ -317,9 +374,13 @@ static void
 JobPassSig(signo)
     int            signo;      /* The signal number we've received */
 {
-    int            mask;
+    sigset_t nmask, omask;
     
-    Lst_ForEach(jobs, JobCondPassSig, (ClientData)(long)signo);
+    if (DEBUG(JOB)) {
+       (void) fprintf(stdout, "JobPassSig(%d) called.\n", signo);
+       (void) fflush(stdout);
+    }
+    Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
 
     /*
      * Deal with proper cleanup based on the signal received. We only run
@@ -327,9 +388,9 @@ JobPassSig(signo)
      * three termination signals are more of a "get out *now*" command.
      */
     if (signo == SIGINT) {
-       JobInterrupt(TRUE);
+       JobInterrupt(TRUE, signo);
     } else if ((signo == SIGHUP) || (signo == SIGTERM) || (signo == SIGQUIT)) {
-       JobInterrupt(FALSE);
+       JobInterrupt(FALSE, signo);
     }
     
     /*
@@ -345,17 +406,24 @@ JobPassSig(signo)
      * This ensures that all our jobs get continued when we wake up before
      * we take any other signal.
      */
-    mask = sigblock(0);
-    (void) sigsetmask(~0 & ~(1 << (signo-1)));
-    signal(signo, SIG_DFL);
+    sigfillset(&nmask);
+    (void) sigprocmask(SIG_BLOCK, &nmask, &omask);
 
-    kill(getpid(), signo);
+    if (DEBUG(JOB)) {
+       (void) fprintf(stdout,
+                      "JobPassSig passing signal to self, mask = %x.\n",
+                      ~0 & ~(1 << (signo-1)));
+       (void) fflush(stdout);
+    }
+    (void) signal(signo, SIG_DFL);
+
+    (void) KILL(getpid(), signo);
 
     signo = SIGCONT;
     Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
 
-    sigsetmask(mask);
-    signal(signo, JobPassSig);
+    (void) sigprocmask(SIG_SETMASK, &omask, NULL);
+    (void) signal(signo, JobPassSig);
 
 }
 
@@ -374,13 +442,36 @@ JobPassSig(signo)
  *-----------------------------------------------------------------------
  */
 static int
-JobCmpPid (job, pid)
+JobCmpPid(job, pid)
     ClientData        job;     /* job to examine */
     ClientData        pid;     /* process id desired */
 {
-    return ( *(int *) pid - ((Job *) job)->pid);
+    return( *(int *) pid - ((Job *) job)->pid);
 }
 
+#ifdef REMOTE
+/*-
+ *-----------------------------------------------------------------------
+ * JobCmpRmtID  --
+ *     Compare the rmtID of the job with the given rmtID and return 0 if they
+ *     are equal. 
+ *
+ * Results:
+ *     0 if the rmtID's match
+ *
+ * Side Effects:
+ *     None.
+ *-----------------------------------------------------------------------
+ */
+static int
+JobCmpRmtID(job, rmtID)
+    ClientData      job;       /* job to examine */
+    ClientData      rmtID;     /* remote id desired */
+{
+    return(*(int *) rmtID - *(int *) job->rmtID);
+}
+#endif
+
 /*-
  *-----------------------------------------------------------------------
  * JobPrintCommand  --
@@ -409,7 +500,7 @@ JobCmpPid (job, pid)
  *-----------------------------------------------------------------------
  */
 static int
-JobPrintCommand (cmdp, jobp)
+JobPrintCommand(cmdp, jobp)
     ClientData    cmdp;                    /* command string to print */
     ClientData    jobp;                    /* job for which to print it */
 {
@@ -428,19 +519,24 @@ JobPrintCommand (cmdp, jobp)
     char         *cmd = (char *) cmdp;
     Job           *job = (Job *) jobp; 
 
-    noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
+    noSpecials = (noExecute && !(job->node->type & OP_MAKE));
 
-    if (strcmp (cmd, "...") == 0) {
+    if (strcmp(cmd, "...") == 0) {
        job->node->type |= OP_SAVE_CMDS; 
        if ((job->flags & JOB_IGNDOTS) == 0) {
-           job->tailCmds = Lst_Succ (Lst_Member (job->node->commands,
-                                                 (ClientData)cmd));
-           return (1);
+           job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
+                                               (ClientData)cmd));
+           return(1);
        }
-       return (0);
+       return(0);
     }
 
-#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) printf (fmt, arg); fprintf (job->cmdFILE, fmt, arg)
+#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) {   \
+       (void) fprintf(stdout, fmt, arg);       \
+       (void) fflush(stdout);                  \
+    }                                          \
+   (void) fprintf(job->cmdFILE, fmt, arg);     \
+   (void) fflush(job->cmdFILE);
 
     numCommands += 1;
 
@@ -448,9 +544,9 @@ JobPrintCommand (cmdp, jobp)
      * For debugging, we replace each command with the result of expanding
      * the variables in the command.
      */
-    cmdNode = Lst_Member (job->node->commands, (ClientData)cmd);
-    cmdStart = cmd = Var_Subst (NULL, cmd, job->node, FALSE);
-    Lst_Replace (cmdNode, (ClientData)cmdStart);
+    cmdNode = Lst_Member(job->node->commands, (ClientData)cmd);
+    cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE);
+    Lst_Replace(cmdNode, (ClientData)cmdStart);
 
     cmdTemplate = "%s\n";
 
@@ -470,16 +566,16 @@ JobPrintCommand (cmdp, jobp)
        cmd++;
 
     if (shutUp) {
-       if (! (job->flags & JOB_SILENT) && !noSpecials &&
+       if (!(job->flags & JOB_SILENT) && !noSpecials &&
            commandShell->hasEchoCtl) {
-               DBPRINTF ("%s\n", commandShell->echoOff);
+               DBPRINTF("%s\n", commandShell->echoOff);
        } else {
            shutUp = FALSE;
        }
     }
 
     if (errOff) {
-       if ( ! (job->flags & JOB_IGNERR) && !noSpecials) {
+       if ( !(job->flags & JOB_IGNERR) && !noSpecials) {
            if (commandShell->hasErrCtl) {
                /*
                 * we don't want the error-control commands showing
@@ -489,16 +585,16 @@ JobPrintCommand (cmdp, jobp)
                 * string too, but why make it any more complex than
                 * it already is?
                 */
-               if (! (job->flags & JOB_SILENT) && !shutUp &&
+               if (!(job->flags & JOB_SILENT) && !shutUp &&
                    commandShell->hasEchoCtl) {
-                       DBPRINTF ("%s\n", commandShell->echoOff);
-                       DBPRINTF ("%s\n", commandShell->ignErr);
-                       DBPRINTF ("%s\n", commandShell->echoOn);
+                       DBPRINTF("%s\n", commandShell->echoOff);
+                       DBPRINTF("%s\n", commandShell->ignErr);
+                       DBPRINTF("%s\n", commandShell->echoOn);
                } else {
-                   DBPRINTF ("%s\n", commandShell->ignErr);
+                   DBPRINTF("%s\n", commandShell->ignErr);
                }
            } else if (commandShell->ignErr &&
-                      (*commandShell->ignErr != '\0'))
+                     (*commandShell->ignErr != '\0'))
            {
                /*
                 * The shell has no error control, so we need to be
@@ -509,15 +605,15 @@ JobPrintCommand (cmdp, jobp)
                 * to ignore errors. Set cmdTemplate to use the weirdness
                 * instead of the simple "%s\n" template.
                 */
-               if (! (job->flags & JOB_SILENT) && !shutUp &&
+               if (!(job->flags & JOB_SILENT) && !shutUp &&
                    commandShell->hasEchoCtl) {
-                       DBPRINTF ("%s\n", commandShell->echoOff);
-                       DBPRINTF (commandShell->errCheck, cmd);
+                       DBPRINTF("%s\n", commandShell->echoOff);
+                       DBPRINTF(commandShell->errCheck, cmd);
                        shutUp = TRUE;
                }
                cmdTemplate = commandShell->ignErr;
                /*
-                * The error ignoration (hee hee) is already taken care
+                * The error ignoration(hee hee) is already taken care
                 * of by the ignErr template, so pretend error checking
                 * is still on.
                 */
@@ -530,7 +626,7 @@ JobPrintCommand (cmdp, jobp)
        }
     }
     
-    DBPRINTF (cmdTemplate, cmd);
+    DBPRINTF(cmdTemplate, cmd);
     
     if (errOff) {
        /*
@@ -539,15 +635,15 @@ JobPrintCommand (cmdp, jobp)
         * for the whole command...
         */
        if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
-           DBPRINTF ("%s\n", commandShell->echoOff);
+           DBPRINTF("%s\n", commandShell->echoOff);
            shutUp = TRUE;
        }
-       DBPRINTF ("%s\n", commandShell->errCheck);
+       DBPRINTF("%s\n", commandShell->errCheck);
     }
     if (shutUp) {
-       DBPRINTF ("%s\n", commandShell->echoOn);
+       DBPRINTF("%s\n", commandShell->echoOn);
     }
-    return (0);
+    return 0;
 }
 
 /*-
@@ -565,13 +661,48 @@ JobPrintCommand (cmdp, jobp)
  *-----------------------------------------------------------------------
  */
 static int
-JobSaveCommand (cmd, gn)
+JobSaveCommand(cmd, gn)
     ClientData   cmd;
     ClientData   gn;
 {
-    cmd = (ClientData) Var_Subst (NULL, (char *) cmd, (GNode *) gn, FALSE);
-    (void)Lst_AtEnd (postCommands->commands, cmd);
-    return (0);
+    cmd = (ClientData) Var_Subst(NULL, (char *) cmd, (GNode *) gn, FALSE);
+    (void) Lst_AtEnd(postCommands->commands, cmd);
+    return(0);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobClose --
+ *     Called to close both input and output pipes when a job is finished.
+ *
+ * Results:
+ *     Nada
+ *
+ * Side Effects:
+ *     The file descriptors associated with the job are closed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobClose(job)
+    Job *job;
+{
+    if (usePipes) {
+#ifdef RMT_WILL_WATCH
+       Rmt_Ignore(job->inPipe);
+#else
+       FD_CLR(job->inPipe, &outputs);
+#endif
+       if (job->outPipe != job->inPipe) {
+          (void) close(job->outPipe);
+       }
+       JobDoOutput(job, TRUE);
+       (void) close(job->inPipe);
+    } else {
+       (void) close(job->outFd);
+       JobDoOutput(job, TRUE);
+    }
 }
 
 /*-
@@ -591,23 +722,23 @@ JobSaveCommand (cmd, gn)
  *     Some nodes may be put on the toBeMade queue.
  *     Final commands for the job are placed on postCommands.
  *
- *     If we got an error and are aborting (aborting == ABORT_ERROR) and
+ *     If we got an error and are aborting(aborting == ABORT_ERROR) and
  *     the job list is now empty, we are done for the day.
- *     If we recognized an error (errors !=0), we set the aborting flag
+ *     If we recognized an error(errors !=0), we set the aborting flag
  *     to ABORT_ERROR so no more jobs will be started.
  *-----------------------------------------------------------------------
  */
 /*ARGSUSED*/
 static void
-JobFinish (job, status)
-    Job           *job;                  /* job to finish */
-    union wait   status;         /* sub-why job went away */
+JobFinish(job, status)
+    Job         *job;            /* job to finish */
+    int                *status;          /* sub-why job went away */
 {
-    Boolean      done;
+    Boolean     done;
 
-    if ((WIFEXITED(status) &&
-         (((status.w_retcode != 0) && !(job->flags & JOB_IGNERR)))) ||
-       (WIFSIGNALED(status) && (status.w_termsig != SIGCONT)))
+    if ((WIFEXITED(*status) &&
+        (((WEXITSTATUS(*status) != 0) && !(job->flags & JOB_IGNERR)))) ||
+       (WIFSIGNALED(*status) && (WTERMSIG(*status) != SIGCONT)))
     {
        /*
         * If it exited non-zero and either we're doing things our
@@ -617,36 +748,38 @@ JobFinish (job, status)
         * cases, finish out the job's output before printing the exit
         * status...
         */
-       if (usePipes) {
-#ifdef RMT_WILL_WATCH
-           Rmt_Ignore(job->inPipe);
-#else
-           FD_CLR(job->inPipe, &outputs);
-#endif /* RMT_WILL_WATCH */
-           if (job->outPipe != job->inPipe) {
-               (void)close (job->outPipe);
-           }
-           JobDoOutput (job, TRUE);
-           (void)close (job->inPipe);
-       } else {
-           (void)close (job->outFd);
-           JobDoOutput (job, TRUE);
-       }
-
+#ifdef REMOTE
+       KILL(job->pid, SIGCONT);
+#endif
+       JobClose(job);
        if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
-           fclose(job->cmdFILE);
+          (void) fclose(job->cmdFILE);
        }
        done = TRUE;
-    } else if (WIFEXITED(status) && status.w_retcode != 0) {
+#ifdef REMOTE
+       if (job->flags & JOB_REMOTE)
+           Rmt_Done(job->rmtID, job->node);
+#endif
+    } else if (WIFEXITED(*status)) {
        /*
         * Deal with ignored errors in -B mode. We need to print a message
         * telling of the ignored error as well as setting status.w_status
         * to 0 so the next command gets run. To do this, we set done to be
-        * TRUE if in -B mode and the job exited non-zero. Note we don't
+        * TRUE if in -B mode and the job exited non-zero.
+        */
+       done = WEXITSTATUS(*status) != 0;
+       /* 
+        * Old comment said: "Note we don't
         * want to close down any of the streams until we know we're at the
-        * end.
+        * end."
+        * But we do. Otherwise when are we going to print the rest of the
+        * stuff?
         */
-       done = TRUE;
+       JobClose(job);
+#ifdef REMOTE
+       if (job->flags & JOB_REMOTE)
+           Rmt_Done(job->rmtID, job->node);
+#endif /* REMOTE */
     } else {
        /*
         * No need to close things down or anything.
@@ -655,93 +788,127 @@ JobFinish (job, status)
     }
     
     if (done ||
-       WIFSTOPPED(status) ||
-       (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) ||
+       WIFSTOPPED(*status) ||
+       (WIFSIGNALED(*status) && (WTERMSIG(*status) == SIGCONT)) ||
        DEBUG(JOB))
     {
        FILE      *out;
        
-       if (!usePipes && (job->flags & JOB_IGNERR)) {
+       if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) {
            /*
             * If output is going to a file and this job is ignoring
             * errors, arrange to have the exit status sent to the
             * output file as well.
             */
-           out = fdopen (job->outFd, "w");
+           out = fdopen(job->outFd, "w");
        } else {
            out = stdout;
        }
 
-       if (WIFEXITED(status)) {
-           if (status.w_retcode != 0) {
+       if (WIFEXITED(*status)) {
+           if (DEBUG(JOB)) {
+               (void) fprintf(stdout, "Process %d exited.\n", job->pid);
+               (void) fflush(stdout);
+           }
+           if (WEXITSTATUS(*status) != 0) {
                if (usePipes && job->node != lastNode) {
-                   fprintf (out, targFmt, job->node->name);
+                   MESSAGE(out, job->node);
                    lastNode = job->node;
                }
-               fprintf (out, "*** Error code %d%s\n", status.w_retcode,
-                        (job->flags & JOB_IGNERR) ? " (ignored)" : "");
+               (void) fprintf(out, "*** Error code %d%s\n",
+                              WEXITSTATUS(*status),
+                              (job->flags & JOB_IGNERR) ? "(ignored)" : "");
 
                if (job->flags & JOB_IGNERR) {
-                   status.w_status = 0;
+                   *status = 0;
                }
            } else if (DEBUG(JOB)) {
                if (usePipes && job->node != lastNode) {
-                   fprintf (out, targFmt, job->node->name);
+                   MESSAGE(out, job->node);
                    lastNode = job->node;
                }
-               fprintf (out, "*** Completed successfully\n");
+               (void) fprintf(out, "*** Completed successfully\n");
+           }
+       } else if (WIFSTOPPED(*status)) {
+           if (DEBUG(JOB)) {
+               (void) fprintf(stdout, "Process %d stopped.\n", job->pid);
+               (void) fflush(stdout);
            }
-       } else if (WIFSTOPPED(status)) {
            if (usePipes && job->node != lastNode) {
-               fprintf (out, targFmt, job->node->name);
+               MESSAGE(out, job->node);
                lastNode = job->node;
            }
-           if (! (job->flags & JOB_REMIGRATE)) {
-               fprintf (out, "*** Stopped -- signal %d\n", status.w_stopsig);
+           if (!(job->flags & JOB_REMIGRATE)) {
+               fprintf(out, "*** Stopped -- signal %d\n", WSTOPSIG(*status));
            }
            job->flags |= JOB_RESUME;
            (void)Lst_AtEnd(stoppedJobs, (ClientData)job);
-           fflush(out);
+#ifdef REMOTE
+           if (job->flags & JOB_REMIGRATE)
+               JobRestart(job);
+#endif
+           (void) fflush(out);
            return;
-       } else if (status.w_termsig == SIGCONT) {
+       } else if (WTERMSIG(*status) == SIGCONT) {
            /*
             * If the beastie has continued, shift the Job from the stopped
-            * list to the running one (or re-stop it if concurrency is
+            * list to the running one(or re-stop it if concurrency is
             * exceeded) and go and get another child.
             */
            if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) {
                if (usePipes && job->node != lastNode) {
-                   fprintf (out, targFmt, job->node->name);
+                   MESSAGE(out, job->node);
                    lastNode = job->node;
                }
-               fprintf (out, "*** Continued\n");
+               (void) fprintf(out, "*** Continued\n");
            }
-           if (! (job->flags & JOB_CONTINUING)) {
-               JobRestart(job);
-           } else {
-               Lst_AtEnd(jobs, (ClientData)job);
-               nJobs += 1;
-               if (! (job->flags & JOB_REMOTE)) {
-                   nLocal += 1;
-               }
-               if (nJobs == maxJobs) {
-                   jobFull = TRUE;
-                   if (DEBUG(JOB)) {
-                       printf("Job queue is full.\n");
-                   }
+           if (!(job->flags & JOB_CONTINUING)) {
+               if (DEBUG(JOB)) {
+                   (void) fprintf(stdout,
+                                  "Warning: process %d was not continuing.\n",
+                                  job->pid);
+                   (void) fflush(stdout);
                }
+#ifdef notdef
+               /*
+                * We don't really want to restart a job from scratch just
+                * because it continued, especially not without killing the
+                * continuing process!  That's why this is ifdef'ed out.
+                * FD - 9/17/90
+                */
+               JobRestart(job);
+#endif
            }
-           fflush(out);
-           return;
+           job->flags &= ~JOB_CONTINUING;
+           Lst_AtEnd(jobs, (ClientData)job);
+           nJobs += 1;
+           if (!(job->flags & JOB_REMOTE)) {
+               if (DEBUG(JOB)) {
+                   (void) fprintf(stdout,
+                                  "Process %d is continuing locally.\n",
+                                  job->pid);
+                   (void) fflush(stdout);
+               }
+               nLocal += 1;
+           }
+           if (nJobs == maxJobs) {
+               jobFull = TRUE;
+               if (DEBUG(JOB)) {
+                   (void) fprintf(stdout, "Job queue is full.\n");
+                   (void) fflush(stdout);
+               }
+           }
+           (void) fflush(out);
+           return;
        } else {
            if (usePipes && job->node != lastNode) {
-               fprintf (out, targFmt, job->node->name);
+               MESSAGE(out, job->node);
                lastNode = job->node;
            }
-           fprintf (out, "*** Signal %d\n", status.w_termsig);
+           (void) fprintf(out, "*** Signal %d\n", WTERMSIG(*status));
        }
 
-       fflush (out);
+       (void) fflush(out);
     }
 
     /*
@@ -749,30 +916,26 @@ JobFinish (job, status)
      * try and restart the job on the next command. If JobStart says it's
      * ok, it's ok. If there's an error, this puppy is done.
      */
-    if ((status.w_status == 0) &&
-       !Lst_IsAtEnd (job->node->commands))
-    {
-       switch (JobStart (job->node,
-                         job->flags & JOB_IGNDOTS,
-                         job))
-       {
-           case JOB_RUNNING:
-               done = FALSE;
-               break;
-           case JOB_ERROR:
-               done = TRUE;
-               status.w_retcode = 1;
-               break;
-           case JOB_FINISHED:
-               /*
-                * If we got back a JOB_FINISHED code, JobStart has already
-                * called Make_Update and freed the job descriptor. We set
-                * done to false here to avoid fake cycles and double frees.
-                * JobStart needs to do the update so we can proceed up the
-                * graph when given the -n flag..
-                */
-               done = FALSE;
-               break;
+    if (compatMake && (WIFEXITED(*status) &&
+       !Lst_IsAtEnd(job->node->commands))) {
+       switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) {
+       case JOB_RUNNING:
+           done = FALSE;
+           break;
+       case JOB_ERROR:
+           done = TRUE;
+           W_SETEXITSTATUS(status, 1);
+           break;
+       case JOB_FINISHED:
+           /*
+            * If we got back a JOB_FINISHED code, JobStart has already
+            * called Make_Update and freed the job descriptor. We set
+            * done to false here to avoid fake cycles and double frees.
+            * JobStart needs to do the update so we can proceed up the
+            * graph when given the -n flag..
+            */
+           done = FALSE;
+           break;
        }
     } else {
        done = TRUE;
@@ -782,7 +945,7 @@ JobFinish (job, status)
     if (done &&
        (aborting != ABORT_ERROR) &&
        (aborting != ABORT_INTERRUPT) &&
-       (status.w_status == 0))
+       (*status == 0))
     {
        /*
         * As long as we aren't aborting and the job didn't return a non-zero
@@ -791,21 +954,19 @@ JobFinish (job, status)
         * on the .END target.
         */
        if (job->tailCmds != NILLNODE) {
-           Lst_ForEachFrom (job->node->commands, job->tailCmds,
+           Lst_ForEachFrom(job->node->commands, job->tailCmds,
                             JobSaveCommand,
-                            (ClientData)job->node);
+                           (ClientData)job->node);
        }
        job->node->made = MADE;
-       Make_Update (job->node);
+       Make_Update(job->node);
        free((Address)job);
-    } else if (status.w_status) {
+    } else if (*status == 0) {
        errors += 1;
        free((Address)job);
     }
 
-    while (!errors && !jobFull && !Lst_IsEmpty(stoppedJobs)) {
-       JobRestart((Job *)Lst_DeQueue(stoppedJobs));
-    }
+    JobRestartJobs();
 
     /*
      * Set aborting if any error.
@@ -823,8 +984,8 @@ JobFinish (job, status)
        /*
         * If we are aborting and the job table is now empty, we finish.
         */
-       (void) unlink (tfile);
-       Finish (errors);
+       (void) eunlink(tfile);
+       Finish(errors);
     }
 }
 
@@ -843,7 +1004,7 @@ JobFinish (job, status)
  *-----------------------------------------------------------------------
  */
 void
-Job_Touch (gn, silent)
+Job_Touch(gn, silent)
     GNode         *gn;         /* the node of the file to touch */
     Boolean      silent;       /* TRUE if should not print messages */
 {
@@ -859,7 +1020,8 @@ Job_Touch (gn, silent)
     }
     
     if (!silent) {
-       printf ("touch %s\n", gn->name);
+       (void) fprintf(stdout, "touch %s\n", gn->name);
+       (void) fflush(stdout);
     }
 
     if (noExecute) {
@@ -867,16 +1029,16 @@ Job_Touch (gn, silent)
     }
 
     if (gn->type & OP_ARCHV) {
-       Arch_Touch (gn);
+       Arch_Touch(gn);
     } else if (gn->type & OP_LIB) {
-       Arch_TouchLib (gn);
+       Arch_TouchLib(gn);
     } else {
        char    *file = gn->path ? gn->path : gn->name;
 
        times[0].tv_sec = times[1].tv_sec = now;
        times[0].tv_usec = times[1].tv_usec = 0;
        if (utimes(file, times) < 0){
-           streamID = open (file, O_RDWR | O_CREAT, 0666);
+           streamID = open(file, O_RDWR | O_CREAT, 0666);
 
            if (streamID >= 0) {
                char    c;
@@ -886,13 +1048,16 @@ Job_Touch (gn, silent)
                 * modification time, then close the file.
                 */
                if (read(streamID, &c, 1) == 1) {
-                   lseek(streamID, (off_t) 0, SEEK_SET);
-                   write(streamID, &c, 1);
+                   (void) lseek(streamID, 0L, L_SET);
+                   (void) write(streamID, &c, 1);
                }
                
-               (void)close (streamID);
-           } else
-               printf("*** couldn't touch %s: %s", file, strerror(errno));
+               (void) close(streamID);
+           } else {
+               (void) fprintf(stdout, "*** couldn't touch %s: %s",
+                              file, strerror(errno));
+               (void) fflush(stdout);
+           }
        }
     }
 }
@@ -911,13 +1076,13 @@ Job_Touch (gn, silent)
  *-----------------------------------------------------------------------
  */
 Boolean
-Job_CheckCommands (gn, abortProc)
+Job_CheckCommands(gn, abortProc)
     GNode          *gn;                    /* The target whose commands need
                                     * verifying */
-    void         (*abortProc) __P((char *, ...));   
+    void        (*abortProc) __P((char *, ...));   
                        /* Function to abort with message */
 {
-    if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
+    if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) &&
        (gn->type & OP_LIB) == 0) {
        /*
         * No commands. Look for .DEFAULT rule from which we might infer
@@ -935,10 +1100,10 @@ Job_CheckCommands (gn, abortProc)
             * .DEFAULT itself.
             */
            Make_HandleUse(DEFAULT, gn);
-           Var_Set (IMPSRC, Var_Value (TARGET, gn, &p1), gn);
+           Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn);
            if (p1)
                free(p1);
-       } else if (Dir_MTime (gn) == 0) {
+       } else if (Dir_MTime(gn) == 0) {
            /*
             * The node wasn't the target of an operator we have no .DEFAULT
             * rule to go on and the target doesn't already exist. There's
@@ -946,21 +1111,22 @@ Job_CheckCommands (gn, abortProc)
             * given, we stop in our tracks, otherwise we just don't update
             * this node's parents so they never get examined. 
             */
+           static const char msg[] = "make: don't know how to make";
+
            if (gn->type & OP_OPTIONAL) {
-               printf ("make: don't know how to make %s (ignored)\n",
-                       gn->name);
+               (void) fprintf(stdout, "%s %s(ignored)\n", msg, gn->name);
+               (void) fflush(stdout);
            } else if (keepgoing) {
-               printf ("make: don't know how to make %s (continuing)\n",
-                       gn->name);
-               return (FALSE);
+               (void) fprintf(stdout, "%s %s(continuing)\n", msg, gn->name);
+               (void) fflush(stdout);
+               return FALSE;
            } else {
-               (*abortProc) ("make: don't know how to make %s. Stop",
-                            gn->name);
-               return(FALSE);
+               (*abortProc)("%s %s. Stop", msg, gn->name);
+               return FALSE;
            }
        }
     }
-    return (TRUE);
+    return TRUE;
 }
 #ifdef RMT_WILL_WATCH
 /*-
@@ -979,7 +1145,7 @@ Job_CheckCommands (gn, abortProc)
 /*ARGSUSED*/
 static void
 JobLocalInput(stream, job)
-    int            stream;     /* Stream that's ready (ignored) */
+    int            stream;     /* Stream that's ready(ignored) */
     Job            *job;       /* Job to which the stream belongs */
 {
     JobDoOutput(job, FALSE);
@@ -1011,25 +1177,25 @@ JobExec(job, argv)
     if (DEBUG(JOB)) {
        int       i;
        
-       printf("Running %s %sly\n", job->node->name,
-              job->flags&JOB_REMOTE?"remote":"local");
-       printf("\tCommand: ");
-       for (i = 0; argv[i] != (char *)NULL; i++) {
-           printf("%s ", argv[i]);
+       (void) fprintf(stdout, "Running %s %sly\n", job->node->name,
+                      job->flags&JOB_REMOTE?"remote":"local");
+       (void) fprintf(stdout, "\tCommand: ");
+       for (i = 0; argv[i] != NULL; i++) {
+           (void) fprintf(stdout, "%s ", argv[i]);
        }
-       printf("\n");
+       (void) fprintf(stdout, "\n");
+       (void) fflush(stdout);
     }
     
     /*
      * Some jobs produce no output and it's disconcerting to have
-     * no feedback of their running (since they produce no output, the
+     * no feedback of their running(since they produce no output, the
      * banner with their name in it never appears). This is an attempt to
      * provide that feedback, even if nothing follows it.
      */
     if ((lastNode != job->node) && (job->flags & JOB_FIRST) &&
-       !(job->flags & JOB_SILENT))
-    {
-       printf(targFmt, job->node->name);
+       !(job->flags & JOB_SILENT)) {
+       MESSAGE(stdout, job->node);
        lastNode = job->node;
     }
     
@@ -1039,41 +1205,45 @@ JobExec(job, argv)
     }
 #endif /* RMT_NO_EXEC */
 
-    if ((cpid =  vfork()) == -1) {
-       Punt ("Cannot fork");
+    if ((cpid = vfork()) == -1) {
+       Punt("Cannot fork");
     } else if (cpid == 0) {
 
        /*
         * Must duplicate the input stream down to the child's input and
-        * reset it to the beginning (again). Since the stream was marked
+        * reset it to the beginning(again). Since the stream was marked
         * close-on-exec, we must clear that bit in the new input.
         */
-       (void) dup2(fileno(job->cmdFILE), 0);
-       fcntl(0, F_SETFD, 0);
-       lseek(0, (off_t) 0, SEEK_SET);
+       if (dup2(FILENO(job->cmdFILE), 0) == -1)
+           Punt("Cannot dup2: %s", strerror(errno));
+       (void) fcntl(0, F_SETFD, 0);
+       (void) lseek(0, 0, L_SET);
        
        if (usePipes) {
            /*
             * Set up the child's output to be routed through the pipe
             * we've created for it.
             */
-           (void) dup2 (job->outPipe, 1);
+           if (dup2(job->outPipe, 1) == -1)
+               Punt("Cannot dup2: %s", strerror(errno));
        } else {
            /*
             * We're capturing output in a file, so we duplicate the
             * descriptor to the temporary file into the standard
             * output.
             */
-           (void) dup2 (job->outFd, 1);
+           if (dup2(job->outFd, 1) == -1)
+               Punt("Cannot dup2: %s", strerror(errno));
        }
        /*
         * The output channels are marked close on exec. This bit was
-        * duplicated by the dup2 (on some systems), so we have to clear
+        * duplicated by the dup2(on some systems), so we have to clear
         * it before routing the shell's error output to the same place as
         * its standard output.
         */
-       fcntl(1, F_SETFD, 0);
-       (void) dup2 (1, 2);
+       (void) fcntl(1, F_SETFD, 0);
+       if (dup2(1, 2) == -1)
+           Punt("Cannot dup2: %s", strerror(errno));
 
 #ifdef USE_PGRP
        /*
@@ -1081,15 +1251,27 @@ JobExec(job, argv)
         * we can kill it and all its descendants in one fell swoop,
         * by killing its process family, but not commit suicide.
         */
-       
-       (void) setpgrp(0, getpid());
-#endif USE_PGRP
+# if defined(SYSV)
+       (void) setsid();
+# else
+       (void) setpgid(0, getpid());
+# endif
+#endif /* USE_PGRP */
 
-       (void) execv (shellPath, argv);
-       (void) write (2, "Could not execute shell\n",
-                sizeof ("Could not execute shell"));
-       _exit (1);
+#ifdef REMOTE
+       if (job->flags & JOB_REMOTE) {
+           Rmt_Exec(shellPath, argv, FALSE);
+       } else 
+#endif /* REMOTE */
+          (void) execv(shellPath, argv);
+
+       (void) write(2, "Could not execute shell\n",
+                    sizeof("Could not execute shell"));
+       _exit(1);
     } else {
+#ifdef REMOTE
+       long omask = sigblock(sigmask(SIGCHLD));
+#endif
        job->pid = cpid;
 
        if (usePipes && (job->flags & JOB_FIRST) ) {
@@ -1108,17 +1290,24 @@ JobExec(job, argv)
        }
 
        if (job->flags & JOB_REMOTE) {
+#ifndef REMOTE
            job->rmtID = 0;
+#else
+           job->rmtID = Rmt_LastID(job->pid);
+#endif /* REMOTE */
        } else {
            nLocal += 1;
            /*
-            * XXX: Used to not happen if CUSTOMS. Why?
+            * XXX: Used to not happen if REMOTE. Why?
             */
-           if (job->cmdFILE != stdout) {
-               fclose(job->cmdFILE);
+           if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
+               (void) fclose(job->cmdFILE);
                job->cmdFILE = NULL;
            }
        }
+#ifdef REMOTE
+       (void) sigsetmask(omask);
+#endif
     }
 
 #ifdef RMT_NO_EXEC
@@ -1128,7 +1317,7 @@ jobExecFinish:
      * Now the job is actually running, add it to the table.
      */
     nJobs += 1;
-    (void)Lst_AtEnd (jobs, (ClientData)job);
+    (void) Lst_AtEnd(jobs, (ClientData)job);
     if (nJobs == maxJobs) {
        jobFull = TRUE;
     }
@@ -1186,7 +1375,7 @@ JobMakeArgv(job, argv)
            argc++;
        }
     }
-    argv[argc] = (char *)NULL;
+    argv[argc] = NULL;
 }
 
 /*-
@@ -1206,44 +1395,91 @@ static void
 JobRestart(job)
     Job          *job;         /* Job to restart */
 {
+#ifdef REMOTE
+    int host;
+#endif
+    
     if (job->flags & JOB_REMIGRATE) {
-       if (DEBUG(JOB)) {
-           printf("Remigrating %x\n", job->pid);
+       if (
+#ifdef REMOTE
+           verboseRemigrates ||
+#endif
+           DEBUG(JOB)) {
+          (void) fprintf(stdout, "*** remigrating %x(%s)\n",
+                          job->pid, job->node->name);
+          (void) fflush(stdout);
        }
-       if (nLocal != maxLocal) {
+
+#ifdef REMOTE
+       if (!Rmt_ReExport(job->pid, job->node, &host)) {
+           if (verboseRemigrates || DEBUG(JOB)) {
+               (void) fprintf(stdout, "*** couldn't migrate...\n");
+               (void) fflush(stdout);
+           }
+#endif
+           if (nLocal != maxLocal) {
                /*
                 * Job cannot be remigrated, but there's room on the local
                 * machine, so resume the job and note that another
                 * local job has started.
                 */
-               if (DEBUG(JOB)) {
-                   printf("resuming on local machine\n");
-               }
+               if (
+#ifdef REMOTE
+                   verboseRemigrates ||
+#endif
+                   DEBUG(JOB)) {
+                   (void) fprintf(stdout, "*** resuming on local machine\n");
+                   (void) fflush(stdout);
+               }
                KILL(job->pid, SIGCONT);
                nLocal +=1;
+#ifdef REMOTE
+               job->flags &= ~(JOB_REMIGRATE|JOB_RESUME|JOB_REMOTE);
+               job->flags |= JOB_CONTINUING;
+#else
                job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
+#endif
        } else {
                /*
                 * Job cannot be restarted. Mark the table as full and
                 * place the job back on the list of stopped jobs.
                 */
-               if (DEBUG(JOB)) {
-                   printf("holding\n");
-               }
+               if (
+#ifdef REMOTE
+                   verboseRemigrates ||
+#endif
+                   DEBUG(JOB)) {
+                  (void) fprintf(stdout, "*** holding\n");
+                  (void) fflush(stdout);
+               }
                (void)Lst_AtFront(stoppedJobs, (ClientData)job);
                jobFull = TRUE;
                if (DEBUG(JOB)) {
-                   printf("Job queue is full.\n");
+                  (void) fprintf(stdout, "Job queue is full.\n");
+                  (void) fflush(stdout);
                }
                return;
+           }
+#ifdef REMOTE
+       } else {
+           /*
+            * Clear out the remigrate and resume flags. Set the continuing
+            * flag so we know later on that the process isn't exiting just
+            * because of a signal.
+            */
+           job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
+           job->flags |= JOB_CONTINUING;
+           job->rmtID = host;
        }
+#endif
        
        (void)Lst_AtEnd(jobs, (ClientData)job);
        nJobs += 1;
        if (nJobs == maxJobs) {
            jobFull = TRUE;
            if (DEBUG(JOB)) {
-               printf("Job queue is full.\n");
+               (void) fprintf(stdout, "Job queue is full.\n");
+               (void) fflush(stdout);
            }
        }
     } else if (job->flags & JOB_RESTART) {
@@ -1258,33 +1494,60 @@ JobRestart(job)
        char      *argv[4];
        
        JobMakeArgv(job, argv);
-       
+
        if (DEBUG(JOB)) {
-           printf("Restarting %s...", job->node->name);
+           (void) fprintf(stdout, "Restarting %s...", job->node->name);
+           (void) fflush(stdout);
        }
-       if (((nLocal >= maxLocal) && ! (job->flags & JOB_SPECIAL))) {
+#ifdef REMOTE
+       if ((job->node->type&OP_NOEXPORT) ||
+           (nLocal < maxLocal && runLocalFirst) 
+# ifdef RMT_NO_EXEC
+           || !Rmt_Export(shellPath, argv, job)
+# else
+           || !Rmt_Begin(shellPath, argv, job->node)
+# endif
+#endif
+       {
+           if (((nLocal >= maxLocal) && !(job->flags & JOB_SPECIAL))) {
                /*
                 * Can't be exported and not allowed to run locally -- put it
                 * back on the hold queue and mark the table full
                 */
                if (DEBUG(JOB)) {
-                   printf("holding\n");
+                   (void) fprintf(stdout, "holding\n");
+                   (void) fflush(stdout);
                }
                (void)Lst_AtFront(stoppedJobs, (ClientData)job);
                jobFull = TRUE;
                if (DEBUG(JOB)) {
-                   printf("Job queue is full.\n");
+                   (void) fprintf(stdout, "Job queue is full.\n");
+                   (void) fflush(stdout);
                }
                return;
-       } else {
+           } else {
                /*
                 * Job may be run locally.
                 */
                if (DEBUG(JOB)) {
-                   printf("running locally\n");
+                   (void) fprintf(stdout, "running locally\n");
+                   (void) fflush(stdout);
                }
                job->flags &= ~JOB_REMOTE;
+           }
+       }
+#ifdef REMOTE
+       else {
+           /*
+            * Can be exported. Hooray!
+            */
+           if (DEBUG(JOB)) {
+               (void) fprintf(stdout, "exporting\n");
+               (void) fflush(stdout);
+           }
+           job->flags |= JOB_REMOTE;
        }
+#endif
        JobExec(job, argv);
     } else {
        /*
@@ -1292,24 +1555,31 @@ JobRestart(job)
         * we don't know...
         */
        if (DEBUG(JOB)) {
-           printf("Resuming %s...", job->node->name);
+          (void) fprintf(stdout, "Resuming %s...", job->node->name);
+          (void) fflush(stdout);
        }
        if (((job->flags & JOB_REMOTE) ||
-            (nLocal < maxLocal) ||
-            (((job->flags & JOB_SPECIAL)) &&
-             (maxLocal == 0))) &&
-           (nJobs != maxJobs))
+           (nLocal < maxLocal) ||
+#ifdef REMOTE
+           (((job->flags & JOB_SPECIAL) &&
+             (job->node->type & OP_NOEXPORT)) &&
+            (maxLocal == 0))) &&
+#else
+           ((job->flags & JOB_SPECIAL) &&
+            (maxLocal == 0))) &&
+#endif
+          (nJobs != maxJobs))
        {
            /*
             * If the job is remote, it's ok to resume it as long as the
             * maximum concurrency won't be exceeded. If it's local and
-            * we haven't reached the local concurrency limit already (or the
+            * we haven't reached the local concurrency limit already(or the
             * job must be run locally and maxLocal is 0), it's also ok to
             * resume it.
             */
            Boolean error;
            extern int errno;
-           union wait status;
+           int status;
            
 #ifdef RMT_WANTS_SIGNALS
            if (job->flags & JOB_REMOTE) {
@@ -1324,19 +1594,20 @@ JobRestart(job)
                 * actually put the thing in the job table.
                 */
                job->flags |= JOB_CONTINUING;
-               status.w_termsig = SIGCONT;
-               JobFinish(job, status);
+               W_SETTERMSIG(&status, SIGCONT);
+               JobFinish(job, &status);
                
                job->flags &= ~(JOB_RESUME|JOB_CONTINUING);
                if (DEBUG(JOB)) {
-                   printf("done\n");
+                  (void) fprintf(stdout, "done\n");
+                  (void) fflush(stdout);
                }
            } else {
                Error("couldn't resume %s: %s",
                    job->node->name, strerror(errno));
-               status.w_status = 0;
-               status.w_retcode = 1;
-               JobFinish(job, status);
+               status = 0;
+               W_SETEXITSTATUS(&status, 1);
+               JobFinish(job, &status);
            }
        } else {
            /*
@@ -1344,12 +1615,14 @@ JobRestart(job)
             * place the job back on the list of stopped jobs.
             */
            if (DEBUG(JOB)) {
-               printf("table full\n");
+               (void) fprintf(stdout, "table full\n");
+               (void) fflush(stdout);
            }
-           (void)Lst_AtFront(stoppedJobs, (ClientData)job);
+           (void) Lst_AtFront(stoppedJobs, (ClientData)job);
            jobFull = TRUE;
            if (DEBUG(JOB)) {
-               printf("Job queue is full.\n");
+               (void) fprintf(stdout, "Job queue is full.\n");
+               (void) fflush(stdout);
            }
        }
     }
@@ -1372,7 +1645,7 @@ JobRestart(job)
  *-----------------------------------------------------------------------
  */
 static int
-JobStart (gn, flags, previous)
+JobStart(gn, flags, previous)
     GNode         *gn;       /* target to create */
     int                   flags;      /* flags for the job to override normal ones.
                               * e.g. JOB_SPECIAL or JOB_IGNDOTS */
@@ -1386,12 +1659,12 @@ JobStart (gn, flags, previous)
     Boolean      local;      /* Set true if the job was run locally */
     Boolean      noExec;     /* Set true if we decide not to run the job */
 
-    if (previous != (Job *)NULL) {
-       previous->flags &= ~ (JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
+    if (previous != NULL) {
+       previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
        job = previous;
     } else {
-       job = (Job *) emalloc (sizeof (Job));
-       if (job == (Job *)NULL) {
+       job = (Job *) emalloc(sizeof(Job));
+       if (job == NULL) {
            Punt("JobStart out of memory");
        }
        flags |= JOB_FIRST;
@@ -1406,10 +1679,10 @@ JobStart (gn, flags, previous)
      * are also added to the field.
      */
     job->flags = 0;
-    if (Targ_Ignore (gn)) {
+    if (Targ_Ignore(gn)) {
        job->flags |= JOB_IGNERR;
     }
-    if (Targ_Silent (gn)) {
+    if (Targ_Silent(gn)) {
        job->flags |= JOB_SILENT;
     }
     job->flags |= flags;
@@ -1418,14 +1691,14 @@ JobStart (gn, flags, previous)
      * Check the commands now so any attributes from .DEFAULT have a chance
      * to migrate to the node
      */
-    if (job->flags & JOB_FIRST) {
+    if (!compatMake && job->flags & JOB_FIRST) {
        cmdsOK = Job_CheckCommands(gn, Error);
     } else {
        cmdsOK = TRUE;
     }
     
     /*
-     * If the -n flag wasn't given, we open up OUR (not the child's)
+     * If the -n flag wasn't given, we open up OUR(not the child's)
      * temporary file to stuff commands in it. The thing is rd/wr so we don't
      * need to reopen it to feed it to the shell. If the -n flag *was* given,
      * we just set the file to be stdout. Cute, huh?
@@ -1439,11 +1712,11 @@ JobStart (gn, flags, previous)
            DieHorribly();
        }
        
-       job->cmdFILE = fopen (tfile, "w+");
-       if (job->cmdFILE == (FILE *) NULL) {
-           Punt ("Could not open %s", tfile);
+       job->cmdFILE = fopen(tfile, "w+");
+       if (job->cmdFILE == NULL) {
+           Punt("Could not open %s", tfile);
        }
-       fcntl(fileno(job->cmdFILE), F_SETFD, 1);
+       (void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
        /*
         * Send the commands to the command file, flush all its buffers then
         * rewind and remove the thing.
@@ -1466,13 +1739,14 @@ JobStart (gn, flags, previous)
            if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){
                cmdsOK = FALSE;
            } else {
-               LstNode ln = Lst_Next (gn->commands);
+               LstNode ln = Lst_Next(gn->commands);
                    
                if ((ln == NILLNODE) ||
-                   JobPrintCommand ((char *)Lst_Datum (ln), job))
+                   JobPrintCommand((ClientData) Lst_Datum(ln),
+                                   (ClientData) job))
                {
                    noExec = TRUE;
-                   Lst_Close (gn->commands);
+                   Lst_Close(gn->commands);
                }
                if (noExec && !(job->flags & JOB_FIRST)) {
                    /*
@@ -1486,21 +1760,7 @@ JobStart (gn, flags, previous)
                     * Job_CatchChildren b/c it wasn't clear if there were
                     * more commands to execute or not...
                     */
-                   if (usePipes) {
-#ifdef RMT_WILL_WATCH
-                       Rmt_Ignore(job->inPipe);
-#else
-                       FD_CLR(job->inPipe, &outputs);
-#endif
-                       if (job->outPipe != job->inPipe) {
-                           (void)close (job->outPipe);
-                       }
-                       JobDoOutput (job, TRUE);
-                       (void)close (job->inPipe);
-                   } else {
-                       (void)close (job->outFd);
-                       JobDoOutput (job, TRUE);
-                   }
+                   JobClose(job);
                }
            }
        } else {
@@ -1508,7 +1768,7 @@ JobStart (gn, flags, previous)
             * We can do all the commands at once. hooray for sanity
             */
            numCommands = 0;
-           Lst_ForEach (gn->commands, JobPrintCommand, (ClientData)job);
+           Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job);
            
            /*
             * If we didn't print out any commands to the shell script,
@@ -1524,7 +1784,7 @@ JobStart (gn, flags, previous)
         * in one fell swoop. This will still set up job->tailCmds correctly.
         */
        if (lastNode != gn) {
-           printf (targFmt, gn->name);
+           MESSAGE(stdout, gn);
            lastNode = gn;
        }
        job->cmdFILE = stdout;
@@ -1548,7 +1808,7 @@ JobStart (gn, flags, previous)
         * up the graph.
         */
        job->cmdFILE = stdout;
-       Job_Touch (gn, job->flags&JOB_SILENT);
+       Job_Touch(gn, job->flags&JOB_SILENT);
        noExec = TRUE;
     }
 
@@ -1560,10 +1820,11 @@ JobStart (gn, flags, previous)
         * Unlink and close the command file if we opened one
         */
        if (job->cmdFILE != stdout) {
-           (void) unlink (tfile);
-           fclose(job->cmdFILE);
+           (void) eunlink(tfile);
+           if (job->cmdFILE != NULL)
+               (void) fclose(job->cmdFILE);
        } else {
-           fflush (stdout);
+            (void) fflush(stdout);
        }
 
        /*
@@ -1575,7 +1836,7 @@ JobStart (gn, flags, previous)
                if (job->tailCmds != NILLNODE) {
                    Lst_ForEachFrom(job->node->commands, job->tailCmds,
                                    JobSaveCommand,
-                                   (ClientData)job->node);
+                                  (ClientData)job->node);
                }
                Make_Update(job->node);
            }
@@ -1586,8 +1847,8 @@ JobStart (gn, flags, previous)
            return(JOB_ERROR);
        }
     } else {
-       fflush (job->cmdFILE);
-       (void) unlink (tfile);
+       (void) fflush(job->cmdFILE);
+       (void) eunlink(tfile);
     }
 
     /*
@@ -1602,54 +1863,75 @@ JobStart (gn, flags, previous)
      * starting a job and then set up its temporary-file name. This is just
      * tfile with two extra digits tacked on -- jobno.
      */
-    if (job->flags & JOB_FIRST) {
+    if (!compatMake || (job->flags & JOB_FIRST)) {
        if (usePipes) {
            int fd[2];
-           (void) pipe(fd); 
+           if (pipe(fd) == -1)
+               Punt("Cannot create pipe: %s", strerror(errno));
            job->inPipe = fd[0];
            job->outPipe = fd[1];
-           (void)fcntl (job->inPipe, F_SETFD, 1);
-           (void)fcntl (job->outPipe, F_SETFD, 1);
+           (void) fcntl(job->inPipe, F_SETFD, 1);
+           (void) fcntl(job->outPipe, F_SETFD, 1);
        } else {
-           printf ("Remaking `%s'\n", gn->name);
-           fflush (stdout);
-           sprintf (job->outFile, "%s%02d", tfile, jobno);
+           (void) fprintf(stdout, "Remaking `%s'\n", gn->name);
+           (void) fflush(stdout);
+           sprintf(job->outFile, "%s%02d", tfile, jobno);
            jobno = (jobno + 1) % 100;
            job->outFd = open(job->outFile,O_WRONLY|O_CREAT|O_APPEND,0600);
-           (void)fcntl (job->outFd, F_SETFD, 1);
+           (void) fcntl(job->outFd, F_SETFD, 1);
        }
     }
 
-    local = TRUE;
+#ifdef REMOTE
+    if (!(gn->type & OP_NOEXPORT) && !(runLocalFirst && nLocal < maxLocal)) {
+#ifdef RMT_NO_EXEC
+       local = !Rmt_Export(shellPath, argv, job);
+#else
+       local = !Rmt_Begin(shellPath, argv, job->node);
+#endif /* RMT_NO_EXEC */
+       if (!local) {
+           job->flags |= JOB_REMOTE;
+       }
+    } else
+#endif
+       local = TRUE;
 
     if (local && (((nLocal >= maxLocal) &&
-        !(job->flags & JOB_SPECIAL) &&
-        (maxLocal != 0))))
+       !(job->flags & JOB_SPECIAL) &&
+#ifdef REMOTE
+       (!(gn->type & OP_NOEXPORT) || (maxLocal != 0))
+#else
+       (maxLocal != 0)
+#endif
+       )))
     {
        /*
         * The job can only be run locally, but we've hit the limit of
         * local concurrency, so put the job on hold until some other job
-        * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END)
+        * finishes. Note that the special jobs(.BEGIN, .INTERRUPT and .END)
         * may be run locally even when the local limit has been reached
-        * (e.g. when maxLocal == 0), though they will be exported if at
-        * all possible. 
+        *(e.g. when maxLocal == 0), though they will be exported if at
+        * all possible. In addition, any target marked with .NOEXPORT will
+        * be run locally if maxLocal is 0.
         */
        jobFull = TRUE;
        
        if (DEBUG(JOB)) {
-           printf("Can only run job locally.\n");
+          (void) fprintf(stdout, "Can only run job locally.\n");
+          (void) fflush(stdout);
        }
        job->flags |= JOB_RESTART;
-       (void)Lst_AtEnd(stoppedJobs, (ClientData)job);
+       (void) Lst_AtEnd(stoppedJobs, (ClientData)job);
     } else {
        if ((nLocal >= maxLocal) && local) {
            /*
-            * If we're running this job locally as a special case (see above),
+            * If we're running this job locally as a special case(see above),
             * at least say the table is full.
             */
            jobFull = TRUE;
            if (DEBUG(JOB)) {
-               printf("Local job queue is full.\n");
+               (void) fprintf(stdout, "Local job queue is full.\n");
+               (void) fflush(stdout);
            }
        }
        JobExec(job, argv);
@@ -1657,6 +1939,52 @@ JobStart (gn, flags, previous)
     return(JOB_RUNNING);
 }
 
+static char * 
+JobOutput(job, cp, endp, msg)
+    register Job *job;
+    register char *cp, *endp;
+    int msg;
+{
+    register char *ecp;
+
+    if (commandShell->noPrint) {
+       ecp = Str_FindSubstring(cp, commandShell->noPrint);
+       while (ecp != NULL) {
+           if (cp != ecp) {
+               *ecp = '\0';
+               if (msg && job->node != lastNode) {
+                   MESSAGE(stdout, job->node);
+                   lastNode = job->node;
+               }
+               /*
+                * The only way there wouldn't be a newline after
+                * this line is if it were the last in the buffer.
+                * however, since the non-printable comes after it,
+                * there must be a newline, so we don't print one.
+                */
+               (void) fprintf(stdout, "%s", cp);
+               (void) fflush(stdout);
+           }
+           cp = ecp + commandShell->noPLen;
+           if (cp != endp) {
+               /*
+                * Still more to print, look again after skipping
+                * the whitespace following the non-printable
+                * command....
+                */
+               cp++;
+               while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
+                   cp++;
+               }
+               ecp = Str_FindSubstring(cp, commandShell->noPrint);
+           } else {
+               return cp;
+           }
+       }
+    }
+    return cp;
+}
+
 /*-
  *-----------------------------------------------------------------------
  * JobDoOutput  --
@@ -1674,7 +2002,7 @@ JobStart (gn, flags, previous)
  *     In both cases, however, we keep our figurative eye out for the
  *     'noPrint' line for the shell from which the output came. If
  *     we recognize a line, we don't print it. If the command is not
- *     alone on the line (the character after it is not \0 or \n), we
+ *     alone on the line(the character after it is not \0 or \n), we
  *     do print whatever follows it.
  *
  * Results:
@@ -1684,17 +2012,18 @@ JobStart (gn, flags, previous)
  *     curPos may be shifted as may the contents of outBuf.
  *-----------------------------------------------------------------------
  */
-static void
-JobDoOutput (job, finish)
+STATIC void
+JobDoOutput(job, finish)
     register Job   *job;         /* the job whose output needs printing */
     Boolean       finish;        /* TRUE if this is the last time we'll be
                                   * called for this job */
 {
     Boolean       gotNL = FALSE;  /* true if got a newline */
+    Boolean       fbuf;          /* true if our buffer filled up */
     register int  nr;            /* number of bytes read */
     register int  i;             /* auxiliary index into outBuf */
-    register int  max;           /* limit for i (end of current data) */
-    int                  nRead;          /* (Temporary) number of bytes read */
+    register int  max;           /* limit for i(end of current data) */
+    int                  nRead;          /*(Temporary) number of bytes read */
 
     FILE         *oFILE;         /* Stream pointer to shell's output file */
     char          inLine[132];
@@ -1705,8 +2034,10 @@ JobDoOutput (job, finish)
         * Read as many bytes as will fit in the buffer.
         */
 end_loop:
+       gotNL = FALSE;
+       fbuf = FALSE;
        
-       nRead = read (job->inPipe, &job->outBuf[job->curPos],
+       nRead = read(job->inPipe, &job->outBuf[job->curPos],
                         JOB_BUFSIZE - job->curPos);
        if (nRead < 0) {
            if (DEBUG(JOB)) {
@@ -1718,7 +2049,7 @@ end_loop:
        }
 
        /*
-        * If we hit the end-of-file (the job is dead), we must flush its
+        * If we hit the end-of-file(the job is dead), we must flush its
         * remaining output, so pretend we read a newline if there's any
         * output remaining in the buffer.
         * Also clear the 'finish' flag so we stop looping.
@@ -1756,15 +2087,15 @@ end_loop:
                 * If we've run out of buffer space, we have no choice
                 * but to print the stuff. sigh. 
                 */
-               gotNL = TRUE;
+               fbuf = TRUE;
                i = job->curPos;
            }
        }
-       if (gotNL) {
+       if (gotNL || fbuf) {
            /*
             * Need to send the output to the screen. Null terminate it
             * first, overwriting the newline character if there was one.
-            * So long as the line isn't one we should filter (according
+            * So long as the line isn't one we should filter(according
             * to the shell description), we print the line, preceeded
             * by a target banner if this target isn't the same as the
             * one for which we last printed something.
@@ -1773,45 +2104,9 @@ end_loop:
             */
            job->outBuf[i] = '\0';
            if (i >= job->curPos) {
-               register char   *cp, *ecp;
-
-               cp = job->outBuf;
-               if (commandShell->noPrint) {
-                   ecp = Str_FindSubstring(job->outBuf,
-                                           commandShell->noPrint);
-                   while (ecp != (char *)NULL) {
-                       if (cp != ecp) {
-                           *ecp = '\0';
-                           if (job->node != lastNode) {
-                               printf (targFmt, job->node->name);
-                               lastNode = job->node;
-                           }
-                           /*
-                            * The only way there wouldn't be a newline after
-                            * this line is if it were the last in the buffer.
-                            * however, since the non-printable comes after it,
-                            * there must be a newline, so we don't print one.
-                            */
-                           printf ("%s", cp);
-                       }
-                       cp = ecp + commandShell->noPLen;
-                       if (cp != &job->outBuf[i]) {
-                           /*
-                            * Still more to print, look again after skipping
-                            * the whitespace following the non-printable
-                            * command....
-                            */
-                           cp++;
-                           while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
-                               cp++;
-                           }
-                           ecp = Str_FindSubstring (cp,
-                                                    commandShell->noPrint);
-                       } else {
-                           break;
-                       }
-                   }
-               }
+               char *cp;
+  
+               cp = JobOutput(job, job->outBuf, &job->outBuf[i]);
 
                /*
                 * There's still more in that thar buffer. This time, though,
@@ -1820,18 +2115,17 @@ end_loop:
                 */
                if (*cp != '\0') {
                    if (job->node != lastNode) {
-                       printf (targFmt, job->node->name);
+                       MESSAGE(stdout, job->node);
                        lastNode = job->node;
                    }
-                   printf ("%s\n", cp);
+                   (void) fprintf(stdout, "%s%s", cp, gotNL ? "\n" : "");
+                   (void) fflush(stdout);
                }
-
-               fflush (stdout);
            }
            if (i < max - 1) {
                /* shift the remaining characters down */
-               memcpy ( job->outBuf, &job->outBuf[i + 1], max - (i + 1));
-               job->curPos = max - (i + 1);
+               (void) memcpy(job->outBuf, &job->outBuf[i + 1], max -(i + 1));
+               job->curPos = max -(i + 1);
                
            } else {
                /*
@@ -1845,7 +2139,7 @@ end_loop:
            /*
             * If the finish flag is true, we must loop until we hit
             * end-of-file on the pipe. This is guaranteed to happen eventually
-            * since the other end of the pipe is now closed (we closed it
+            * since the other end of the pipe is now closed(we closed it
             * explicitly and the child has exited). When we do get an EOF,
             * finish will be set FALSE and we'll fall through and out.
             */
@@ -1862,62 +2156,36 @@ end_loop:
         * Change to read in blocks and do FindSubString type things as for
         * pipes? That would allow for "@echo -n..."
         */
-       oFILE = fopen (job->outFile, "r");
-       if (oFILE != (FILE *) NULL) {
-           printf ("Results of making %s:\n", job->node->name);
-           while (fgets (inLine, sizeof(inLine), oFILE) != NULL) {
-               register char   *cp, *ecp, *endp;
+       oFILE = fopen(job->outFile, "r");
+       if (oFILE != NULL) {
+           (void) fprintf(stdout, "Results of making %s:\n", job->node->name);
+           (void) fflush(stdout);
+           while (fgets(inLine, sizeof(inLine), oFILE) != NULL) {
+               register char   *cp, *endp, *oendp;
 
                cp = inLine;
-               endp = inLine + strlen(inLine);
+               oendp = endp = inLine + strlen(inLine);
                if (endp[-1] == '\n') {
                    *--endp = '\0';
                }
-               if (commandShell->noPrint) {
-                   ecp = Str_FindSubstring(cp, commandShell->noPrint);
-                   while (ecp != (char *)NULL) {
-                       if (cp != ecp) {
-                           *ecp = '\0';
-                           /*
-                            * The only way there wouldn't be a newline after
-                            * this line is if it were the last in the buffer.
-                            * however, since the non-printable comes after it,
-                            * there must be a newline, so we don't print one.
-                            */
-                           printf ("%s", cp);
-                       }
-                       cp = ecp + commandShell->noPLen;
-                       if (cp != endp) {
-                           /*
-                            * Still more to print, look again after skipping
-                            * the whitespace following the non-printable
-                            * command....
-                            */
-                           cp++;
-                           while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
-                               cp++;
-                           }
-                           ecp = Str_FindSubstring(cp, commandShell->noPrint);
-                       } else {
-                           break;
-                       }
-                   }
-               }
+               cp = JobOutput(job, inLine, endp, FALSE);
 
                /*
                 * There's still more in that thar buffer. This time, though,
                 * we know there's no newline at the end, so we add one of
                 * our own free will.
                 */
-               if (*cp != '\0') {
-                   printf ("%s\n", cp);
+               (void) fprintf(stdout, "%s", cp);
+               (void) fflush(stdout);
+               if (endp != oendp) {
+                   (void) fprintf(stdout, "\n");
+                   (void) fflush(stdout);
                }
            }
-           fclose (oFILE);
-           (void) unlink (job->outFile);
+           (void) fclose(oFILE);
+           (void) eunlink(job->outFile);
        }
     }
-    fflush(stdout);
 }
 
 /*-
@@ -1940,13 +2208,13 @@ end_loop:
  *-----------------------------------------------------------------------
  */
 void
-Job_CatchChildren (block)
+Job_CatchChildren(block)
     Boolean      block;        /* TRUE if should block on the wait. */
 {
     int          pid;          /* pid of dead child */
     register Job  *job;                /* job descriptor for dead child */
     LstNode       jnode;       /* list element for finding job */
-    union wait   status;       /* Exit/termination status */
+    int                  status;       /* Exit/termination status */
 
     /*
      * Don't even bother if we know there's no one around.
@@ -1955,40 +2223,54 @@ Job_CatchChildren (block)
        return;
     }
     
-    while ((pid = wait3((int *)&status, (block?0:WNOHANG)|WUNTRACED,
-                       (struct rusage *)0)) > 0)
+    while ((pid = waitpid((pid_t) -1, &status,
+                         (block?0:WNOHANG)|WUNTRACED)) > 0)
     {
-       if (DEBUG(JOB))
-           printf("Process %d exited or stopped.\n", pid);
+       if (DEBUG(JOB)) {
+           (void) fprintf(stdout, "Process %d exited or stopped.\n", pid);
+           (void) fflush(stdout);
+       }
            
 
-       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 (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) {
                jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid);
                if (jnode == NILLNODE) {
-                   Error("Resumed child (%d) not in table", pid);
+                   Error("Resumed child(%d) not in table", pid);
                    continue;
                }
                job = (Job *)Lst_Datum(jnode);
-               (void)Lst_Remove(stoppedJobs, jnode);
+               (void) Lst_Remove(stoppedJobs, jnode);
            } else {
-               Error ("Child (%d) not in table?", pid);
+               Error("Child(%d) not in table?", pid);
                continue;
            }
        } else {
-           job = (Job *) Lst_Datum (jnode);
-           (void)Lst_Remove (jobs, jnode);
+           job = (Job *) Lst_Datum(jnode);
+           (void) Lst_Remove(jobs, jnode);
            nJobs -= 1;
            if (jobFull && DEBUG(JOB)) {
-               printf("Job queue is no longer full.\n");
+               (void) fprintf(stdout, "Job queue is no longer full.\n");
+               (void) fflush(stdout);
            }
            jobFull = FALSE;
+#ifdef REMOTE
+           if (!(job->flags & JOB_REMOTE)) {
+               if (DEBUG(JOB)) {
+                   (void) fprintf(stdout,
+                                  "Job queue has one fewer local process.\n");
+                   (void) fflush(stdout);
+               }
+               nLocal -= 1;
+           }
+#else
            nLocal -= 1;
+#endif
        }
 
-       JobFinish (job, status);
+       JobFinish(job, &status);
     }
 }
 
@@ -1997,7 +2279,7 @@ Job_CatchChildren (block)
  * Job_CatchOutput --
  *     Catch the output from our children, if we're using
  *     pipes do so. Otherwise just block time until we get a
- *     signal (most likely a SIGCHLD) since there's no point in
+ *     signal(most likely a SIGCHLD) since there's no point in
  *     just spinning when there's nothing to do and the reaping
  *     of a child can wait for a while. 
  *
@@ -2009,7 +2291,7 @@ Job_CatchChildren (block)
  * -----------------------------------------------------------------------
  */
 void
-Job_CatchOutput ()
+Job_CatchOutput()
 {
     int                  nfds;
     struct timeval       timeout;
@@ -2020,7 +2302,7 @@ Job_CatchOutput ()
     int                          pnJobs;       /* Previous nJobs */
 #endif
 
-    fflush(stdout);
+    (void) fflush(stdout);
 #ifdef RMT_WILL_WATCH
     pnJobs = nJobs;
 
@@ -2037,7 +2319,7 @@ Job_CatchOutput ()
      * NOTE: IT IS THE RESPONSIBILITY OF Rmt_Wait TO CALL Job_CatchChildren
      * IN A TIMELY FASHION TO CATCH ANY LOCALLY RUNNING JOBS THAT EXIT.
      * It may use the variable nLocal to determine if it needs to call
-     * Job_CatchChildren (if nLocal is 0, there's nothing for which to
+     * Job_CatchChildren(if nLocal is 0, there's nothing for which to
      * wait...)
      */
     while (nJobs != 0 && pnJobs == nJobs) {
@@ -2049,21 +2331,21 @@ Job_CatchOutput ()
        timeout.tv_sec = SEL_SEC;
        timeout.tv_usec = SEL_USEC;
 
-       if ((nfds = select (FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0)
-       {
+       if ((nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0,
+                          (fd_set *) 0, &timeout)) <= 0)
            return;
-       else {
-           if (Lst_Open (jobs) == FAILURE) {
-               Punt ("Cannot open job table");
+       else {
+           if (Lst_Open(jobs) == FAILURE) {
+               Punt("Cannot open job table");
            }
-           while (nfds && (ln = Lst_Next (jobs)) != NILLNODE) {
-               job = (Job *) Lst_Datum (ln);
+           while (nfds && (ln = Lst_Next(jobs)) != NILLNODE) {
+               job = (Job *) Lst_Datum(ln);
                if (FD_ISSET(job->inPipe, &readfds)) {
-                   JobDoOutput (job, FALSE);
+                   JobDoOutput(job, FALSE);
                    nfds -= 1;
                }
            }
-           Lst_Close (jobs);
+           Lst_Close(jobs);
        }
     }
 #endif /* RMT_WILL_WATCH */
@@ -2084,10 +2366,10 @@ Job_CatchOutput ()
  *-----------------------------------------------------------------------
  */
 void
-Job_Make (gn)
+Job_Make(gn)
     GNode   *gn;
 {
-    (void)JobStart (gn, 0, (Job *)NULL);
+    (void) JobStart(gn, 0, NULL);
 }
 
 /*-
@@ -2103,7 +2385,7 @@ Job_Make (gn)
  *-----------------------------------------------------------------------
  */
 void
-Job_Init (maxproc, maxlocal)
+Job_Init(maxproc, maxlocal)
     int           maxproc;  /* the greatest number of jobs which may be
                             * running at one time */
     int                  maxlocal; /* the greatest number of local jobs which may
@@ -2111,9 +2393,9 @@ Job_Init (maxproc, maxlocal)
 {
     GNode         *begin;     /* node for commands to do at the very start */
 
-    sprintf (tfile, "/tmp/make%05d", getpid());
+    (void) sprintf(tfile, "/tmp/make%05d", getpid());
 
-    jobs =       Lst_Init (FALSE);
+    jobs =       Lst_Init(FALSE);
     stoppedJobs = Lst_Init(FALSE);
     maxJobs =    maxproc;
     maxLocal =           maxlocal;
@@ -2126,7 +2408,11 @@ Job_Init (maxproc, maxlocal)
 
     lastNode =   NILGNODE;
 
-    if (maxJobs == 1) {
+    if (maxJobs == 1
+#ifdef REMOTE
+       || noMessages
+#endif
+                    ) {
        /*
         * If only one job can run at a time, there's no need for a banner,
         * no is there?
@@ -2136,7 +2422,7 @@ Job_Init (maxproc, maxlocal)
        targFmt = TARG_FMT;
     }
     
-    if (shellPath == (char *) NULL) {
+    if (shellPath == NULL) {
        /*
         * The user didn't specify a shell to use, so we are using the
         * default one... Both the absolute path and the last component
@@ -2145,13 +2431,13 @@ Job_Init (maxproc, maxlocal)
         * All default shells are located in _PATH_DEFSHELLDIR.
         */
        shellName = commandShell->name;
-       shellPath = str_concat (_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
+       shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
     }
 
-    if (commandShell->exit == (char *)NULL) {
+    if (commandShell->exit == NULL) {
        commandShell->exit = "";
     }
-    if (commandShell->echo == (char *)NULL) {
+    if (commandShell->echo == NULL) {
        commandShell->echo = "";
     }
 
@@ -2159,51 +2445,51 @@ Job_Init (maxproc, maxlocal)
      * Catch the four signals that POSIX specifies if they aren't ignored.
      * JobPassSig will take care of calling JobInterrupt if appropriate.
      */
-    if (signal (SIGINT, SIG_IGN) != SIG_IGN) {
-       signal (SIGINT, JobPassSig);
+    if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGINT, JobPassSig);
     }
-    if (signal (SIGHUP, SIG_IGN) != SIG_IGN) {
-       signal (SIGHUP, JobPassSig);
+    if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGHUP, JobPassSig);
     }
-    if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) {
-       signal (SIGQUIT, JobPassSig);
+    if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGQUIT, JobPassSig);
     }
-    if (signal (SIGTERM, SIG_IGN) != SIG_IGN) {
-       signal (SIGTERM, JobPassSig);
+    if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGTERM, JobPassSig);
     }
     /*
      * There are additional signals that need to be caught and passed if
      * either the export system wants to be told directly of signals or if
-     * we're giving each job its own process group (since then it won't get
+     * we're giving each job its own process group(since then it won't get
      * signals from the terminal driver as we own the terminal)
      */
 #if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP)
-    if (signal (SIGTSTP, SIG_IGN) != SIG_IGN) {
-       signal (SIGTSTP, JobPassSig);
+    if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGTSTP, JobPassSig);
     }
-    if (signal (SIGTTOU, SIG_IGN) != SIG_IGN) {
-       signal (SIGTTOU, JobPassSig);
+    if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGTTOU, JobPassSig);
     }
-    if (signal (SIGTTIN, SIG_IGN) != SIG_IGN) {
-       signal (SIGTTIN, JobPassSig);
+    if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGTTIN, JobPassSig);
     }
-    if (signal (SIGWINCH, SIG_IGN) != SIG_IGN) {
-       signal (SIGWINCH, JobPassSig);
+    if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) {
+       (void) signal(SIGWINCH, JobPassSig);
     }
 #endif
     
-    begin = Targ_FindNode (".BEGIN", TARG_NOCREATE);
+    begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
 
     if (begin != NILGNODE) {
-       JobStart (begin, JOB_SPECIAL, (Job *)0);
+       JobStart(begin, JOB_SPECIAL, (Job *)0);
        while (nJobs) {
            Job_CatchOutput();
 #ifndef RMT_WILL_WATCH
-           Job_CatchChildren (!usePipes);
+           Job_CatchChildren(!usePipes);
 #endif /* RMT_WILL_WATCH */
        }
     }
-    postCommands = Targ_FindNode (".END", TARG_CREATE);
+    postCommands = Targ_FindNode(".END", TARG_CREATE);
 }
 
 /*-
@@ -2221,9 +2507,9 @@ Job_Init (maxproc, maxlocal)
  *-----------------------------------------------------------------------
  */
 Boolean
-Job_Full ()
+Job_Full()
 {
-    return (aborting || jobFull);
+    return(aborting || jobFull);
 }
 
 /*-
@@ -2243,7 +2529,7 @@ Job_Full ()
  * -----------------------------------------------------------------------
  */
 Boolean
-Job_Empty ()
+Job_Empty()
 {
     if (nJobs == 0) {
        if (!Lst_IsEmpty(stoppedJobs) && !aborting) {
@@ -2252,9 +2538,7 @@ Job_Empty ()
             * it...Try and restart the stopped jobs.
             */
            jobFull = FALSE;
-           while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
-               JobRestart((Job *)Lst_DeQueue(stoppedJobs));
-           }
+           JobRestartJobs();
            return(FALSE);
        } else {
            return(TRUE);
@@ -2278,7 +2562,7 @@ Job_Empty ()
  *-----------------------------------------------------------------------
  */
 static Shell *
-JobMatchShell (name)
+JobMatchShell(name)
     char         *name;      /* Final component of shell path */
 {
     register Shell *sh;              /* Pointer into shells table */
@@ -2287,24 +2571,23 @@ JobMatchShell (name)
                  *cp2;
     char         *eoname;
 
-    eoname = name + strlen (name);
+    eoname = name + strlen(name);
 
-    match = (Shell *) NULL;
+    match = NULL;
 
     for (sh = shells; sh->name != NULL; sh++) {
-       for (cp1 = eoname - strlen (sh->name), cp2 = sh->name;
+       for (cp1 = eoname - strlen(sh->name), cp2 = sh->name;
             *cp1 != '\0' && *cp1 == *cp2;
             cp1++, cp2++) {
                 continue;
        }
        if (*cp1 != *cp2) {
            continue;
-       } else if (match == (Shell *) NULL ||
-                  strlen (match->name) < strlen (sh->name)) {
-                      match = sh;
+       } else if (match == NULL || strlen(match->name) < strlen(sh->name)) {
+          match = sh;
        }
     }
-    return (match == (Shell *) NULL ? sh : match);
+    return(match == NULL ? sh : match);
 }
 
 /*-
@@ -2351,7 +2634,7 @@ JobMatchShell (name)
  *-----------------------------------------------------------------------
  */
 ReturnStatus
-Job_ParseShell (line)
+Job_ParseShell(line)
     char         *line;  /* The shell spec */
 {
     char         **words;
@@ -2362,88 +2645,88 @@ Job_ParseShell (line)
     Shell        newShell;
     Boolean      fullSpec = FALSE;
 
-    while (isspace (*line)) {
+    while (isspace(*line)) {
        line++;
     }
-    words = brk_string (line, &wordCount, TRUE);
+    words = brk_string(line, &wordCount, TRUE);
 
-    memset ((Address)&newShell, 0, sizeof(newShell));
+    memset((Address)&newShell, 0, sizeof(newShell));
     
     /*
      * Parse the specification by keyword
      */
-    for (path = (char *)NULL, argc = wordCount - 1, argv = words + 1;
+    for (path = NULL, argc = wordCount - 1, argv = words + 1;
         argc != 0;
         argc--, argv++) {
-            if (strncmp (*argv, "path=", 5) == 0) {
+            if (strncmp(*argv, "path=", 5) == 0) {
                 path = &argv[0][5];
-            } else if (strncmp (*argv, "name=", 5) == 0) {
+            } else if (strncmp(*argv, "name=", 5) == 0) {
                 newShell.name = &argv[0][5];
             } else {
-                if (strncmp (*argv, "quiet=", 6) == 0) {
+                if (strncmp(*argv, "quiet=", 6) == 0) {
                     newShell.echoOff = &argv[0][6];
-                } else if (strncmp (*argv, "echo=", 5) == 0) {
+                } else if (strncmp(*argv, "echo=", 5) == 0) {
                     newShell.echoOn = &argv[0][5];
-                } else if (strncmp (*argv, "filter=", 7) == 0) {
+                } else if (strncmp(*argv, "filter=", 7) == 0) {
                     newShell.noPrint = &argv[0][7];
                     newShell.noPLen = strlen(newShell.noPrint);
-                } else if (strncmp (*argv, "echoFlag=", 9) == 0) {
+                } else if (strncmp(*argv, "echoFlag=", 9) == 0) {
                     newShell.echo = &argv[0][9];
-                } else if (strncmp (*argv, "errFlag=", 8) == 0) {
+                } else if (strncmp(*argv, "errFlag=", 8) == 0) {
                     newShell.exit = &argv[0][8];
-                } else if (strncmp (*argv, "hasErrCtl=", 10) == 0) {
+                } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) {
                     char c = argv[0][10];
                     newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
-                                           (c != 'T') && (c != 't'));
-                } else if (strncmp (*argv, "check=", 6) == 0) {
+                                          (c != 'T') && (c != 't'));
+                } else if (strncmp(*argv, "check=", 6) == 0) {
                     newShell.errCheck = &argv[0][6];
-                } else if (strncmp (*argv, "ignore=", 7) == 0) {
+                } else if (strncmp(*argv, "ignore=", 7) == 0) {
                     newShell.ignErr = &argv[0][7];
                 } else {
-                    Parse_Error (PARSE_FATAL, "Unknown keyword \"%s\"",
+                    Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
                                  *argv);
-                    return (FAILURE);
+                    return(FAILURE);
                 }
                 fullSpec = TRUE;
             }
     }
 
-    if (path == (char *)NULL) {
+    if (path == NULL) {
        /*
         * If no path was given, the user wants one of the pre-defined shells,
         * yes? So we find the one s/he wants with the help of JobMatchShell
         * and set things up the right way. shellPath will be set up by
         * Job_Init.
         */
-       if (newShell.name == (char *)NULL) {
-           Parse_Error (PARSE_FATAL, "Neither path nor name specified");
-           return (FAILURE);
+       if (newShell.name == NULL) {
+           Parse_Error(PARSE_FATAL, "Neither path nor name specified");
+           return(FAILURE);
        } else {
-           commandShell = JobMatchShell (newShell.name);
+           commandShell = JobMatchShell(newShell.name);
            shellName = newShell.name;
        }
     } else {
        /*
-        * The user provided a path. If s/he gave nothing else (fullSpec is
+        * The user provided a path. If s/he gave nothing else(fullSpec is
         * FALSE), try and find a matching shell in the ones we know of.
         * Else we just take the specification at its word and copy it
         * to a new location. In either case, we need to record the
         * path the user gave for the shell.
         */
        shellPath = path;
-       path = strrchr (path, '/');
-       if (path == (char *)NULL) {
+       path = strrchr(path, '/');
+       if (path == NULL) {
            path = shellPath;
        } else {
            path += 1;
        }
-       if (newShell.name != (char *)NULL) {
+       if (newShell.name != NULL) {
            shellName = newShell.name;
        } else {
            shellName = path;
        }
        if (!fullSpec) {
-           commandShell = JobMatchShell (shellName);
+           commandShell = JobMatchShell(shellName);
        } else {
            commandShell = (Shell *) emalloc(sizeof(Shell));
            *commandShell = newShell;
@@ -2455,10 +2738,10 @@ Job_ParseShell (line)
     }
     
     if (!commandShell->hasErrCtl) {
-       if (commandShell->errCheck == (char *)NULL) {
+       if (commandShell->errCheck == NULL) {
            commandShell->errCheck = "";
        }
-       if (commandShell->ignErr == (char *)NULL) {
+       if (commandShell->ignErr == NULL) {
            commandShell->ignErr = "%s\n";
        }
     }
@@ -2467,7 +2750,7 @@ Job_ParseShell (line)
      * Do not free up the words themselves, since they might be in use by the
      * shell specification...
      */
-    free (words);
+    free(words);
     return SUCCESS;
 }
 
@@ -2485,9 +2768,10 @@ Job_ParseShell (line)
  *-----------------------------------------------------------------------
  */
 static void
-JobInterrupt (runINTERRUPT)
+JobInterrupt(runINTERRUPT, signo)
     int            runINTERRUPT;       /* Non-zero if commands for the .INTERRUPT
                                 * target should be executed */
+    int            signo;              /* signal received */
 {
     LstNode      ln;           /* element in job table */
     Job           *job;                /* job descriptor in that element */
@@ -2495,18 +2779,16 @@ JobInterrupt (runINTERRUPT)
     
     aborting = ABORT_INTERRUPT;
 
-    (void)Lst_Open (jobs);
-    while ((ln = Lst_Next (jobs)) != NILLNODE) {
-       job = (Job *) Lst_Datum (ln);
+   (void) Lst_Open(jobs);
+    while ((ln = Lst_Next(jobs)) != NILLNODE) {
+       job = (Job *) Lst_Datum(ln);
 
-       if (!Targ_Precious (job->node)) {
-           char        *file = (job->node->path == (char *)NULL ?
+       if (!Targ_Precious(job->node)) {
+           char        *file = (job->node->path == NULL ?
                                 job->node->name :
                                 job->node->path);
-           struct stat st;
-           if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) && 
-               unlink(file) != -1) {
-               Error ("*** %s removed", file);
+           if (!noExecute && eunlink(file) != -1) {
+               Error("*** %s removed", file);
            }
        }
 #ifdef RMT_WANTS_SIGNALS
@@ -2514,44 +2796,110 @@ JobInterrupt (runINTERRUPT)
            /*
             * If job is remote, let the Rmt module do the killing.
             */
-           if (!Rmt_Signal(job, SIGINT)) {
+           if (!Rmt_Signal(job, signo)) {
                /*
                 * If couldn't kill the thing, finish it out now with an
                 * error code, since no exit report will come in likely.
                 */
-               union wait status;
+               int status;
 
                status.w_status = 0;
                status.w_retcode = 1;
-               JobFinish(job, status);
+               JobFinish(job, &status);
            }
        } else if (job->pid) {
-           KILL(job->pid, SIGINT);
+           KILL(job->pid, signo);
        }
 #else
        if (job->pid) {
+           if (DEBUG(JOB)) {
+               (void) fprintf(stdout,
+                              "JobInterrupt passing signal to child %d.\n", 
+                              job->pid);
+               (void) fflush(stdout);
+           }
+           KILL(job->pid, signo);
+       }
+#endif /* RMT_WANTS_SIGNALS */
+    }
+
+#ifdef REMOTE
+   (void)Lst_Open(stoppedJobs);
+    while ((ln = Lst_Next(stoppedJobs)) != NILLNODE) {
+       job = (Job *) Lst_Datum(ln);
+
+       if (job->flags & JOB_RESTART) {
+           if (DEBUG(JOB)) {
+               (void) fprintf(stdout, "%s%s",
+                              "JobInterrupt skipping job on stopped queue",
+                              "-- it was waiting to be restarted.\n");
+               (void) fflush(stdout);
+           }
+           continue;
+       }
+       if (!Targ_Precious(job->node)) {
+           char        *file = (job->node->path == NULL ?
+                                job->node->name :
+                                job->node->path);
+           if (eunlink(file) == 0) {
+               Error("*** %s removed", file);
+           }
+       }
+       /*
+        * Resume the thing so it will take the signal.
+        */
+       if (DEBUG(JOB)) {
+           (void) fprintf(stdout,
+                          "JobInterrupt passing CONT to stopped child %d.\n", 
+                          job->pid);
+           (void) fflush(stdout);
+       }
+       KILL(job->pid, SIGCONT);
+#ifdef RMT_WANTS_SIGNALS
+       if (job->flags & JOB_REMOTE) {
+           /*
+            * If job is remote, let the Rmt module do the killing.
+            */
+           if (!Rmt_Signal(job, SIGINT)) {
+               /*
+                * If couldn't kill the thing, finish it out now with an
+                * error code, since no exit report will come in likely.
+                */
+               int status;
+               status.w_status = 0;
+               status.w_retcode = 1;
+               JobFinish(job, &status);
+           }
+       } else if (job->pid) {
+           if (DEBUG(JOB)) {
+               (void) fprintf(stdout,
+                      "JobInterrupt passing interrupt to stopped child %d.\n",
+                              job->pid);
+               (void) fflush(stdout);
+           }
            KILL(job->pid, SIGINT);
        }
 #endif /* RMT_WANTS_SIGNALS */
     }
-    Lst_Close (jobs);
+#endif
+    Lst_Close(stoppedJobs);
 
     if (runINTERRUPT && !touchFlag) {
-       interrupt = Targ_FindNode (".INTERRUPT", TARG_NOCREATE);
+       interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
        if (interrupt != NILGNODE) {
            ignoreErrors = FALSE;
 
-           JobStart (interrupt, JOB_IGNDOTS, (Job *)0);
+           JobStart(interrupt, JOB_IGNDOTS, (Job *)0);
            while (nJobs) {
                Job_CatchOutput();
 #ifndef RMT_WILL_WATCH
-               Job_CatchChildren (!usePipes);
+               Job_CatchChildren(!usePipes);
 #endif /* RMT_WILL_WATCH */
            }
        }
     }
-    (void) unlink (tfile);
-    exit (0);
+    (void) eunlink(tfile);
+    exit(signo);
 }
 
 /*
@@ -2564,29 +2912,28 @@ JobInterrupt (runINTERRUPT)
  *     Number of errors reported.
  *
  * Side Effects:
- *     The process' temporary file (tfile) is removed if it still
+ *     The process' temporary file(tfile) is removed if it still
  *     existed.
  *-----------------------------------------------------------------------
  */
 int
-Job_End ()
+Job_End()
 {
-    if (postCommands != NILGNODE && !Lst_IsEmpty (postCommands->commands)) {
+    if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) {
        if (errors) {
-           Error ("Errors reported so .END ignored");
+           Error("Errors reported so .END ignored");
        } else {
-           JobStart (postCommands, JOB_SPECIAL | JOB_IGNDOTS,
-                      (Job *)0);
+           JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL);
 
            while (nJobs) {
                Job_CatchOutput();
 #ifndef RMT_WILL_WATCH
-               Job_CatchChildren (!usePipes);
+               Job_CatchChildren(!usePipes);
 #endif /* RMT_WILL_WATCH */
            }
        }
     }
-    (void) unlink (tfile);
+    (void) eunlink(tfile);
     return(errors);
 }
 
@@ -2632,9 +2979,9 @@ Job_Wait()
  *-----------------------------------------------------------------------
  */
 void
-Job_AbortAll ()
+Job_AbortAll()
 {
-    LstNode            ln;             /* element in job table */
+    LstNode            ln;     /* element in job table */
     Job                *job;   /* the job descriptor in that element */
     int                foo;
     
@@ -2642,9 +2989,9 @@ Job_AbortAll ()
     
     if (nJobs) {
 
-       (void)Lst_Open (jobs);
-       while ((ln = Lst_Next (jobs)) != NILLNODE) {
-           job = (Job *) Lst_Datum (ln);
+       (void) Lst_Open(jobs);
+       while ((ln = Lst_Next(jobs)) != NILLNODE) {
+           job = (Job *) Lst_Datum(ln);
 
            /*
             * kill the child process with increasingly drastic signals to make
@@ -2668,7 +3015,88 @@ Job_AbortAll ()
     /*
      * Catch as many children as want to report in at first, then give up
      */
-    while (wait3(&foo, WNOHANG, (struct rusage *)0) > 0)
+    while (waitpid((pid_t) -1, &foo, WNOHANG) > 0)
        continue;
-    (void) unlink (tfile);
+    (void) eunlink(tfile);
+}
+
+#ifdef REMOTE
+/*-
+ *-----------------------------------------------------------------------
+ * JobFlagForMigration --
+ *     Handle the eviction of a child. Called from RmtStatusChange.
+ *     Flags the child as remigratable and then suspends it.
+ *
+ * Results:
+ *     none.
+ *
+ * Side Effects:
+ *     The job descriptor is flagged for remigration.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+JobFlagForMigration(hostID)
+    int          hostID;       /* ID of host we used, for matching children. */
+{
+    register Job  *job;                /* job descriptor for dead child */
+    LstNode       jnode;       /* list element for finding job */
+
+    if (DEBUG(JOB)) {
+       (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID);
+       (void) fflush(stdout);
+    }
+    jnode = Lst_Find(jobs, (ClientData)hostID, JobCmpRmtID);
+
+    if (jnode == NILLNODE) {
+       jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID);
+               if (jnode == NILLNODE) {
+                   if (DEBUG(JOB)) {
+                       Error("Evicting host(%d) not in table", hostID);
+                   }
+                   return;
+               }
+    }
+    job = (Job *) Lst_Datum(jnode);
+
+    if (DEBUG(JOB)) {
+       (void) fprintf(stdout,
+                      "JobFlagForMigration(%d) found job '%s'.\n", hostID,
+                      job->node->name);
+       (void) fflush(stdout);
+    }
+
+    KILL(job->pid, SIGSTOP);
+
+    job->flags |= JOB_REMIGRATE;
+}
+
+#endif
+\f
+/*-
+ *-----------------------------------------------------------------------
+ * JobRestartJobs --
+ *     Tries to restart stopped jobs if there are slots available.
+ *     Note that this tries to restart them regardless of pending errors.
+ *     It's not good to leave stopped jobs lying around!
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     Resumes(and possibly migrates) jobs.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobRestartJobs()
+{
+    while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
+       if (DEBUG(JOB)) {
+           (void) fprintf(stdout,
+                      "Job queue is not full. Restarting a stopped job.\n");
+           (void) fflush(stdout);
+       }
+       JobRestart((Job *)Lst_DeQueue(stoppedJobs));
+    }
 }
index 8abd47f..72da78e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: lstInt.h,v 1.4 1995/06/14 15:21:23 christos Exp $      */
+/*     $NetBSD: lstInt.h,v 1.6 1995/11/10 21:27:27 cgd Exp $   */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -45,6 +45,7 @@
 #ifndef _LSTINT_H_
 #define _LSTINT_H_
 
+#include         "make.h"
 #include         "lst.h"
 
 typedef struct ListNode {
@@ -89,7 +90,7 @@ typedef struct        {
  * PAlloc (var, ptype) --
  *     Allocate a pointer-typedef structure 'ptype' into the variable 'var'
  */
-#define        PAlloc(var,ptype)       var = (ptype) malloc (sizeof (*var))
+#define        PAlloc(var,ptype)       var = (ptype) emalloc (sizeof (*var))
 
 /*
  * LstValid (l) --
index 03cd943..1ce33b6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.20 1995/09/27 18:42:21 jtc Exp $    */
+/*     $NetBSD: main.c,v 1.23 1995/11/22 17:40:14 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -48,7 +48,7 @@ char copyright[] =
 #if 0
 static char sccsid[] = "@(#)main.c     5.25 (Berkeley) 4/1/91";
 #else
-static char rcsid[] = "$NetBSD: main.c,v 1.20 1995/09/27 18:42:21 jtc Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.23 1995/11/22 17:40:14 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -83,11 +83,12 @@ static char rcsid[] = "$NetBSD: main.c,v 1.20 1995/09/27 18:42:21 jtc Exp $";
 #include <sys/time.h>
 #include <sys/param.h>
 #include <sys/resource.h>
+#include <sys/signal.h>
 #include <sys/stat.h>
 #include <sys/utsname.h>
+#include <sys/resource.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <signal.h>
 #include <stdio.h>
 #if __STDC__
 #include <stdarg.h>
@@ -113,7 +114,7 @@ Boolean                     allPrecious;    /* .PRECIOUS given on line by itself */
 
 static Boolean         noBuiltins;     /* -r flag */
 static Lst             makefiles;      /* ordered list of makefiles to read */
-int                    maxJobs;        /* -J argument */
+int                    maxJobs;        /* -j argument */
 static int             maxLocal;       /* -L argument */
 Boolean                        compatMake;     /* -B argument */
 Boolean                        debug;          /* -d flag */
@@ -156,12 +157,13 @@ MainParseArgs(argc, argv)
        extern int optind;
        extern char *optarg;
        int c;
+       int forceJobs = 0;
 
        optind = 1;     /* since we're called more than once */
-#ifdef notyet
+#ifdef REMOTE
 # define OPTFLAGS "BD:I:L:PSd:ef:ij:knqrst"
 #else
-# define OPTFLAGS "D:I:d:ef:ij:knqrst"
+# define OPTFLAGS "BD:I:PSd:ef:ij:knqrst"
 #endif
 rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
                switch(c) {
@@ -175,15 +177,16 @@ rearg:    while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
                        Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                        break;
-#ifdef notyet
                case 'B':
                        compatMake = TRUE;
                        break;
+#ifdef REMOTE
                case 'L':
                        maxLocal = atoi(optarg);
                        Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                        break;
+#endif
                case 'P':
                        usePipes = FALSE;
                        Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
@@ -192,7 +195,6 @@ rearg:      while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
                        keepgoing = FALSE;
                        Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
                        break;
-#endif
                case 'd': {
                        char *modules = optarg;
 
@@ -260,7 +262,11 @@ rearg:     while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
                        Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
                        break;
                case 'j':
+                       forceJobs = TRUE;
                        maxJobs = atoi(optarg);
+#ifndef REMOTE
+                       maxLocal = maxJobs;
+#endif
                        Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
                        Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
                        break;
@@ -295,6 +301,13 @@ rearg:     while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
                }
        }
 
+       /*
+        * Be compatible if user did not specify -j and did not explicitly
+        * turned compatibility on
+        */
+       if (!compatMake && !forceJobs)
+               compatMake = TRUE;
+
        oldVars = TRUE;
 
        /*
@@ -384,6 +397,19 @@ main(argc, argv)
        struct utsname utsname;
        char *machine = getenv("MACHINE");
 
+#ifdef RLIMIT_NOFILE
+       /*
+        * get rid of resource limit on file descriptors
+        */
+       {
+               struct rlimit rl;
+               if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
+                   rl.rlim_cur != rl.rlim_max) {
+                       rl.rlim_cur = rl.rlim_max;
+                       (void) setrlimit(RLIMIT_NOFILE, &rl);
+               }
+       }
+#endif
        /*
         * Find where we are and take care of PWD for the automounter...
         * All this code is so that we know where we are when we start up
@@ -416,7 +442,7 @@ main(argc, argv)
         * MACHINE_ARCH is always known at compile time.
         */
        if (!machine) {
-           if (uname(&utsname)) {
+           if (uname(&utsname) == -1) {
                    perror("make: uname");
                    exit(2);
            }
@@ -491,13 +517,13 @@ main(argc, argv)
        debug = 0;                      /* No debug verbosity, please. */
        jobsRunning = FALSE;
 
-       maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
        maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
-#ifdef notyet
-       compatMake = FALSE;             /* No compat mode */
+#ifdef REMOTE
+       maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
 #else
-       compatMake = TRUE;              /* No compat mode */
+       maxJobs = maxLocal;
 #endif
+       compatMake = FALSE;             /* No compat mode */
     
 
        /*
@@ -657,10 +683,6 @@ main(argc, argv)
        else
                targs = Targ_FindList(create, TARG_CREATE);
 
-/*
- * this was original amMake -- want to allow parallelism, so put this
- * back in, eventually.
- */
        if (!compatMake) {
                /*
                 * Initialize job module before traversing the graph, now that
@@ -936,6 +958,26 @@ enomem()
        exit(2);
 }
 
+/*
+ * enunlink --
+ *     Remove a file carefully, avoiding directories.
+ */
+int
+eunlink(file)
+       const char *file;
+{
+       struct stat st;
+
+       if (lstat(file, &st) == -1)
+               return -1;
+
+       if (S_ISDIR(st.st_mode)) {
+               errno = EISDIR;
+               return -1;
+       }
+       return unlink(file);
+}
+
 /*
  * usage --
  *     exit with usage message
index 4e31684..b4b44ca 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $NetBSD: make.1,v 1.9.2.1 1995/12/05 02:50:07 jtc Exp $
+.\"    $NetBSD: make.1,v 1.11 1995/11/08 02:31:00 christos Exp $
 .\" Copyright (c) 1990 The Regents of the University of California.
 .\" All rights reserved.
 .\"
@@ -40,7 +40,7 @@
 .Nd maintain program dependencies
 .Sh SYNOPSIS
 .Nm make
-.Op Fl eiknqrstv
+.Op Fl Beiknqrstv
 .Op Fl D Ar variable
 .Op Fl d Ar flags
 .Op Fl f Ar makefile
@@ -74,6 +74,9 @@ and makefiles, please refer to
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
+.It Fl B 
+Try to be backwards compatible by executing a single shell per command and
+by executing the commands to make the sources of a dependency line in sequence.
 .It Fl D Ar variable
 Define
 .Ar variable
@@ -112,7 +115,7 @@ Print debugging information about target list maintenance.
 Print debugging information about variable assignment.
 .El
 .It Fl e
-Specify that environment variables override macro assignments within
+Specify that environmental variables override macro assignments within
 makefiles.
 .It Fl f Ar makefile
 Specify a makefile to read instead of the default
@@ -137,7 +140,9 @@ before each command line in the makefile.
 .It Fl j Ar max_jobs
 Specify the maximum number of jobs that
 .Nm make
-may have running at any one time.
+may have running at any one time. Turns compatibility mode off, unless the 
+.Ar B
+flag is also specified.
 .It Fl k
 Continue processing after errors are encountered, but only on those targets
 that do not depend on the target whose creation caused the error.
index e333389..c719a2c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: nonints.h,v 1.6 1995/06/14 15:19:45 christos Exp $     */
+/*     $NetBSD: nonints.h,v 1.7 1995/11/02 23:55:00 christos Exp $     */
 
 /*-
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -73,6 +73,7 @@ int PrintAddr __P((ClientData, ClientData));
 void Finish __P((int));
 char *emalloc __P((size_t));
 void enomem __P((void));
+int eunlink __P((const char *));
 
 /* parse.c */
 void Parse_Error __P((int, char *, ...));
index 6cb4d09..174ff11 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: parse.c,v 1.16 1995/09/10 03:58:16 christos Exp $      */
+/*     $NetBSD: parse.c,v 1.17 1995/11/02 23:55:03 christos Exp $      */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)parse.c    5.18 (Berkeley) 2/19/91";
 #else
-static char rcsid[] = "$NetBSD: parse.c,v 1.16 1995/09/10 03:58:16 christos Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.17 1995/11/02 23:55:03 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -2216,7 +2216,11 @@ test_char:
                break;
            case '#':
                if (!ignComment) {
-                   if (compatMake && (lastc != '\\')) {
+                   if (
+#if 0
+                   compatMake &&
+#endif
+                   (lastc != '\\')) {
                        /*
                         * If the character is a hash mark and it isn't escaped
                         * (or we're being compatible), the thing is a comment.
index 0b6802a..43b94d5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: suff.c,v 1.10 1995/09/25 02:46:30 christos Exp $       */
+/*     $NetBSD: suff.c,v 1.11 1995/11/02 23:55:08 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)suff.c     5.6 (Berkeley) 6/1/90";
 #else
-static char rcsid[] = "$NetBSD: suff.c,v 1.10 1995/09/25 02:46:30 christos Exp $";
+static char rcsid[] = "$NetBSD: suff.c,v 1.11 1995/11/02 23:55:08 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -1427,7 +1427,7 @@ SuffExpandChildren(cgnp, pgnp)
            /*
             * Add all elements of the members list to the parent node.
             */
-           while (!Lst_IsEmpty(members)) {
+           while(!Lst_IsEmpty(members)) {
                gn = (GNode *)Lst_DeQueue(members);
 
                if (DEBUG(SUFF)) {
@@ -1995,6 +1995,7 @@ sfnd_abort:
                                    (targ == NULL ? dirSearchPath :
                                     targ->suff->searchPath));
            if (gn->path != NULL) {
+               char *ptr;
                Var_Set(TARGET, gn->path, gn);
 
                if (targ != NULL) {
@@ -2002,7 +2003,7 @@ sfnd_abort:
                     * Suffix known for the thing -- trim the suffix off
                     * the path to form the proper .PREFIX variable.
                     */
-                   int         len = strlen(gn->path);
+                   int         savep = strlen(gn->path) - targ->suff->nameLen;
                    char        savec;
 
                    if (gn->suffix)
@@ -2010,12 +2011,17 @@ sfnd_abort:
                    gn->suffix = targ->suff;
                    gn->suffix->refCount++;
 
-                   savec = gn->path[len-targ->suff->nameLen];
-                   gn->path[len-targ->suff->nameLen] = '\0';
+                   savec = gn->path[savep];
+                   gn->path[savep] = '\0';
 
-                   Var_Set(PREFIX, gn->path, gn);
+                   if ((ptr = strrchr(gn->path, '/')) != NULL)
+                       ptr++;
+                   else
+                       ptr = gn->path;
 
-                   gn->path[len-targ->suff->nameLen] = savec;
+                   Var_Set(PREFIX, ptr, gn);
+
+                   gn->path[savep] = savec;
                } else {
                    /*
                     * The .PREFIX gets the full path if the target has
@@ -2025,7 +2031,12 @@ sfnd_abort:
                        gn->suffix->refCount--;
                    gn->suffix = NULL;
 
-                   Var_Set(PREFIX, gn->path, gn);
+                   if ((ptr = strrchr(gn->path, '/')) != NULL)
+                       ptr++;
+                   else
+                       ptr = gn->path;
+
+                   Var_Set(PREFIX, ptr, gn);
                }
            }
        } else {
index 9820542..b3ddf6a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: util.c,v 1.4 1995/06/14 15:20:11 christos Exp $        */
+/*     $NetBSD: util.c,v 1.5 1995/11/22 17:40:17 christos Exp $        */
 
 /*
  * Missing stuff from OS's
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: util.c,v 1.1.1.1 1995/10/18 08:45:43 deraadt Exp $";
+static char rcsid[] = "$Id: util.c,v 1.2 1995/12/14 03:23:39 deraadt Exp $";
 #endif
 
 #include <stdio.h>
@@ -302,3 +302,26 @@ utimes(file, tvp)
 
 
 #endif /* __hpux */
+
+#if defined(sun) && defined(__svr4__)
+#include <signal.h>
+
+/* turn into bsd signals */
+void (*
+signal(s, a)) ()
+    int     s;
+    void (*a)();
+{
+    struct sigaction sa, osa;
+
+    sa.sa_handler = a;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_RESTART;
+
+    if (sigaction(s, &sa, &osa) == -1)
+       return SIG_ERR;
+    else
+       return osa.sa_handler;
+}
+
+#endif
index d4b0b57..28ae8b7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: var.c,v 1.11 1995/06/14 15:20:13 christos Exp $        */
+/*     $NetBSD: var.c,v 1.12 1995/11/02 23:55:12 christos Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)var.c      5.7 (Berkeley) 6/1/90";
 #else
-static char rcsid[] = "$NetBSD: var.c,v 1.11 1995/06/14 15:20:13 christos Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.12 1995/11/02 23:55:12 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -1116,7 +1116,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
     Boolean        haveModifier;/* TRUE if have modifiers for the variable */
     register char   endc;      /* Ending character when variable in parens
                                 * or braces */
-    register char   startc;    /* Starting character when variable in parens
+    register char   startc=0;  /* Starting character when variable in parens
                                 * or braces */
     int             cnt;       /* Used to count brace pairs when variable in
                                 * in parens or braces */