Sync up with NetBSD:
authorbriggs <briggs@openbsd.org>
Mon, 2 Sep 1996 16:04:06 +0000 (16:04 +0000)
committerbriggs <briggs@openbsd.org>
Mon, 2 Sep 1996 16:04:06 +0000 (16:04 +0000)
(christos)
Fix bug reported by Greg Hudson where leaf (source only) nodes were
referenced only by their basename and not by their full pathname. This
breaks when .PATH or MAKEOBJDIR are used. There might be Makefiles
around that try to work around this bug by prepending ${.CURDIR} to
the sources, and they should be found and fixed. Also a lot of the gunk
in suff.c that was attempting to work around the same problem could be
removed.
(christos)
- Move -D flags from Makefile to config.h and explain what they do. Add
  -Wall -Wno-unused to CFLAGS. Add new define SYSVVARSUB to enable SysV
  style variable substitutions and enable them.
- Add SunOS style command substitutions via SUNSHCMD
- Fix core dump with '{variable = value'
(christos)
Fix bug where make will always exit with 0, even when one or more
parallel jobs failed. (Only affects parallel make code)
(christos)
Protect __P from being multiply defined (for systems that already
define it)
(christos) Add strdup() since ultrix is missing it.
From Larry Schwimmer <rosebud@cyclone.Stanford.EDU>
(christos) Add estrdup(), a checked version of strdup and use it.
(christos) Recognize SVR4 style long filename entries in archives.
(thorpej) Tidy up some RCS ids a bit.

17 files changed:
usr.bin/make/Makefile
usr.bin/make/arch.c
usr.bin/make/config.h
usr.bin/make/dir.c
usr.bin/make/extern.h
usr.bin/make/job.c
usr.bin/make/main.c
usr.bin/make/make.1
usr.bin/make/make.c
usr.bin/make/make.h
usr.bin/make/nonints.h
usr.bin/make/parse.c
usr.bin/make/pathnames.h
usr.bin/make/suff.c
usr.bin/make/targ.c
usr.bin/make/util.c
usr.bin/make/var.c

index b9b15eb..9293eb2 100644 (file)
@@ -1,9 +1,9 @@
-#      $OpenBSD: Makefile,v 1.3 1996/03/27 19:32:34 niklas Exp $
-#      $NetBSD: Makefile,v 1.10 1996/03/11 13:45:31 christos Exp $
+#      $OpenBSD: Makefile,v 1.4 1996/09/02 16:04:06 briggs Exp $
+#      $NetBSD: Makefile,v 1.11 1996/05/28 23:34:35 christos Exp $
 #      @(#)Makefile    5.2 (Berkeley) 12/28/90
 
 PROG=  make
-CFLAGS+= -I${.CURDIR} -DPOSIX -DSYSVINCLUDE
+CFLAGS+= -I${.CURDIR} -Wall -Wno-unused
 SRCS=  arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
        make.c parse.c str.c suff.c targ.c var.c util.c
 SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
index 48370dc..e47bf42 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: arch.c,v 1.5 1996/07/31 00:01:04 niklas Exp $ */
-/*     $NetBSD: arch.c,v 1.14 1996/03/12 18:04:27 christos Exp $       */
+/*     $OpenBSD: arch.c,v 1.6 1996/09/02 16:04:07 briggs Exp $ */
+/*     $NetBSD: arch.c,v 1.16 1996/08/13 16:42:00 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -44,7 +44,7 @@
 static char sccsid[] = "@(#)arch.c     5.7 (Berkeley) 12/28/90";
 static char rcsid[] = "$NetBSD: arch.c,v 1.14 1996/03/12 18:04:27 christos Exp $";
 #else
-static char rcsid[] = "$OpenBSD: arch.c,v 1.5 1996/07/31 00:01:04 niklas Exp $";
+static char rcsid[] = "$OpenBSD: arch.c,v 1.6 1996/09/02 16:04:07 briggs Exp $";
 #endif
 #endif /* not lint */
 
@@ -102,9 +102,6 @@ static char rcsid[] = "$OpenBSD: arch.c,v 1.5 1996/07/31 00:01:04 niklas Exp $";
 #include    <sys/param.h>
 #include    <ctype.h>
 #include    <ar.h>
-#if !defined(__svr4__) && !defined(__SVR4) && !defined(__alpha__)
-#include    <ranlib.h>
-#endif
 #include    <utime.h>
 #include    <stdio.h>
 #include    <stdlib.h>
@@ -119,12 +116,18 @@ typedef struct Arch {
     char         *name;      /* Name of archive */
     Hash_Table   members;    /* All the members of the archive described
                               * by <name, struct ar_hdr *> key/value pairs */
+    char         *fnametab;  /* Extended name table strings */
+    size_t       fnamesize;  /* Size of the string table */
 } Arch;
 
 static int ArchFindArchive __P((ClientData, ClientData));
 static void ArchFree __P((ClientData));
 static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean));
 static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *));
+#if defined(__svr4__) || defined(__SVR4)
+#define SVR4ARCHIVES
+static int ArchSVR4Entry __P((Arch *, char *, size_t, FILE *));
+#endif
 
 /*-
  *-----------------------------------------------------------------------
@@ -154,6 +157,8 @@ ArchFree(ap)
        free((Address) Hash_GetValue (entry));
 
     free(a->name);
+    if (a->fnametab)
+       free(a->fnametab);
     Hash_DeleteTable(&a->members);
     free((Address) a);
 }
@@ -543,31 +548,56 @@ ArchStatMember (archive, member, hash)
     }
 
     ar = (Arch *)emalloc (sizeof (Arch));
-    ar->name = strdup (archive);
+    ar->name = estrdup (archive);
+    ar->fnametab = NULL;
+    ar->fnamesize = 0;
     Hash_InitTable (&ar->members, -1);
     memName[AR_MAX_NAME_LEN] = '\0';
     
     while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) {
        if (strncmp ( arh.ar_fmag, ARFMAG, sizeof (arh.ar_fmag)) != 0) {
-                                /*
-                                 * The header is bogus, so the archive is bad
-                                 * and there's no way we can recover...
-                                 */
-                                fclose (arch);
-                                Hash_DeleteTable (&ar->members);
-                                free ((Address)ar);
-                                return ((struct ar_hdr *) NULL);
+           /*
+            * The header is bogus, so the archive is bad
+            * and there's no way we can recover...
+            */
+           goto badarch;
        } else {
+           /*
+            * We need to advance the stream's pointer to the start of the
+            * next header. Files are padded with newlines to an even-byte
+            * boundary, so we need to extract the size of the file from the
+            * 'size' field of the header and round it up during the seek.
+            */
+           arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
+           size = (int) strtol(arh.ar_size, NULL, 10);
+
            (void) strncpy (memName, arh.ar_name, sizeof(arh.ar_name));
            for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
                continue;
            }
            cp[1] = '\0';
 
-#if defined(__svr4__) || defined(__SVR4)
-           /* svr4 names are slash terminated */
-           if (cp[0] == '/')
-               cp[0] = '\0';
+#ifdef SVR4ARCHIVES
+           /*
+            * svr4 names are slash terminated. Also svr4 extended AR format.
+            */
+           if (memName[0] == '/') {
+               /*
+                * svr4 magic mode; handle it
+                */
+               switch (ArchSVR4Entry(ar, memName, size, arch)) {
+               case -1:  /* Invalid data */
+                   goto badarch;
+               case 0:   /* List of files entry */
+                   continue;
+               default:  /* Got the entry */
+                   break;
+               }
+           }
+           else {
+               if (cp[0] == '/')
+                   cp[0] = '\0';
+           }
 #endif
 
 #ifdef AR_EFMT1
@@ -580,18 +610,10 @@ ArchStatMember (archive, member, hash)
 
                unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
 
-               if (elen > MAXPATHLEN) {
-                       fclose (arch);
-                       Hash_DeleteTable (&ar->members);
-                       free ((Address)ar);
-                       return ((struct ar_hdr *) NULL);
-               }
-               if (fread (memName, elen, 1, arch) != 1) {
-                       fclose (arch);
-                       Hash_DeleteTable (&ar->members);
-                       free ((Address)ar);
-                       return ((struct ar_hdr *) NULL);
-               }
+               if (elen > MAXPATHLEN)
+                       goto badarch;
+               if (fread (memName, elen, 1, arch) != 1)
+                       goto badarch;
                memName[elen] = '\0';
                fseek (arch, -elen, 1);
                if (DEBUG(ARCH) || DEBUG(MAKE)) {
@@ -605,14 +627,6 @@ ArchStatMember (archive, member, hash)
            memcpy ((Address)Hash_GetValue (he), (Address)&arh,
                sizeof (struct ar_hdr));
        }
-       /*
-        * We need to advance the stream's pointer to the start of the
-        * next header. Files are padded with newlines to an even-byte
-        * boundary, so we need to extract the size of the file from the
-        * 'size' field of the header and round it up during the seek.
-        */
-       arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
-       size = (int) strtol(arh.ar_size, NULL, 10);
        fseek (arch, (size + 1) & ~1, 1);
     }
 
@@ -631,7 +645,120 @@ ArchStatMember (archive, member, hash)
     } else {
        return ((struct ar_hdr *) NULL);
     }
+
+badarch:
+    fclose (arch);
+    Hash_DeleteTable (&ar->members);
+    if (ar->fnametab)
+       free(ar->fnametab);
+    free ((Address)ar);
+    return ((struct ar_hdr *) NULL);
+}
+
+#ifdef SVR4ARCHIVES
+/*-
+ *-----------------------------------------------------------------------
+ * ArchSVR4Entry --
+ *     Parse an SVR4 style entry that begins with a slash.
+ *     If it is "//", then load the table of filenames
+ *     If it is "/<offset>", then try to substitute the long file name
+ *     from offset of a table previously read.
+ *
+ * Results:
+ *     -1: Bad data in archive
+ *      0: A table was loaded from the file
+ *      1: Name was successfully substituted from table
+ *      2: Name was not successfully substituted from table
+ *
+ * Side Effects:
+ *     If a table is read, the file pointer is moved to the next archive
+ *     member
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+ArchSVR4Entry(ar, name, size, arch)
+       Arch *ar;
+       char *name;
+       size_t size;
+       FILE *arch;
+{
+#define ARLONGNAMES1 "//"
+#define ARLONGNAMES2 "/ARFILENAMES"
+    size_t entry;
+    char *ptr, *eptr;
+
+    if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 ||
+       strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) {
+
+       if (ar->fnametab != NULL) {
+           if (DEBUG(ARCH)) {
+               printf("Attempted to redefine an SVR4 name table\n");
+           }
+           return -1;
+       }
+
+       /*
+        * This is a table of archive names, so we build one for
+        * ourselves
+        */
+       ar->fnametab = emalloc(size);
+       ar->fnamesize = size;
+
+       if (fread(ar->fnametab, size, 1, arch) != 1) {
+           if (DEBUG(ARCH)) {
+               printf("Reading an SVR4 name table failed\n");
+           }
+           return -1;
+       }
+       eptr = ar->fnametab + size;
+       for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++)
+           switch (*ptr) {
+           case '/':
+               entry++;
+               *ptr = '\0';
+               break;
+
+           case '\n':
+               break;
+
+           default:
+               break;
+           }
+       if (DEBUG(ARCH)) {
+           printf("Found svr4 archive name table with %d entries\n", entry);
+       }
+       return 0;
+    }
+
+    if (name[1] == ' ' || name[1] == '\0')
+       return 2;
+
+    entry = (size_t) strtol(&name[1], &eptr, 0);
+    if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) {
+       if (DEBUG(ARCH)) {
+           printf("Could not parse SVR4 name %s\n", name);
+       }
+       return 2;
+    }
+    if (entry >= ar->fnamesize) {
+       if (DEBUG(ARCH)) {
+           printf("SVR4 entry offset %s is greater than %d\n",
+                  name, ar->fnamesize);
+       }
+       return 2;
+    }
+
+    if (DEBUG(ARCH)) {
+       printf("Replaced %s with %s\n", name, &ar->fnametab[entry]);
+    }
+
+    (void) strncpy(name, &ar->fnametab[entry], MAXPATHLEN);
+    name[MAXPATHLEN] = '\0';
+    return 1;
 }
+#endif
+
 
 /*-
  *-----------------------------------------------------------------------
index 7292cf2..e062828 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: config.h,v 1.4 1996/07/31 00:01:03 niklas Exp $       */
-/*     $NetBSD: config.h,v 1.5 1996/02/04 20:34:43 christos Exp $      */
+/*     $OpenBSD: config.h,v 1.5 1996/09/02 16:04:07 briggs Exp $       */
+/*     $NetBSD: config.h,v 1.6 1996/05/28 23:34:39 christos Exp $      */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  *     re-made, causing later targets to appear up-to-date. On systems
  *     that don't have this problem, you should defined this. Under
  *     NFS you probably should not, unless you aren't exporting jobs.
- *
- * POSIX
- *     If the POSIX standard for Make is to be followed. There are
- *     several areas that I dislike, hence this constant.
  */
 #define        LIBSUFF ".a"
 #define        RECHECK
 
+/*
+ * POSIX
+ *     Adhere to the POSIX 1003.2 draft for the make(1) program.
+ *     - Use MAKEFLAGS instead of MAKE to pick arguments from the
+ *       environment.
+ *     - Allow empty command lines if starting with tab.
+ */
+#define POSIX
+
+/*
+ * SYSVINCLUDES
+ *     Recognize system V like include directives [include "filename"]
+ * SYSVVARSUB
+ *     Recognize system V like ${VAR:x=y} variable substitutions
+ */
+#define SYSVINCLUDES
+#define SYSVVARSUB
+
+/*
+ * SUNSHCMD
+ *     Recognize SunOS and Solaris:
+ *             VAR :sh= CMD    # Assign VAR to the command substitution of CMD
+ *             ${VAR:sh}       # Return the command substitution of the value
+ *                             # of ${VAR}
+ */
+#define SUNSHCMD
+
 #if !defined(__svr4__) && !defined(__SVR4) && !defined(__alpha__)
 # ifndef RANLIBMAG
 #  define RANLIBMAG "__.SYMDEF"
index fa1f8fa..7e3ae7b 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: dir.c,v 1.4 1996/06/26 05:36:29 deraadt Exp $ */
-/*     $NetBSD: dir.c,v 1.10 1996/02/04 22:20:38 christos Exp $        */
+/*     $OpenBSD: dir.c,v 1.5 1996/09/02 16:04:09 briggs Exp $  */
+/*     $NetBSD: dir.c,v 1.11 1996/08/13 16:42:02 christos Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)dir.c      5.6 (Berkeley) 12/28/90";
 #else
-static char rcsid[] = "$OpenBSD: dir.c,v 1.4 1996/06/26 05:36:29 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: dir.c,v 1.5 1996/09/02 16:04:09 briggs Exp $";
 #endif
 #endif /* not lint */
 
@@ -355,7 +355,7 @@ DirMatchFiles (pattern, p, expansions)
             (pattern[0] == '.')))
        {
            (void)Lst_AtEnd(expansions,
-                           (isDot ? strdup(entry->name) :
+                           (isDot ? estrdup(entry->name) :
                             str_concat(p->name, entry->name,
                                        STR_ADDSLASH)));
        }
@@ -707,7 +707,7 @@ Dir_FindFile (name, path)
            }
            hits += 1;
            dot->hits += 1;
-           return (strdup (name));
+           return (estrdup (name));
     }
     
     if (Lst_Open (path) == FAILURE) {
@@ -818,7 +818,7 @@ Dir_FindFile (name, path)
                /*
                 * Checking in dot -- DON'T put a leading ./ on the thing.
                 */
-               file = strdup(name);
+               file = estrdup(name);
                checkedDot = TRUE;
            }
            if (DEBUG(DIR)) {
@@ -914,7 +914,7 @@ Dir_FindFile (name, path)
     }
     
     if (Hash_FindEntry (&p->files, cp) != (Hash_Entry *)NULL) {
-       return (strdup (name));
+       return (estrdup (name));
     } else {
        return ((char *) NULL);
     }
@@ -929,7 +929,7 @@ Dir_FindFile (name, path)
        if (DEBUG(DIR)) {
            printf("got it (in mtime cache)\n");
        }
-       return(strdup(name));
+       return(estrdup(name));
     } else if (stat (name, &stb) == 0) {
        entry = Hash_CreateEntry(&mtimes, name, (Boolean *)NULL);
        if (DEBUG(DIR)) {
@@ -937,7 +937,7 @@ Dir_FindFile (name, path)
                    name);
        }
        Hash_SetValue(entry, (long)stb.st_mtime);
-       return (strdup (name));
+       return (estrdup (name));
     } else {
        if (DEBUG(DIR)) {
            printf("failed. Returning NULL\n");
@@ -980,7 +980,7 @@ Dir_MTime (gn)
     }
     
     if (fullName == (char *)NULL) {
-       fullName = strdup(gn->name);
+       fullName = estrdup(gn->name);
     }
 
     entry = Hash_FindEntry(&mtimes, fullName);
@@ -1054,7 +1054,7 @@ Dir_AddDir (path, name)
        
        if ((d = opendir (name)) != (DIR *) NULL) {
            p = (Path *) emalloc (sizeof (Path));
-           p->name = strdup (name);
+           p->name = estrdup (name);
            p->hits = 0;
            p->refCount = 1;
            Hash_InitTable (&p->files, -1);
@@ -1138,7 +1138,7 @@ Dir_MakeFlags (flag, path)
     LstNode      ln;     /* the node of the current directory */
     Path         *p;     /* the structure describing the current directory */
     
-    str = strdup ("");
+    str = estrdup ("");
     
     if (Lst_Open (path) == SUCCESS) {
        while ((ln = Lst_Next (path)) != NILLNODE) {
index 719f2fb..ae704a5 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: extern.h,v 1.4 1996/06/26 05:36:35 deraadt Exp $      */
-/*     $NetBSD: nonints.h,v 1.9 1996/03/31 21:30:07 christos Exp $     */
+/*     $OpenBSD: extern.h,v 1.5 1996/09/02 16:04:16 briggs Exp $       */
+/*     $NetBSD: nonints.h,v 1.11 1996/08/13 16:42:11 christos Exp $    */
 
 /*-
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -66,12 +66,14 @@ void For_Run  __P((void));
 /* main.c */
 void Main_ParseArgLine __P((char *));
 int main __P((int, char **));
+char *Cmd_Exec __P((char *, char **));
 void Error __P((char *, ...));
 void Fatal __P((char *, ...));
 void Punt __P((char *, ...));
 void DieHorribly __P((void));
 int PrintAddr __P((ClientData, ClientData));
 void Finish __P((int));
+char *estrdup __P((const char *));
 void *emalloc __P((size_t));
 void *erealloc __P((void *, size_t));
 void enomem __P((void));
index 0474a42..f1e45d2 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: job.c,v 1.4 1996/06/26 05:36:32 deraadt Exp $ */
-/*     $NetBSD: job.c,v 1.14 1996/02/04 22:20:42 christos Exp $        */
+/*     $OpenBSD: job.c,v 1.5 1996/09/02 16:04:11 briggs Exp $  */
+/*     $NetBSD: job.c,v 1.15 1996/05/29 15:28:05 christos Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)job.c      5.15 (Berkeley) 3/1/91";
 #else
-static char rcsid[] = "$OpenBSD: job.c,v 1.4 1996/06/26 05:36:32 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: job.c,v 1.5 1996/09/02 16:04:11 briggs Exp $";
 #endif
 #endif /* not lint */
 
@@ -970,7 +970,7 @@ JobFinish(job, status)
        job->node->made = MADE;
        Make_Update(job->node);
        free((Address)job);
-    } else if (*status == 0) {
+    } else if (*status != 0) {
        errors += 1;
        free((Address)job);
     }
index 5ffcbcf..b3caf3e 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: main.c,v 1.7 1996/04/21 23:43:21 deraadt Exp $        */
-/*     $NetBSD: main.c,v 1.28 1996/03/31 21:30:05 christos Exp $       */
+/*     $OpenBSD: main.c,v 1.8 1996/09/02 16:04:13 briggs Exp $ */
+/*     $NetBSD: main.c,v 1.30 1996/08/13 16:42:08 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -50,7 +50,7 @@ char copyright[] =
 static char sccsid[] = "@(#)main.c     5.25 (Berkeley) 4/1/91";
 static char rcsid[] = "$NetBSD: main.c,v 1.26 1996/03/11 13:45:33 christos Exp $";
 #else
-static char rcsid[] = "$OpenBSD: main.c,v 1.7 1996/04/21 23:43:21 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: main.c,v 1.8 1996/09/02 16:04:13 briggs Exp $";
 #endif
 #endif /* not lint */
 
@@ -88,6 +88,7 @@ static char rcsid[] = "$OpenBSD: main.c,v 1.7 1996/04/21 23:43:21 deraadt Exp $"
 #include <sys/signal.h>
 #include <sys/stat.h>
 #include <sys/utsname.h>
+#include <sys/wait.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -337,7 +338,7 @@ rearg:      while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
                                        optind = 1;     /* - */
                                goto rearg;
                        }
-                       (void)Lst_AtEnd(create, (ClientData)strdup(*argv));
+                       (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
                }
 }
 
@@ -824,6 +825,142 @@ found:            Var_Set("MAKEFILE", fname, VAR_GLOBAL);
        return(TRUE);
 }
 
+/*-
+ * Cmd_Exec --
+ *     Execute the command in cmd, and return the output of that command
+ *     in a string.
+ *
+ * Results:
+ *     A string containing the output of the command, or the empty string
+ *     If err is not NULL, it contains the reason for the command failure
+ *
+ * Side Effects:
+ *     The string must be freed by the caller.
+ */
+char *
+Cmd_Exec(cmd, err)
+    char *cmd;
+    char **err;
+{
+    char       *args[4];       /* Args for invoking the shell */
+    int        fds[2];         /* Pipe streams */
+    int        cpid;           /* Child PID */
+    int        pid;            /* PID from wait() */
+    char       *res;           /* result */
+    int                status;         /* command exit status */
+    Buffer     buf;            /* buffer to store the result */
+    char       *cp;
+    int                cc;
+
+
+    *err = NULL;
+
+    /*
+     * Set up arguments for shell
+     */
+    args[0] = "sh";
+    args[1] = "-c";
+    args[2] = cmd;
+    args[3] = NULL;
+
+    /*
+     * Open a pipe for fetching its output
+     */
+    if (pipe(fds) == -1) {
+       *err = "Couldn't create pipe for \"%s\"";
+       goto bad;
+    }
+
+    /*
+     * Fork
+     */
+    switch (cpid = vfork()) {
+    case 0:
+       /*
+        * Close input side of pipe
+        */
+       (void) close(fds[0]);
+
+       /*
+        * Duplicate the output stream to the shell's output, then
+        * shut the extra thing down. Note we don't fetch the error
+        * stream...why not? Why?
+        */
+       (void) dup2(fds[1], 1);
+       (void) close(fds[1]);
+       
+       (void) execv("/bin/sh", args);
+       _exit(1);
+       /*NOTREACHED*/
+
+    case -1:
+       *err = "Couldn't exec \"%s\"";
+       goto bad;
+
+    default:
+       /*
+        * No need for the writing half
+        */
+       (void) close(fds[1]);
+       
+       buf = Buf_Init (MAKE_BSIZE);
+
+       do {
+           char   result[BUFSIZ];
+           cc = read(fds[0], result, sizeof(result));
+           if (cc > 0) 
+               Buf_AddBytes(buf, cc, (Byte *) result);
+       }
+       while (cc > 0 || (cc == -1 && errno == EINTR));
+
+       /*
+        * Close the input side of the pipe.
+        */
+       (void) close(fds[0]);
+
+       /*
+        * Wait for the process to exit.
+        */
+       while(((pid = wait(&status)) != cpid) && (pid >= 0))
+           continue;
+
+       res = (char *)Buf_GetAll (buf, &cc);
+       Buf_Destroy (buf, FALSE);
+
+       if (cc == 0) 
+           *err = "Couldn't read shell's output for \"%s\"";
+
+       if (status)
+           *err = "\"%s\" returned non-zero status";
+
+       /*
+        * Null-terminate the result, convert newlines to spaces and
+        * install it in the variable.
+        */
+       res[cc] = '\0';
+       cp = &res[cc] - 1;
+
+       if (*cp == '\n') {
+           /*
+            * A final newline is just stripped
+            */
+           *cp-- = '\0';
+       }
+       while (cp >= res) {
+           if (*cp == '\n') {
+               *cp = ' ';
+           }
+           cp--;
+       }
+       break;
+    }
+    return res;
+bad:
+    res = emalloc(1);
+    *res = '\0';
+    return res;
+}
+
 /*-
  * Error --
  *     Print an error message given its format.
@@ -992,6 +1129,21 @@ emalloc(len)
        return(p);
 }
 
+/*
+ * emalloc --
+ *     strdup, but die on error.
+ */
+char *
+estrdup(str)
+       const char *str;
+{
+       char *p;
+
+       if ((p = strdup(str)) == NULL)
+               enomem();
+       return(p);
+}
+
 /*
  * erealloc --
  *     realloc, but die on error.
index 85777b1..22fb866 100644 (file)
@@ -1,5 +1,6 @@
-.\"    $OpenBSD: make.1,v 1.6 1996/03/27 19:32:37 niklas Exp $
-.\"    $NetBSD: make.1,v 1.14 1996/03/15 21:52:32 christos Exp $
+.\"    $OpenBSD: make.1,v 1.7 1996/09/02 16:04:13 briggs Exp $
+.\"    $NetBSD: make.1,v 1.15 1996/08/30 17:59:40 thorpej Exp $
+.\"
 .\" Copyright (c) 1990 The Regents of the University of California.
 .\" All rights reserved.
 .\"
index c366518..805c96d 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: make.c,v 1.2 1996/03/27 19:32:38 niklas Exp $ */
-/*     $NetBSD: make.c,v 1.8 1996/03/15 21:52:37 christos Exp $        */
+/*     $OpenBSD: make.c,v 1.3 1996/09/02 16:04:14 briggs Exp $ */
+/*     $NetBSD: make.c,v 1.9 1996/08/30 23:21:10 christos Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -44,7 +44,7 @@
 static char sccsid[] = "@(#)make.c     5.3 (Berkeley) 6/1/90";
 static char rcsid[] = "$NetBSD: make.c,v 1.8 1996/03/15 21:52:37 christos Exp $";
 #else
-static char rcsid[] = "$OpenBSD: make.c,v 1.2 1996/03/27 19:32:38 niklas Exp $";
+static char rcsid[] = "$OpenBSD: make.c,v 1.3 1996/09/02 16:04:14 briggs Exp $";
 #endif
 #endif /* not lint */
 
@@ -580,9 +580,16 @@ MakeAddAllSrc (cgnp, pgnp)
     GNode      *pgn = (GNode *) pgnp;
     if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
        char *child;
-       char *p1;
+       char *p1 = NULL;
 
-       child = Var_Value(TARGET, cgn, &p1);
+       if (OP_NOP(cgn->type)) {
+           /*
+            * this node is only source; use the specific pathname for it
+            */
+           child = cgn->path ? cgn->path : cgn->name;
+       }
+       else
+           child = Var_Value(TARGET, cgn, &p1);
        Var_Append (ALLSRC, child, pgn);
        if (pgn->type & OP_JOIN) {
            if (cgn->made == MADE) {
index c5f1a66..49ea41f 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: make.h,v 1.5 1996/03/27 19:32:39 niklas Exp $ */
-/*     $NetBSD: make.h,v 1.9 1996/03/06 00:15:21 christos Exp $        */
+/*     $OpenBSD: make.h,v 1.6 1996/09/02 16:04:15 briggs Exp $ */
+/*     $NetBSD: make.h,v 1.10 1996/08/13 16:39:30 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
 #if !defined(MAKE_BOOTSTRAP) && defined(BSD)
 #include <sys/cdefs.h>
 #else
+#ifndef __P
 #if defined(__STDC__) || defined(__cplusplus)
 #define        __P(protos)     protos          /* full-blown ANSI C */
 #else
 #define        __P(protos)     ()              /* traditional C preprocessor */    
 #endif
 #endif
+#endif
 #if __STDC__
 #include <stdlib.h>
 #include <unistd.h>
index 87c9b32..5646bb1 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: nonints.h,v 1.4 1996/06/26 05:36:35 deraadt Exp $     */
-/*     $NetBSD: nonints.h,v 1.9 1996/03/31 21:30:07 christos Exp $     */
+/*     $OpenBSD: nonints.h,v 1.5 1996/09/02 16:04:16 briggs Exp $      */
+/*     $NetBSD: nonints.h,v 1.11 1996/08/13 16:42:11 christos Exp $    */
 
 /*-
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -66,12 +66,14 @@ void For_Run  __P((void));
 /* main.c */
 void Main_ParseArgLine __P((char *));
 int main __P((int, char **));
+char *Cmd_Exec __P((char *, char **));
 void Error __P((char *, ...));
 void Fatal __P((char *, ...));
 void Punt __P((char *, ...));
 void DieHorribly __P((void));
 int PrintAddr __P((ClientData, ClientData));
 void Finish __P((int));
+char *estrdup __P((const char *));
 void *emalloc __P((size_t));
 void *erealloc __P((void *, size_t));
 void enomem __P((void));
index 67fd0c7..02f6087 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: parse.c,v 1.8 1996/07/23 18:37:12 deraadt Exp $       */
-/*     $NetBSD: parse.c,v 1.22 1996/03/15 21:52:41 christos Exp $      */
+/*     $OpenBSD: parse.c,v 1.9 1996/09/02 16:04:17 briggs Exp $        */
+/*     $NetBSD: parse.c,v 1.24 1996/08/13 16:42:13 christos Exp $      */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)parse.c    5.18 (Berkeley) 2/19/91";
 #else
-static char rcsid[] = "$NetBSD: parse.c,v 1.22 1996/03/15 21:52:41 christos Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.24 1996/08/13 16:42:13 christos Exp $";
 #endif
 #endif /* not lint */
 
@@ -97,7 +97,6 @@ static char rcsid[] = "$NetBSD: parse.c,v 1.22 1996/03/15 21:52:41 christos Exp
 #include <stdio.h>
 #include <ctype.h>
 #include <errno.h>
-#include <sys/wait.h>
 #include "make.h"
 #include "hash.h"
 #include "dir.h"
@@ -541,7 +540,7 @@ ParseDoSrc (tOp, src, allsrc)
         * invoked if the user didn't specify a target on the command
         * line. This is to allow #ifmake's to succeed, or something...
         */
-       (void) Lst_AtEnd (create, (ClientData)strdup(src));
+       (void) Lst_AtEnd (create, (ClientData)estrdup(src));
        /*
         * Add the name to the .TARGETS variable as well, so the user cna
         * employ that, if desired.
@@ -1276,22 +1275,31 @@ Parse_IsVar (line)
        default:
            if (wasSpace && haveName) {
                    if (ISEQOPERATOR(*line)) {
+                       /*
+                        * We must have a finished word
+                        */
+                       if (level != 0)
+                           return FALSE;
+
                        /*
                         * When an = operator [+?!:] is found, the next
-                        * character must be an = or it ain't a valid
+                        * character must be an = or it ain't a valid
                         * assignment.
                         */
-                       if (line[1] != '=' && level == 0)
-                           return FALSE;
-                       else
+                       if (line[1] == '=')
                            return haveName;
-                   }
-                   else {
+#ifdef SUNSHCMD
                        /*
-                        * This is the start of another word, so not assignment.
+                        * This is a shell command
                         */
-                       return FALSE;
+                       if (strncmp(line, ":sh", 3) == 0)
+                           return haveName;
+#endif
                    }
+                   /*
+                    * This is the start of another word, so not assignment.
+                    */
+                   return FALSE;
            }
            else {
                haveName = TRUE; 
@@ -1394,6 +1402,17 @@ Parse_DoVar (line, ctxt)
            break;
 
        default:
+#ifdef SUNSHCMD
+           while (*opc != ':')
+               if (--opc < line)
+                   break;
+
+           if (strncmp(opc, ":sh", 3) == 0) {
+               type = VAR_SHELL;
+               *opc = '\0';
+               break;
+           }
+#endif
            type = VAR_NORMAL;
            break;
     }
@@ -1425,156 +1444,38 @@ Parse_DoVar (line, ctxt)
        Var_Set(line, cp, ctxt);
        free(cp);
     } else if (type == VAR_SHELL) {
-       char    *args[4];       /* Args for invoking the shell */
-       int     fds[2];         /* Pipe streams */
-       int     cpid;           /* Child PID */
-       int     pid;            /* PID from wait() */
-       Boolean freeCmd;        /* TRUE if the command needs to be freed, i.e.
-                                * if any variable expansion was performed */
-
-       /* 
-        * Avoid clobbered variable warnings by forcing the compiler
-        * to ``unregister'' variables
-        */
-#if __GNUC__
-       (void) &freeCmd;
-#endif
+       Boolean freeCmd = FALSE; /* TRUE if the command needs to be freed, i.e.
+                                 * if any variable expansion was performed */
+       char *res, *err;
 
-       /*
-        * Set up arguments for shell
-        */
-       args[0] = "sh";
-       args[1] = "-c";
-       if (strchr(cp, '$') != (char *)NULL) {
+       if (strchr(cp, '$') != NULL) {
            /*
             * There's a dollar sign in the command, so perform variable
             * expansion on the whole thing. The resulting string will need
             * freeing when we're done, so set freeCmd to TRUE.
             */
-           args[2] = Var_Subst(NULL, cp, VAR_CMD, TRUE);
+           cp = Var_Subst(NULL, cp, VAR_CMD, TRUE);
            freeCmd = TRUE;
-       } else {
-           args[2] = cp;
-           freeCmd = FALSE;
        }
-       args[3] = (char *)NULL;
 
-       /*
-        * Open a pipe for fetching its output
-        */
-       pipe(fds);
+       res = Cmd_Exec(cp, &err);
+       Var_Set(line, res, ctxt);
+       free(res);
 
-       /*
-        * Fork
-        */
-       cpid = vfork();
-       if (cpid == 0) {
-           /*
-            * Close input side of pipe
-            */
-           close(fds[0]);
+       if (err)
+           Parse_Error(PARSE_WARNING, err, cp);
 
-           /*
-            * Duplicate the output stream to the shell's output, then
-            * shut the extra thing down. Note we don't fetch the error
-            * stream...why not? Why?
-            */
-           dup2(fds[1], 1);
-           close(fds[1]);
-           
-           execv("/bin/sh", args);
-           _exit(1);
-       } else if (cpid < 0) {
-           /*
-            * Couldn't fork -- tell the user and make the variable null
-            */
-           Parse_Error(PARSE_WARNING, "Couldn't exec \"%s\"", cp);
-           Var_Set(line, "", ctxt);
-       } else {
-           int status;
-           int cc;
-           Buffer buf;
-           char *res;
-
-           /*
-            * No need for the writing half
-            */
-           close(fds[1]);
-           
-           buf = Buf_Init (MAKE_BSIZE);
-
-           do {
-               char   result[BUFSIZ];
-               cc = read(fds[0], result, sizeof(result));
-               if (cc > 0) 
-                   Buf_AddBytes(buf, cc, (Byte *) result);
-           }
-           while (cc > 0 || (cc == -1 && errno == EINTR));
-
-           /*
-            * Close the input side of the pipe.
-            */
-           close(fds[0]);
-
-           /*
-            * Wait for the process to exit.
-            */
-           while(((pid = wait(&status)) != cpid) && (pid >= 0))
-               continue;
-
-           res = (char *)Buf_GetAll (buf, &cc);
-           Buf_Destroy (buf, FALSE);
-
-           if (cc == 0) {
-               /*
-                * Couldn't read the child's output -- tell the user and
-                * set the variable to null
-                */
-               Parse_Error(PARSE_WARNING, "Couldn't read shell's output");
-           }
-
-           if (status) {
-               /*
-                * Child returned an error -- tell the user but still use
-                * the result.
-                */
-               Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp);
-           }
-
-           /*
-            * Null-terminate the result, convert newlines to spaces and
-            * install it in the variable.
-            */
-           res[cc] = '\0';
-           cp = &res[cc] - 1;
-
-           if (*cp == '\n') {
-               /*
-                * A final newline is just stripped
-                */
-               *cp-- = '\0';
-           }
-           while (cp >= res) {
-               if (*cp == '\n') {
-                   *cp = ' ';
-               }
-               cp--;
-           }
-           Var_Set(line, res, ctxt);
-           free(res);
-
-       }
-       if (freeCmd) {
-           free(args[2]);
-       }
+       if (freeCmd)
+           free(cp);
     } else {
        /*
         * Normal assignment -- just do it.
         */
-       Var_Set (line, cp, ctxt);
+       Var_Set(line, cp, ctxt);
     }
 }
 
+
 /*-
  * ParseAddCmd  --
  *     Lst_ForEach function to add a command line to all targets
@@ -1735,7 +1636,7 @@ ParseDoInclude (file)
        char      *prefEnd, *Fname;
 
        /* Make a temporary copy of this, to be safe. */
-       Fname = strdup(fname);
+       Fname = estrdup(fname);
 
        prefEnd = strrchr (Fname, '/');
        if (prefEnd != (char *)NULL) {
@@ -1743,7 +1644,7 @@ ParseDoInclude (file)
            
            *prefEnd = '\0';
            if (file[0] == '/')
-               newName = strdup(file);
+               newName = estrdup(file);
            else
                newName = str_concat (Fname, file, STR_ADDSLASH);
            fullname = Dir_FindFile (newName, parseIncPath);
@@ -1860,7 +1761,7 @@ Parse_FromString(str)
     curPTR = (PTR *) emalloc (sizeof (PTR));
     curPTR->str = curPTR->ptr = str;
     lineno = 0;
-    fname = strdup(fname);
+    fname = estrdup(fname);
 }
 
 
index 868c0cb..300ad24 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: pathnames.h,v 1.4 1996/08/24 18:11:59 imp Exp $       */
-/*     $NetBSD: pathnames.h,v 1.4 1996/03/06 00:15:26 christos Exp $   */
+/*     $OpenBSD: pathnames.h,v 1.5 1996/09/02 16:04:18 briggs Exp $    */
+/*     $NetBSD: pathnames.h,v 1.5 1996/08/30 17:59:41 thorpej Exp $    */
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
index a2c045b..96b3db7 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: suff.c,v 1.3 1996/06/26 05:36:38 deraadt Exp $        */
-/*     $NetBSD: suff.c,v 1.11 1995/11/02 23:55:08 christos Exp $       */
+/*     $OpenBSD: suff.c,v 1.4 1996/09/02 16:04:19 briggs Exp $ */
+/*     $NetBSD: suff.c,v 1.12 1996/08/13 16:42:16 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)suff.c     5.6 (Berkeley) 6/1/90";
 #else
-static char rcsid[] = "$OpenBSD: suff.c,v 1.3 1996/06/26 05:36:38 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: suff.c,v 1.4 1996/09/02 16:04:19 briggs Exp $";
 #endif
 #endif /* not lint */
 
@@ -803,7 +803,7 @@ Suff_AddSuffix (str)
     if (ln == NILLNODE) {
        s = (Suff *) emalloc (sizeof (Suff));
 
-       s->name =       strdup (str);
+       s->name =       estrdup (str);
        s->nameLen =    strlen (s->name);
        s->searchPath = Lst_Init (FALSE);
        s->children =   Lst_Init (FALSE);
@@ -1010,7 +1010,7 @@ SuffAddSrc (sp, lsp)
         * that...
         */
        s2 = (Src *) emalloc (sizeof (Src));
-       s2->file =      strdup(targ->pref);
+       s2->file =      estrdup(targ->pref);
        s2->pref =      targ->pref;
        s2->parent =    targ;
        s2->node =      NILGNODE;
@@ -1273,7 +1273,7 @@ SuffFindCmds (targ, slst)
                     * again (ick)), and return the new structure.
                     */
                    ret = (Src *)emalloc (sizeof (Src));
-                   ret->file = strdup(s->name);
+                   ret->file = estrdup(s->name);
                    ret->pref = targ->pref;
                    ret->suff = suff;
                    suff->refCount++;
@@ -1863,7 +1863,7 @@ SuffFindNormalDeps(gn, slst)
             * Allocate a Src structure to which things can be transformed
             */
            targ = (Src *)emalloc(sizeof (Src));
-           targ->file = strdup(gn->name);
+           targ->file = estrdup(gn->name);
            targ->suff = (Suff *)Lst_Datum(ln);
            targ->suff->refCount++;
            targ->node = gn;
@@ -1908,13 +1908,13 @@ SuffFindNormalDeps(gn, slst)
        }
        
        targ = (Src *)emalloc(sizeof (Src));
-       targ->file = strdup(gn->name);
+       targ->file = estrdup(gn->name);
        targ->suff = suffNull;
        targ->suff->refCount++;
        targ->node = gn;
        targ->parent = (Src *)NULL;
        targ->children = 0;
-       targ->pref = strdup(sopref);
+       targ->pref = estrdup(sopref);
 #ifdef DEBUG_SRC
        targ->cp = Lst_Init(FALSE);
 #endif
@@ -2053,7 +2053,7 @@ sfnd_abort:
                gn->suffix->refCount++;
            if (gn->path != NULL)
                free(gn->path);
-           gn->path = strdup(gn->name);
+           gn->path = estrdup(gn->name);
        }
        
        goto sfnd_return;
@@ -2154,7 +2154,7 @@ sfnd_abort:
      */
     if (gn->path)
        free(gn->path);
-    gn->path = strdup(gn->name);
+    gn->path = estrdup(gn->name);
 
     /*
      * Nuke the transformation path and the Src structures left over in the
@@ -2335,7 +2335,7 @@ Suff_Init ()
      */
     emptySuff = suffNull = (Suff *) emalloc (sizeof (Suff));
 
-    suffNull->name =               strdup ("");
+    suffNull->name =               estrdup ("");
     suffNull->nameLen =     0;
     suffNull->searchPath =  Lst_Init (FALSE);
     Dir_Concat(suffNull->searchPath, dirSearchPath);
index 6d04770..198b27d 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: targ.c,v 1.3 1996/04/21 23:43:28 deraadt Exp $        */
-/*     $NetBSD: targ.c,v 1.7 1996/04/08 18:57:49 jtc Exp $     */
+/*     $OpenBSD: targ.c,v 1.4 1996/09/02 16:04:20 briggs Exp $ */
+/*     $NetBSD: targ.c,v 1.9 1996/08/30 17:59:43 thorpej Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -41,7 +41,7 @@
 
 #ifndef lint
 /* from: static char sccsid[] = "@(#)targ.c    5.9 (Berkeley) 3/1/91"; */
-static char *rcsid = "$Id: targ.c,v 1.3 1996/04/21 23:43:28 deraadt Exp $";
+static char *rcsid = "$Id: targ.c,v 1.4 1996/09/02 16:04:20 briggs Exp $";
 #endif /* not lint */
 
 /*-
@@ -162,7 +162,7 @@ Targ_NewGN (name)
     register GNode *gn;
 
     gn = (GNode *) emalloc (sizeof (GNode));
-    gn->name = strdup (name);
+    gn->name = estrdup (name);
     gn->path = (char *) 0;
     if (name[0] == '-' && name[1] == 'l') {
        gn->type = OP_LIB;
index 767551e..3023173 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: util.c,v 1.3 1996/06/26 05:36:38 deraadt Exp $        */
+/*     $OpenBSD: util.c,v 1.4 1996/09/02 16:04:21 briggs Exp $ */
 /*     $NetBSD: util.c,v 1.5 1995/11/22 17:40:17 christos Exp $        */
 
 /*
@@ -7,7 +7,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$OpenBSD: util.c,v 1.3 1996/06/26 05:36:38 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: util.c,v 1.4 1996/09/02 16:04:21 briggs Exp $";
 #endif
 
 #include <stdio.h>
@@ -40,7 +40,32 @@ strerror(e)
 }
 #endif
 
-#if defined(sun) || defined(__hpux)
+#ifdef ultrix
+#include <string.h>
+
+/* strdup
+ *
+ * Make a duplicate of a string.
+ * For systems which lack this function.
+ */
+char *
+strdup(str)
+    const char *str;
+{
+    size_t len;
+
+    if (str == NULL)
+       return NULL;
+    len = strlen(str) + 1;
+    if ((p = malloc(len)) == NULL)
+       return NULL;
+
+    return memcpy(p, str, len);
+}
+
+#endif
+
+#if defined(sun) || defined(__hpux) || defined(__sgi)
 
 int
 setenv(name, value, dum)
index 15ee8d7..06cc5ae 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: var.c,v 1.3 1996/06/26 05:36:39 deraadt Exp $ */
-/*     $NetBSD: var.c,v 1.12 1995/11/02 23:55:12 christos Exp $        */
+/*     $OpenBSD: var.c,v 1.4 1996/09/02 16:04:22 briggs Exp $  */
+/*     $NetBSD: var.c,v 1.14 1996/08/13 16:42:25 christos Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)var.c      5.7 (Berkeley) 6/1/90";
 #else
-static char rcsid[] = "$OpenBSD: var.c,v 1.3 1996/06/26 05:36:39 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: var.c,v 1.4 1996/09/02 16:04:22 briggs Exp $";
 #endif
 #endif /* not lint */
 
@@ -166,7 +166,9 @@ static Boolean VarTail __P((char *, Boolean, Buffer, ClientData));
 static Boolean VarSuffix __P((char *, Boolean, Buffer, ClientData));
 static Boolean VarRoot __P((char *, Boolean, Buffer, ClientData));
 static Boolean VarMatch __P((char *, Boolean, Buffer, ClientData));
+#ifdef SYSVVARSUB
 static Boolean VarSYSVMatch __P((char *, Boolean, Buffer, ClientData));
+#endif
 static Boolean VarNoMatch __P((char *, Boolean, Buffer, ClientData));
 static Boolean VarSubstitute __P((char *, Boolean, Buffer, ClientData));
 static char *VarModify __P((char *, Boolean (*)(char *, Boolean, Buffer,
@@ -280,7 +282,7 @@ VarFind (name, ctxt, flags)
            int         len;
            
            v = (Var *) emalloc(sizeof(Var));
-           v->name = strdup(name);
+           v->name = estrdup(name);
 
            len = strlen(env);
            
@@ -333,7 +335,7 @@ VarAdd (name, val, ctxt)
 
     v = (Var *) emalloc (sizeof (Var));
 
-    v->name = strdup (name);
+    v->name = estrdup (name);
 
     len = val ? strlen(val) : 0;
     v->val = Buf_Init(len+1);
@@ -783,8 +785,7 @@ VarMatch (word, addSpace, buf, pattern)
     return(addSpace);
 }
 
-
-
+#ifdef SYSVVARSUB
 /*-
  *-----------------------------------------------------------------------
  * VarSYSVMatch --
@@ -826,6 +827,7 @@ VarSYSVMatch (word, addSpace, buf, patp)
 
     return(addSpace);
 }
+#endif
 
 
 /*-
@@ -1634,7 +1636,22 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
                        break;
                    }
                    /*FALLTHRU*/
-               default: {
+#ifdef SUNSHCMD
+               case 's':
+                   if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
+                       char *err;
+                       newStr = Cmd_Exec (str, &err);
+                       if (err)
+                           Error (err, str);
+                       cp = tstr + 2;
+                       termc = *cp;
+                       break;
+                   }
+                   /*FALLTHRU*/
+#endif
+               default:
+               {
+#ifdef SYSVVARSUB
                    /*
                     * This can either be a bogus modifier or a System-V
                     * substitution command.
@@ -1701,7 +1718,9 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
                        pattern.lhs[pattern.leftLen] = '=';
                        pattern.rhs[pattern.rightLen] = endc;
                        termc = endc;
-                   } else {
+                   } else
+#endif
+                   {
                        Error ("Unknown modifier '%c'\n", *tstr);
                        for (cp = tstr+1;
                             *cp != ':' && *cp != endc && *cp != '\0';