[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/main.c between version 1.45 and 1.46

version 1.45, 2000/11/24 14:36:34 version 1.46, 2001/05/03 13:41:07
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenPackages$ */
   /*      $OpenBSD$ */
 /*      $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $    */  /*      $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $    */
   
 /*  /*
Line 92 
Line 93 
 #include "dir.h"  #include "dir.h"
 #include "job.h"  #include "job.h"
 #include "pathnames.h"  #include "pathnames.h"
   #include "stats.h"
   
 #ifndef lint  #ifndef lint
 UNUSED  UNUSED
Line 110 
Line 112 
 #endif /* not lint */  #endif /* not lint */
   
   
 #ifndef DEFMAXLOCAL  #ifndef DEFMAXLOCAL
 #define DEFMAXLOCAL DEFMAXJOBS  #define DEFMAXLOCAL DEFMAXJOBS
 #endif  /* DEFMAXLOCAL */  #endif  /* DEFMAXLOCAL */
   
 #define MAKEFLAGS       ".MAKEFLAGS"  #define MAKEFLAGS       ".MAKEFLAGS"
   
 LIST                    create;         /* Targets to be made */  LIST                    create;         /* Targets to be made */
 TIMESTAMP               now;            /* Time at start of make */  TIMESTAMP               now;            /* Time at start of make */
 GNode                   *DEFAULT;       /* .DEFAULT node */  GNode                   *DEFAULT;       /* .DEFAULT node */
 Boolean                 allPrecious;    /* .PRECIOUS given on line by itself */  Boolean                 allPrecious;    /* .PRECIOUS given on line by itself */
   
 static Boolean          noBuiltins;     /* -r flag */  static Boolean          noBuiltins;     /* -r flag */
 static LIST             makefiles;      /* ordered list of makefiles to read */  static LIST             makefiles;      /* ordered list of makefiles to read */
Line 127 
Line 129 
 static LIST             variables;      /* list of variables to print */  static LIST             variables;      /* list of variables to print */
 int                     maxJobs;        /* -j argument */  int                     maxJobs;        /* -j argument */
 static int              maxLocal;       /* -L argument */  static int              maxLocal;       /* -L argument */
 Boolean                 compatMake;     /* -B argument */  Boolean                 compatMake;     /* -B argument */
 Boolean                 debug;          /* -d flag */  Boolean                 debug;          /* -d flag */
 Boolean                 noExecute;      /* -n flag */  Boolean                 noExecute;      /* -n flag */
 Boolean                 keepgoing;      /* -k flag */  Boolean                 keepgoing;      /* -k flag */
 Boolean                 queryFlag;      /* -q flag */  Boolean                 queryFlag;      /* -q flag */
 Boolean                 touchFlag;      /* -t flag */  Boolean                 touchFlag;      /* -t flag */
 Boolean                 usePipes;       /* !-P flag */  Boolean                 usePipes;       /* !-P flag */
 Boolean                 ignoreErrors;   /* -i flag */  Boolean                 ignoreErrors;   /* -i flag */
 Boolean                 beSilent;       /* -s flag */  Boolean                 beSilent;       /* -s flag */
 Boolean                 oldVars;        /* variable substitution style */  Boolean                 oldVars;        /* variable substitution style */
 Boolean                 checkEnvFirst;  /* -e flag */  Boolean                 checkEnvFirst;  /* -e flag */
 static Boolean          jobsRunning;    /* TRUE if the jobs might be running */  static Boolean          jobsRunning;    /* TRUE if the jobs might be running */
   
 static void             MainParseArgs __P((int, char **));  static void             MainParseArgs(int, char **);
 char *                  chdir_verify_path __P((char *, char *));  static char *           chdir_verify_path(char *, char *);
 static int              ReadMakefile __P((void *, void *));  static int              ReadMakefile(void *, void *);
 static void             add_dirpath __P((Lst, const char *));  static void             add_dirpath(Lst, const char *);
 static void             usage __P((void));  static void             usage(void);
 static void             posixParseOptLetter __P((char));  static void             posixParseOptLetter(int);
 int                     main __P((int, char **));  
   
 static char *curdir;                    /* startup directory */  static char *curdir;                    /* startup directory */
 static char *objdir;                    /* where we chdir'ed to */  static char *objdir;                    /* where we chdir'ed to */
   
   
 static void  static void
 posixParseOptLetter(c)  posixParseOptLetter(c)
     char c;      int c;
 {  {
         switch(c) {          switch(c) {
         case 'B':          case 'B':
Line 213 
Line 215 
  *   *
  *      XXX: Deal with command line overriding .MAKEFLAGS in makefile   *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
  *   *
  * Results:  
  *      None  
  *  
  * Side Effects:   * Side Effects:
  *      Various global and local flags will be set depending on the flags   *      Various global and local flags will be set depending on the flags
  *      given   *      given
Line 237 
Line 236 
 # define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"  # define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
 #endif  #endif
 # define OPTLETTERS "BPSiknqrst"  # define OPTLETTERS "BPSiknqrst"
 rearg:  while((c = getopt(argc, argv, OPTFLAGS)) != -1) {  rearg:  while ((c = getopt(argc, argv, OPTFLAGS)) != -1) {
                 switch(c) {                  switch (c) {
                 case 'D':                  case 'D':
                         Var_Set(optarg, "1", VAR_GLOBAL);                          Var_Set(optarg, "1", VAR_GLOBAL);
                         Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);                          Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
Line 304 
Line 303 
                                 case 'j':                                  case 'j':
                                         debug |= DEBUG_JOB;                                          debug |= DEBUG_JOB;
                                         break;                                          break;
                                   case 'l':
                                           debug |= DEBUG_LOUD;
                                           break;
                                 case 'm':                                  case 'm':
                                         debug |= DEBUG_MAKE;                                          debug |= DEBUG_MAKE;
                                         break;                                          break;
Line 383 
Line 385 
                                 Punt("illegal (null) argument.");                                  Punt("illegal (null) argument.");
                         if (**argv == '-') {                          if (**argv == '-') {
                                 if ((*argv)[1])                                  if ((*argv)[1])
                                         optind = 0;     /* -flag... */                                          optind = 0;     /* -flag... */
                                 else                                  else
                                         optind = 1;     /* - */                                          optind = 1;     /* - */
                                 goto rearg;                                  goto rearg;
                         }                          }
                         Lst_AtEnd(&create, estrdup(*argv));                          Lst_AtEnd(&create, estrdup(*argv));
Line 394 
Line 396 
   
 /*-  /*-
  * Main_ParseArgLine --   * Main_ParseArgLine --
  *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target   *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
  *      is encountered and by main() when reading the .MAKEFLAGS envariable.   *      is encountered and by main() when reading the .MAKEFLAGS envariable.
  *      Takes a line of arguments and breaks it into its   *      Takes a line of arguments and breaks it into its
  *      component words and passes those words and the number of them to the   *      component words and passes those words and the number of them to the
  *      MainParseArgs function.   *      MainParseArgs function.
  *      The line should have all its leading whitespace removed.   *      The line should have all its leading whitespace removed.
  *   *
  * Results:  
  *      None  
  *  
  * Side Effects:   * Side Effects:
  *      Only those that come from the various arguments.   *      Only those that come from the various arguments.
  */   */
Line 418 
Line 417 
         char *argv0;          char *argv0;
         char *s;          char *s;
   
   
         if (line == NULL)          if (line == NULL)
                 return;                  return;
         for (; *line == ' '; ++line)          for (; *line == ' '; ++line)
Line 429 
Line 429 
          * any blanks or dashes. */           * any blanks or dashes. */
         for (s = line;; s++) {          for (s = line;; s++) {
                 if (*s == '\0') {                  if (*s == '\0') {
                         while (line != s)                          while (line != s)
                                 posixParseOptLetter(*line++);                                  posixParseOptLetter(*line++);
                         return;                          return;
                 }                  }
                 if (strchr(OPTLETTERS, *s) == NULL)                  if (strchr(OPTLETTERS, *s) == NULL)
                         break;                          break;
         }          }
         argv0 = Var_Value(".MAKE", VAR_GLOBAL);          argv0 = Var_Value(".MAKE");
         buf = emalloc(strlen(line) + strlen(argv0) + 2);          buf = emalloc(strlen(line) + strlen(argv0) + 2);
         (void)sprintf(buf, "%s %s", argv0, line);          (void)sprintf(buf, "%s %s", argv0, line);
   
         argv = brk_string(buf, &argc, TRUE, &args);          argv = brk_string(buf, &argc, &args);
         free(buf);          free(buf);
         MainParseArgs(argc, argv);          MainParseArgs(argc, argv);
   
Line 450 
Line 450 
   
 char *  char *
 chdir_verify_path(path, obpath)  chdir_verify_path(path, obpath)
         char *path;      char *path;
         char *obpath;      char *obpath;
 {  {
         struct stat sb;      struct stat sb;
   
         if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {      if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
                 if (chdir(path)) {          if (chdir(path)) {
                         (void)fprintf(stderr, "make warning: %s: %s.\n",              (void)fprintf(stderr, "make warning: %s: %s.\n",
                                       path, strerror(errno));                    path, strerror(errno));
                         return 0;              return NULL;
                 }          } else {
                 else {              if (path[0] != '/') {
                         if (path[0] != '/') {                  (void)snprintf(obpath, MAXPATHLEN, "%s/%s", curdir, path);
                                 (void) snprintf(obpath, MAXPATHLEN, "%s/%s",                  return obpath;
                                                 curdir, path);              }
                                 return obpath;              else
                         }                  return path;
                         else  
                                 return path;  
                 }  
         }          }
       }
   
         return 0;      return NULL;
 }  }
   
   
 /* Add a :-separated path to a Lst of directories.  */  /* Add a :-separated path to a Lst of directories.  */
 static void  static void
 add_dirpath(l, n)  add_dirpath(l, n)
     Lst         l;      Lst         l;
     const char  *n;      const char  *n;
 {  {
     const char *start;      const char *start;
     const char *cp;      const char *cp;
Line 495 
Line 494 
     }      }
 }  }
   
   int main(int, char **);
 /*-  /*-
  * main --   * main --
  *      The main function, for obvious reasons. Initializes variables   *      The main function, for obvious reasons. Initializes variables
Line 518 
Line 517 
         int argc;          int argc;
         char **argv;          char **argv;
 {  {
         LIST targs;     /* target nodes to create -- passed to Make_Init */          LIST targs;                     /* target nodes to create */
         Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */          Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
         struct stat sb, sa;          struct stat sb, sa;
         char *p, *path, *pathp, *pwd;          char *p, *path, *pathp, *pwd;
         char mdpath[MAXPATHLEN + 1];          char mdpath[MAXPATHLEN + 1];
         char obpath[MAXPATHLEN + 1];          char obpath[MAXPATHLEN + 1];
         char cdpath[MAXPATHLEN + 1];          char cdpath[MAXPATHLEN + 1];
         char *machine = getenv("MACHINE");          char *machine = getenv("MACHINE");
         char *machine_arch = getenv("MACHINE_ARCH");          char *machine_arch = getenv("MACHINE_ARCH");
                                         /* avoid faults on read-only strings */                                          /* avoid faults on read-only strings */
         static char syspath[] = _PATH_DEFSYSPATH;          static char syspath[] = _PATH_DEFSYSPATH;
   
         set_out_of_date(now);          set_out_of_date(now);
   #ifdef HAS_STATS
           Init_Stats();
   #endif
   
 #ifdef RLIMIT_NOFILE  #ifdef RLIMIT_NOFILE
         /*          /*
          * get rid of resource limit on file descriptors           * get rid of resource limit on file descriptors
Line 540 
Line 543 
                 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&                  if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
                     rl.rlim_cur != rl.rlim_max) {                      rl.rlim_cur != rl.rlim_max) {
                         rl.rlim_cur = rl.rlim_max;                          rl.rlim_cur = rl.rlim_max;
                         (void) setrlimit(RLIMIT_NOFILE, &rl);                          (void)setrlimit(RLIMIT_NOFILE, &rl);
                 }                  }
         }          }
 #endif  #endif
Line 564 
Line 567 
         if ((pwd = getenv("PWD")) != NULL) {          if ((pwd = getenv("PWD")) != NULL) {
             if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&              if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
                 sa.st_dev == sb.st_dev)                  sa.st_dev == sb.st_dev)
                 (void) strcpy(curdir, pwd);                  (void)strcpy(curdir, pwd);
         }          }
   
         /*          /*
Line 614 
Line 617 
                 if (!(path = getenv("MAKEOBJDIR"))) {                  if (!(path = getenv("MAKEOBJDIR"))) {
                         path = _PATH_OBJDIR;                          path = _PATH_OBJDIR;
                         pathp = _PATH_OBJDIRPREFIX;                          pathp = _PATH_OBJDIRPREFIX;
                         (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",                          (void)snprintf(mdpath, MAXPATHLEN, "%s.%s",
                                         path, machine);                                          path, machine);
                         if (!(objdir = chdir_verify_path(mdpath, obpath)))                          if (!(objdir = chdir_verify_path(mdpath, obpath)))
                                 if (!(objdir=chdir_verify_path(path, obpath))) {                                  if (!(objdir=chdir_verify_path(path, obpath))) {
                                         (void) snprintf(mdpath, MAXPATHLEN,                                          (void)snprintf(mdpath, MAXPATHLEN,
                                                         "%s%s", pathp, curdir);                                                          "%s%s", pathp, curdir);
                                         if (!(objdir=chdir_verify_path(mdpath,                                          if (!(objdir=chdir_verify_path(mdpath,
                                                                        obpath)))                                                                         obpath)))
Line 629 
Line 632 
                         objdir = curdir;                          objdir = curdir;
         }          }
         else {          else {
                 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);                  (void)snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
                 if (!(objdir = chdir_verify_path(mdpath, obpath)))                  if (!(objdir = chdir_verify_path(mdpath, obpath)))
                         objdir = curdir;                          objdir = curdir;
         }          }
Line 653 
Line 656 
         debug = 0;                      /* No debug verbosity, please. */          debug = 0;                      /* No debug verbosity, please. */
         jobsRunning = FALSE;          jobsRunning = FALSE;
   
         maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */          maxLocal = DEFMAXLOCAL;         /* Set default local max concurrency */
 #ifdef REMOTE  #ifdef REMOTE
         maxJobs = DEFMAXJOBS;           /* Set default max concurrency */          maxJobs = DEFMAXJOBS;           /* Set default max concurrency */
 #else  #else
Line 692 
Line 695 
         Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);          Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
   
         /*          /*
          * First snag any flags out of the MAKE environment variable.           * First snag any flags out of the MAKEFLAGS environment variable.
          * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's  
          * in a different format).  
          */           */
 #ifdef POSIX  
         Main_ParseArgLine(getenv("MAKEFLAGS"));          Main_ParseArgLine(getenv("MAKEFLAGS"));
 #else  
         Main_ParseArgLine(getenv("MAKE"));  
 #endif  
   
         MainParseArgs(argc, argv);          MainParseArgs(argc, argv);
   
 #ifdef POSIX          /* And set up everything for sub-makes */
         Var_AddCmdline(MAKEFLAGS);          Var_AddCmdline(MAKEFLAGS);
 #endif  
   
   
         /*          /*
          * Initialize archive, target and suffix modules in preparation for           * Initialize archive, target and suffix modules in preparation for
          * parsing the makefile(s)           * parsing the makefile(s)
Line 746 
Line 743 
   
         /*          /*
          * Read in the built-in rules first, followed by the specified           * Read in the built-in rules first, followed by the specified
          * makefile, if it was (makefile != (char *) NULL), or the default           * makefile, if it was (makefile != (char *)NULL), or the default
          * Makefile and makefile, in that order, if it wasn't.           * Makefile and makefile, in that order, if it wasn't.
          */           */
         if (!noBuiltins) {          if (!noBuiltins) {
                 LstNode ln;                  LstNode ln;
                 LIST sysMkPath;         /* Path of sys.mk */                  LIST sysMkPath;                 /* Path of sys.mk */
   
                 Lst_Init(&sysMkPath);                  Lst_Init(&sysMkPath);
                 Dir_Expand(_PATH_DEFSYSMK, &sysIncPath, &sysMkPath);                  Dir_Expand(_PATH_DEFSYSMK, &sysIncPath, &sysMkPath);
Line 777 
Line 774 
   
         (void)ReadMakefile(".depend", NULL);          (void)ReadMakefile(".depend", NULL);
   
         Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);          Var_Append("MFLAGS", Var_Value(MAKEFLAGS),
               VAR_GLOBAL);
   
         /* Install all the flags into the MAKE envariable. */          /* Install all the flags into the MAKEFLAGS env variable. */
         if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL)) != NULL) && *p)          if (((p = Var_Value(MAKEFLAGS)) != NULL) && *p)
 #ifdef POSIX  
                 esetenv("MAKEFLAGS", p);                  esetenv("MAKEFLAGS", p);
 #else  
                 esetenv("MAKE", p);  
 #endif  
   
         /*          /*
          * For compatibility, look at the directories in the VPATH variable           * For compatibility, look at the directories in the VPATH variable
Line 793 
Line 787 
          * variable's value is in the same format as the PATH envariable, i.e.           * variable's value is in the same format as the PATH envariable, i.e.
          * <directory>:<directory>:<directory>...           * <directory>:<directory>:<directory>...
          */           */
         if (Var_Exists("VPATH", VAR_CMD)) {          if (Var_Value("VPATH") != NULL) {
                 char *vpath;              char *vpath;
                 /*  
                  * GCC stores string constants in read-only memory, but  
                  * Var_Subst will want to write this thing, so store it  
                  * in an array  
                  */  
                 static char VPATH[] = "${VPATH}";  
   
                 vpath = Var_Subst(VPATH, (SymTable *)VAR_CMD, FALSE);              vpath = Var_Subst("${VPATH}", NULL, FALSE);
                 add_dirpath(&dirSearchPath, vpath);              add_dirpath(&dirSearchPath, vpath);
                 (void)free(vpath);              (void)free(vpath);
         }          }
   
         /*          /* Now that all search paths have been read for suffixes et al, it's
          * Now that all search paths have been read for suffixes et al, it's           * time to add the default search path to their lists...  */
          * time to add the default search path to their lists...  
          */  
         Suff_DoPaths();          Suff_DoPaths();
   
         /* print the initial graph, if the user requested it */          /* Print the initial graph, if the user requested it.  */
         if (DEBUG(GRAPH1))          if (DEBUG(GRAPH1))
                 Targ_PrintGraph(1);                  Targ_PrintGraph(1);
   
         /* print the values of any variables requested by the user */          /* Print the values of any variables requested by the user.  */
         if (printVars) {          if (printVars) {
                 LstNode ln;                  LstNode ln;
   
                 for (ln = Lst_First(&variables); ln != NULL; ln = Lst_Adv(ln)) {                  for (ln = Lst_First(&variables); ln != NULL; ln = Lst_Adv(ln)) {
                         char *value = Var_Value((char *)Lst_Datum(ln),                          char *value = Var_Value((char *)Lst_Datum(ln));
                                           VAR_GLOBAL);  
   
                         printf("%s\n", value ? value : "");                          printf("%s\n", value ? value : "");
                 }                  }
         }          }
   
         /*          /* Have now read the entire graph and need to make a list of targets
          * Have now read the entire graph and need to make a list of targets  
          * to create. If none was given on the command line, we consult the           * to create. If none was given on the command line, we consult the
          * parsing module to find the main target(s) to create.           * parsing module to find the main target(s) to create.  */
          */  
         Lst_Init(&targs);          Lst_Init(&targs);
         if (!Lst_IsEmpty(&create))          if (!Lst_IsEmpty(&create))
                 Targ_FindList(&targs, &create);                  Targ_FindList(&targs, &create);
Line 841 
Line 824 
                 Parse_MainName(&targs);                  Parse_MainName(&targs);
   
         if (!compatMake && !printVars) {          if (!compatMake && !printVars) {
                 /*                  /* Initialize job module before traversing the graph, now that
                  * Initialize job module before traversing the graph, now that                   * any .BEGIN and .END targets have been read.  This is done
                  * any .BEGIN and .END targets have been read.  This is done  
                  * only if the -q flag wasn't given (to prevent the .BEGIN from                   * only if the -q flag wasn't given (to prevent the .BEGIN from
                  * being executed should it exist).                   * being executed should it exist).  */
                  */  
                 if (!queryFlag) {                  if (!queryFlag) {
                         if (maxLocal == -1)                          if (maxLocal == -1)
                                 maxLocal = maxJobs;                                  maxLocal = maxJobs;
Line 854 
Line 835 
                         jobsRunning = TRUE;                          jobsRunning = TRUE;
                 }                  }
   
                 /* Traverse the graph, checking on all the targets */                  /* Traverse the graph, checking on all the targets.  */
                 outOfDate = Make_Run(&targs);                  outOfDate = Make_Run(&targs);
         } else if (!printVars) {          } else if (!printVars) {
                 /*                  /* Compat_Init will take care of creating all the targets as
                  * Compat_Init will take care of creating all the targets as                   * well as initializing the module.  */
                  * well as initializing the module.  
                  */  
                 Compat_Run(&targs);                  Compat_Run(&targs);
         }          }
   
Line 874 
Line 853 
                 Targ_PrintGraph(2);                  Targ_PrintGraph(2);
   
         Suff_End();          Suff_End();
         Targ_End();          Targ_End();
         Arch_End();          Arch_End();
         Var_End();          Var_End();
         Parse_End();          Parse_End();
Line 882 
Line 861 
         Job_End();          Job_End();
   
         if (queryFlag && outOfDate)          if (queryFlag && outOfDate)
                 return(1);                  return 1;
         else          else
                 return(0);                  return 0;
 }  }
   
 /*-  /*-
Line 899 
Line 878 
  */   */
 static Boolean  static Boolean
 ReadMakefile(p, q)  ReadMakefile(p, q)
         void *p;          void * p;
         void *q;          void * q                UNUSED;
 {  {
         char *fname = p;                /* makefile to read */          char *fname = p;                /* makefile to read */
         extern LIST parseIncPath;          extern LIST parseIncPath;
Line 908 
Line 887 
         char *name, path[MAXPATHLEN + 1];          char *name, path[MAXPATHLEN + 1];
   
         if (!strcmp(fname, "-")) {          if (!strcmp(fname, "-")) {
                 Parse_File(estrdup("(stdin)"), stdin);  
                 Var_Set("MAKEFILE", "", VAR_GLOBAL);                  Var_Set("MAKEFILE", "", VAR_GLOBAL);
                   Parse_File(estrdup("(stdin)"), stdin);
         } else {          } else {
                 if ((stream = fopen(fname, "r")) != NULL)                  if ((stream = fopen(fname, "r")) != NULL)
                         goto found;                          goto found;
Line 926 
Line 905 
                 if (!name)                  if (!name)
                         name = Dir_FindFile(fname, &sysIncPath);                          name = Dir_FindFile(fname, &sysIncPath);
                 if (!name || !(stream = fopen(name, "r")))                  if (!name || !(stream = fopen(name, "r")))
                         return(FALSE);                          return FALSE;
                 fname = name;                  fname = name;
                 /*                  /*
                  * set the MAKEFILE variable desired by System V fans -- the                   * set the MAKEFILE variable desired by System V fans -- the
Line 937 
Line 916 
                 Parse_File(fname, stream);                  Parse_File(fname, stream);
                 (void)fclose(stream);                  (void)fclose(stream);
         }          }
         return(TRUE);          return TRUE;
 }  }
   
 /*-  /*-
Line 954 
Line 933 
  */   */
 char *  char *
 Cmd_Exec(cmd, err)  Cmd_Exec(cmd, err)
     char *cmd;      const char *cmd;
     char **err;      char **err;
 {  {
     char        *args[4];       /* Args for invoking the shell */      char        *args[4];       /* Args for invoking the shell */
     int         fds[2];         /* Pipe streams */      int         fds[2];         /* Pipe streams */
     int         cpid;           /* Child PID */      int         cpid;           /* Child PID */
     int         pid;            /* PID from wait() */      int         pid;            /* PID from wait() */
     char        *res;           /* result */      char        *res;           /* result */
     int         status;         /* command exit status */      int         status;         /* command exit status */
     BUFFER      buf;            /* buffer to store the result */      BUFFER      buf;            /* buffer to store the result */
     char        *cp;      char        *cp;
     ssize_t     cc;      ssize_t     cc;
     size_t      length;      size_t      length;
   
   
     *err = NULL;      *err = NULL;
Line 976 
Line 955 
      */       */
     args[0] = "sh";      args[0] = "sh";
     args[1] = "-c";      args[1] = "-c";
     args[2] = cmd;      args[2] = (char *)cmd;
     args[3] = NULL;      args[3] = NULL;
   
     /*      /*
Line 995 
Line 974 
         /*          /*
          * Close input side of pipe           * Close input side of pipe
          */           */
         (void) close(fds[0]);          (void)close(fds[0]);
   
         /*          /*
          * Duplicate the output stream to the shell's output, then           * Duplicate the output stream to the shell's output, then
          * shut the extra thing down. Note we don't fetch the error           * shut the extra thing down. Note we don't fetch the error
          * stream...why not? Why?           * stream...why not? Why?
          */           */
         (void) dup2(fds[1], 1);          (void)dup2(fds[1], 1);
         (void) close(fds[1]);          if (fds[1] != 1)
               (void)close(fds[1]);
   
         (void) execv("/bin/sh", args);          (void)execv("/bin/sh", args);
         _exit(1);          _exit(1);
         /*NOTREACHED*/          /*NOTREACHED*/
   
Line 1017 
Line 997 
         /*          /*
          * No need for the writing half           * No need for the writing half
          */           */
         (void) close(fds[1]);          (void)close(fds[1]);
   
         Buf_Init(&buf, MAKE_BSIZE);          Buf_Init(&buf, MAKE_BSIZE);
   
Line 1032 
Line 1012 
         /*          /*
          * Close the input side of the pipe.           * Close the input side of the pipe.
          */           */
         (void) close(fds[0]);          (void)close(fds[0]);
   
         /*          /*
          * Wait for the process to exit.           * Wait for the process to exit.
          */           */
         while(((pid = wait(&status)) != cpid) && (pid >= 0))          while ((pid = wait(&status)) != cpid && pid >= 0)
             continue;              continue;
   
         res = Buf_Retrieve(&buf);  
         length = Buf_Size(&buf);  
   
         if (cc == -1)          if (cc == -1)
             *err = "Couldn't read shell's output for \"%s\"";              *err = "Couldn't read shell's output for \"%s\"";
   
         if (status)          if (status)
             *err = "\"%s\" returned non-zero status";              *err = "\"%s\" returned non-zero status";
   
         /*          length = Buf_Size(&buf);
          * Null-terminate the result, convert newlines to spaces and          res = Buf_Retrieve(&buf);
          * install it in the variable.  
          */          /* The result is null terminated, Convert newlines to spaces and
         res[length] = '\0';           * install in the variable.  */
         cp = res + length - 1;          cp = res + length - 1;
   
         if (*cp == '\n') {          if (*cp == '\n')
             /*              /* A final newline is just stripped.  */
              * A final newline is just stripped  
              */  
             *cp-- = '\0';              *cp-- = '\0';
         }  
         while (cp >= res) {          while (cp >= res) {
             if (*cp == '\n') {              if (*cp == '\n')
                 *cp = ' ';                  *cp = ' ';
             }  
             cp--;              cp--;
         }          }
         break;          break;
     }      }
     return res;      return res;
 bad:  bad:
     res = emalloc(1);      return estrdup("");
     *res = '\0';  
     return res;  
 }  }
   
 /*-  /*-
  * Error --   * Error --
  *      Print an error message given its format.   *      Print an error message given its format.
  *  
  * Results:  
  *      None.  
  *  
  * Side Effects:  
  *      The message is printed.  
  */   */
 /* VARARGS */  /* VARARGS */
 void  void
Line 1108 
Line 1074 
         (void)vfprintf(stderr, fmt, ap);          (void)vfprintf(stderr, fmt, ap);
         va_end(ap);          va_end(ap);
         (void)fprintf(stderr, "\n");          (void)fprintf(stderr, "\n");
         (void)fflush(stderr);  
 }  }
   
 /*-  /*-
Line 1116 
Line 1081 
  *      Produce a Fatal error message. If jobs are running, waits for them   *      Produce a Fatal error message. If jobs are running, waits for them
  *      to finish.   *      to finish.
  *   *
  * Results:  
  *      None  
  *  
  * Side Effects:   * Side Effects:
  *      The program exits   *      The program exits
  */   */
Line 1146 
Line 1108 
         (void)vfprintf(stderr, fmt, ap);          (void)vfprintf(stderr, fmt, ap);
         va_end(ap);          va_end(ap);
         (void)fprintf(stderr, "\n");          (void)fprintf(stderr, "\n");
         (void)fflush(stderr);  
   
         if (DEBUG(GRAPH2))          if (DEBUG(GRAPH2))
                 Targ_PrintGraph(2);                  Targ_PrintGraph(2);
Line 1158 
Line 1119 
  *      Major exception once jobs are being created. Kills all jobs, prints   *      Major exception once jobs are being created. Kills all jobs, prints
  *      a message and exits.   *      a message and exits.
  *   *
  * Results:  
  *      None  
  *  
  * Side Effects:   * Side Effects:
  *      All children are killed indiscriminately and the program Lib_Exits   *      All children are killed indiscriminately and the program Lib_Exits
  */   */
Line 1187 
Line 1145 
         (void)vfprintf(stderr, fmt, ap);          (void)vfprintf(stderr, fmt, ap);
         va_end(ap);          va_end(ap);
         (void)fprintf(stderr, "\n");          (void)fprintf(stderr, "\n");
         (void)fflush(stderr);  
   
         DieHorribly();          DieHorribly();
 }  }
Line 1196 
Line 1153 
  * DieHorribly --   * DieHorribly --
  *      Exit without giving a message.   *      Exit without giving a message.
  *   *
  * Results:  
  *      None  
  *  
  * Side Effects:   * Side Effects:
  *      A big one...   *      A big one...
  */   */
Line 1217 
Line 1171 
  *      Called when aborting due to errors in child shell to signal   *      Called when aborting due to errors in child shell to signal
  *      abnormal exit.   *      abnormal exit.
  *   *
  * Results:  
  *      None  
  *  
  * Side Effects:   * Side Effects:
  *      The program exits   *      The program exits
  */   */
Line 1230 
Line 1181 
         Fatal("%d error%s", errors, errors == 1 ? "" : "s");          Fatal("%d error%s", errors, errors == 1 ? "" : "s");
 }  }
   
   
 /*  /*
  * usage --   * usage --
  *      exit with usage message   *      exit with usage message
Line 1239 
Line 1191 
 {  {
         (void)fprintf(stderr,          (void)fprintf(stderr,
 "usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\  "usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
             [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\              [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
             [variable=value] [target ...]\n");              [variable=value] [target ...]\n");
         exit(2);          exit(2);
 }  }
   
Line 1249 
Line 1201 
 PrintAddr(a)  PrintAddr(a)
     void *a;      void *a;
 {  {
     printf("%lx ", (unsigned long) a);      printf("%lx ", (unsigned long)a);
 }  }

Legend:
Removed from v.1.45  
changed lines
  Added in v.1.46