]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/main.c
Update to bmake-20200902
[FreeBSD/FreeBSD.git] / contrib / bmake / main.c
1 /*      $NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $        */
2
3 /*
4  * Copyright (c) 1988, 1989, 1990, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Adam de Boor.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 /*
36  * Copyright (c) 1989 by Berkeley Softworks
37  * All rights reserved.
38  *
39  * This code is derived from software contributed to Berkeley by
40  * Adam de Boor.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions
44  * are met:
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in the
49  *    documentation and/or other materials provided with the distribution.
50  * 3. All advertising materials mentioning features or use of this software
51  *    must display the following acknowledgement:
52  *      This product includes software developed by the University of
53  *      California, Berkeley and its contributors.
54  * 4. Neither the name of the University nor the names of its contributors
55  *    may be used to endorse or promote products derived from this software
56  *    without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68  * SUCH DAMAGE.
69  */
70
71 #ifndef MAKE_NATIVE
72 static char rcsid[] = "$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $";
73 #else
74 #include <sys/cdefs.h>
75 #ifndef lint
76 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
77  The Regents of the University of California.  All rights reserved.");
78 #endif /* not lint */
79
80 #ifndef lint
81 #if 0
82 static char sccsid[] = "@(#)main.c      8.3 (Berkeley) 3/19/94";
83 #else
84 __RCSID("$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $");
85 #endif
86 #endif /* not lint */
87 #endif
88
89 /*-
90  * main.c --
91  *      The main file for this entire program. Exit routines etc
92  *      reside here.
93  *
94  * Utility functions defined in this file:
95  *      Main_ParseArgLine       Takes a line of arguments, breaks them and
96  *                              treats them as if they were given when first
97  *                              invoked. Used by the parse module to implement
98  *                              the .MFLAGS target.
99  *
100  *      Error                   Print a tagged error message. The global
101  *                              MAKE variable must have been defined. This
102  *                              takes a format string and optional arguments
103  *                              for it.
104  *
105  *      Fatal                   Print an error message and exit. Also takes
106  *                              a format string and arguments for it.
107  *
108  *      Punt                    Aborts all jobs and exits with a message. Also
109  *                              takes a format string and arguments for it.
110  *
111  *      Finish                  Finish things up by printing the number of
112  *                              errors which occurred, as passed to it, and
113  *                              exiting.
114  */
115
116 #include <sys/types.h>
117 #include <sys/time.h>
118 #include <sys/param.h>
119 #include <sys/resource.h>
120 #include <sys/stat.h>
121 #if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL)
122 #include <sys/sysctl.h>
123 #endif
124 #include <sys/utsname.h>
125 #include "wait.h"
126
127 #include <ctype.h>
128 #include <errno.h>
129 #include <signal.h>
130 #include <stdarg.h>
131 #include <stdio.h>
132 #include <stdlib.h>
133 #include <time.h>
134
135 #include "make.h"
136 #include "hash.h"
137 #include "dir.h"
138 #include "job.h"
139 #include "pathnames.h"
140 #include "trace.h"
141
142 #ifdef USE_IOVEC
143 #include <sys/uio.h>
144 #endif
145
146 #ifndef DEFMAXLOCAL
147 #define DEFMAXLOCAL DEFMAXJOBS
148 #endif  /* DEFMAXLOCAL */
149
150 #ifndef __arraycount
151 # define __arraycount(__x)      (sizeof(__x) / sizeof(__x[0]))
152 #endif
153
154 Lst                     create;         /* Targets to be made */
155 time_t                  now;            /* Time at start of make */
156 GNode                   *DEFAULT;       /* .DEFAULT node */
157 Boolean                 allPrecious;    /* .PRECIOUS given on line by itself */
158 Boolean                 deleteOnError;  /* .DELETE_ON_ERROR: set */
159
160 static Boolean          noBuiltins;     /* -r flag */
161 static Lst              makefiles;      /* ordered list of makefiles to read */
162 static int              printVars;      /* -[vV] argument */
163 #define COMPAT_VARS 1
164 #define EXPAND_VARS 2
165 static Lst              variables;      /* list of variables to print
166                                          * (for -v and -V) */
167 int                     maxJobs;        /* -j argument */
168 static int              maxJobTokens;   /* -j argument */
169 Boolean                 compatMake;     /* -B argument */
170 int                     debug;          /* -d argument */
171 Boolean                 debugVflag;     /* -dV */
172 Boolean                 noExecute;      /* -n flag */
173 Boolean                 noRecursiveExecute;     /* -N flag */
174 Boolean                 keepgoing;      /* -k flag */
175 Boolean                 queryFlag;      /* -q flag */
176 Boolean                 touchFlag;      /* -t flag */
177 Boolean                 enterFlag;      /* -w flag */
178 Boolean                 enterFlagObj;   /* -w and objdir != srcdir */
179 Boolean                 ignoreErrors;   /* -i flag */
180 Boolean                 beSilent;       /* -s flag */
181 Boolean                 oldVars;        /* variable substitution style */
182 Boolean                 checkEnvFirst;  /* -e flag */
183 Boolean                 parseWarnFatal; /* -W flag */
184 static int jp_0 = -1, jp_1 = -1;        /* ends of parent job pipe */
185 Boolean                 varNoExportEnv; /* -X flag */
186 Boolean                 doing_depend;   /* Set while reading .depend */
187 static Boolean          jobsRunning;    /* TRUE if the jobs might be running */
188 static const char *     tracefile;
189 static void             MainParseArgs(int, char **);
190 static int              ReadMakefile(const char *);
191 static void             usage(void) MAKE_ATTR_DEAD;
192 static void             purge_cached_realpaths(void);
193
194 static Boolean          ignorePWD;      /* if we use -C, PWD is meaningless */
195 static char objdir[MAXPATHLEN + 1];     /* where we chdir'ed to */
196 char curdir[MAXPATHLEN + 1];            /* Startup directory */
197 char *progname;                         /* the program name */
198 char *makeDependfile;
199 pid_t myPid;
200 int makelevel;
201
202 FILE *debug_file;
203
204 Boolean forceJobs = FALSE;
205
206 /*
207  * On some systems MACHINE is defined as something other than
208  * what we want.
209  */
210 #ifdef FORCE_MACHINE
211 # undef MACHINE
212 # define MACHINE FORCE_MACHINE
213 #endif
214
215 extern Lst parseIncPath;
216
217 /*
218  * For compatibility with the POSIX version of MAKEFLAGS that includes
219  * all the options with out -, convert flags to -f -l -a -g -s.
220  */
221 static char *
222 explode(const char *flags)
223 {
224     size_t len;
225     char *nf, *st;
226     const char *f;
227
228     if (flags == NULL)
229         return NULL;
230
231     for (f = flags; *f; f++)
232         if (!isalpha((unsigned char)*f))
233             break;
234
235     if (*f)
236         return bmake_strdup(flags);
237
238     len = strlen(flags);
239     st = nf = bmake_malloc(len * 3 + 1);
240     while (*flags) {
241         *nf++ = '-';
242         *nf++ = *flags++;
243         *nf++ = ' ';
244     }
245     *nf = '\0';
246     return st;
247 }
248
249 static void
250 parse_debug_options(const char *argvalue)
251 {
252         const char *modules;
253         const char *mode;
254         char *fname;
255         int len;
256
257         for (modules = argvalue; *modules; ++modules) {
258                 switch (*modules) {
259                 case 'A':
260                         debug = ~(0|DEBUG_LINT);
261                         break;
262                 case 'a':
263                         debug |= DEBUG_ARCH;
264                         break;
265                 case 'C':
266                         debug |= DEBUG_CWD;
267                         break;
268                 case 'c':
269                         debug |= DEBUG_COND;
270                         break;
271                 case 'd':
272                         debug |= DEBUG_DIR;
273                         break;
274                 case 'e':
275                         debug |= DEBUG_ERROR;
276                         break;
277                 case 'f':
278                         debug |= DEBUG_FOR;
279                         break;
280                 case 'g':
281                         if (modules[1] == '1') {
282                                 debug |= DEBUG_GRAPH1;
283                                 ++modules;
284                         }
285                         else if (modules[1] == '2') {
286                                 debug |= DEBUG_GRAPH2;
287                                 ++modules;
288                         }
289                         else if (modules[1] == '3') {
290                                 debug |= DEBUG_GRAPH3;
291                                 ++modules;
292                         }
293                         break;
294                 case 'h':
295                         debug |= DEBUG_HASH;
296                         break;
297                 case 'j':
298                         debug |= DEBUG_JOB;
299                         break;
300                 case 'L':
301                         debug |= DEBUG_LINT;
302                         break;
303                 case 'l':
304                         debug |= DEBUG_LOUD;
305                         break;
306                 case 'M':
307                         debug |= DEBUG_META;
308                         break;
309                 case 'm':
310                         debug |= DEBUG_MAKE;
311                         break;
312                 case 'n':
313                         debug |= DEBUG_SCRIPT;
314                         break;
315                 case 'p':
316                         debug |= DEBUG_PARSE;
317                         break;
318                 case 's':
319                         debug |= DEBUG_SUFF;
320                         break;
321                 case 't':
322                         debug |= DEBUG_TARG;
323                         break;
324                 case 'V':
325                         debugVflag = TRUE;
326                         break;
327                 case 'v':
328                         debug |= DEBUG_VAR;
329                         break;
330                 case 'x':
331                         debug |= DEBUG_SHELL;
332                         break;
333                 case 'F':
334                         if (debug_file != stdout && debug_file != stderr)
335                                 fclose(debug_file);
336                         if (*++modules == '+') {
337                                 modules++;
338                                 mode = "a";
339                         } else
340                                 mode = "w";
341                         if (strcmp(modules, "stdout") == 0) {
342                                 debug_file = stdout;
343                                 goto debug_setbuf;
344                         }
345                         if (strcmp(modules, "stderr") == 0) {
346                                 debug_file = stderr;
347                                 goto debug_setbuf;
348                         }
349                         len = strlen(modules);
350                         fname = bmake_malloc(len + 20);
351                         memcpy(fname, modules, len + 1);
352                         /* Let the filename be modified by the pid */
353                         if (strcmp(fname + len - 3, ".%d") == 0)
354                                 snprintf(fname + len - 2, 20, "%d", getpid());
355                         debug_file = fopen(fname, mode);
356                         if (!debug_file) {
357                                 fprintf(stderr, "Cannot open debug file %s\n",
358                                     fname);
359                                 usage();
360                         }
361                         free(fname);
362                         goto debug_setbuf;
363                 default:
364                         (void)fprintf(stderr,
365                             "%s: illegal argument to d option -- %c\n",
366                             progname, *modules);
367                         usage();
368                 }
369         }
370 debug_setbuf:
371         /*
372          * Make the debug_file unbuffered, and make
373          * stdout line buffered (unless debugfile == stdout).
374          */
375         setvbuf(debug_file, NULL, _IONBF, 0);
376         if (debug_file != stdout) {
377                 setvbuf(stdout, NULL, _IOLBF, 0);
378         }
379 }
380
381 /*
382  * does path contain any relative components
383  */
384 static Boolean
385 is_relpath(const char *path)
386 {
387         const char *cp;
388
389         if (path[0] != '/')
390                 return TRUE;
391         cp = path;
392         while ((cp = strstr(cp, "/.")) != NULL) {
393                 cp += 2;
394                 if (cp[0] == '/' || cp[0] == '\0')
395                         return TRUE;
396                 else if (cp[0] == '.') {
397                         if (cp[1] == '/' || cp[1] == '\0')
398                                 return TRUE;
399                 }
400         }
401         return FALSE;
402 }
403
404 /*-
405  * MainParseArgs --
406  *      Parse a given argument vector. Called from main() and from
407  *      Main_ParseArgLine() when the .MAKEFLAGS target is used.
408  *
409  *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
410  *
411  * Results:
412  *      None
413  *
414  * Side Effects:
415  *      Various global and local flags will be set depending on the flags
416  *      given
417  */
418 static void
419 MainParseArgs(int argc, char **argv)
420 {
421         char *p;
422         char c = '?';
423         int arginc;
424         char *argvalue;
425         const char *getopt_def;
426         struct stat sa, sb;
427         char *optscan;
428         Boolean inOption, dashDash = FALSE;
429         char found_path[MAXPATHLEN + 1];        /* for searching for sys.mk */
430
431 #define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstv:w"
432 /* Can't actually use getopt(3) because rescanning is not portable */
433
434         getopt_def = OPTFLAGS;
435 rearg:
436         inOption = FALSE;
437         optscan = NULL;
438         while(argc > 1) {
439                 char *getopt_spec;
440                 if(!inOption)
441                         optscan = argv[1];
442                 c = *optscan++;
443                 arginc = 0;
444                 if(inOption) {
445                         if(c == '\0') {
446                                 ++argv;
447                                 --argc;
448                                 inOption = FALSE;
449                                 continue;
450                         }
451                 } else {
452                         if (c != '-' || dashDash)
453                                 break;
454                         inOption = TRUE;
455                         c = *optscan++;
456                 }
457                 /* '-' found at some earlier point */
458                 getopt_spec = strchr(getopt_def, c);
459                 if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
460                         /* -<something> found, and <something> should have an arg */
461                         inOption = FALSE;
462                         arginc = 1;
463                         argvalue = optscan;
464                         if(*argvalue == '\0') {
465                                 if (argc < 3)
466                                         goto noarg;
467                                 argvalue = argv[2];
468                                 arginc = 2;
469                         }
470                 } else {
471                         argvalue = NULL;
472                 }
473                 switch(c) {
474                 case '\0':
475                         arginc = 1;
476                         inOption = FALSE;
477                         break;
478                 case 'B':
479                         compatMake = TRUE;
480                         Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
481                         Var_Set(MAKE_MODE, "compat", VAR_GLOBAL);
482                         break;
483                 case 'C':
484                         if (chdir(argvalue) == -1) {
485                                 (void)fprintf(stderr,
486                                               "%s: chdir %s: %s\n",
487                                               progname, argvalue,
488                                               strerror(errno));
489                                 exit(1);
490                         }
491                         if (getcwd(curdir, MAXPATHLEN) == NULL) {
492                                 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
493                                 exit(2);
494                         }
495                         if (!is_relpath(argvalue) &&
496                             stat(argvalue, &sa) != -1 &&
497                             stat(curdir, &sb) != -1 &&
498                             sa.st_ino == sb.st_ino &&
499                             sa.st_dev == sb.st_dev)
500                                 strncpy(curdir, argvalue, MAXPATHLEN);
501                         ignorePWD = TRUE;
502                         break;
503                 case 'D':
504                         if (argvalue == NULL || argvalue[0] == 0) goto noarg;
505                         Var_Set(argvalue, "1", VAR_GLOBAL);
506                         Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
507                         Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
508                         break;
509                 case 'I':
510                         if (argvalue == NULL) goto noarg;
511                         Parse_AddIncludeDir(argvalue);
512                         Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
513                         Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
514                         break;
515                 case 'J':
516                         if (argvalue == NULL) goto noarg;
517                         if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
518                             (void)fprintf(stderr,
519                                 "%s: internal error -- J option malformed (%s)\n",
520                                 progname, argvalue);
521                                 usage();
522                         }
523                         if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
524                             (fcntl(jp_1, F_GETFD, 0) < 0)) {
525 #if 0
526                             (void)fprintf(stderr,
527                                 "%s: ###### warning -- J descriptors were closed!\n",
528                                 progname);
529                             exit(2);
530 #endif
531                             jp_0 = -1;
532                             jp_1 = -1;
533                             compatMake = TRUE;
534                         } else {
535                             Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
536                             Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
537                         }
538                         break;
539                 case 'N':
540                         noExecute = TRUE;
541                         noRecursiveExecute = TRUE;
542                         Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
543                         break;
544                 case 'S':
545                         keepgoing = FALSE;
546                         Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
547                         break;
548                 case 'T':
549                         if (argvalue == NULL) goto noarg;
550                         tracefile = bmake_strdup(argvalue);
551                         Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
552                         Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
553                         break;
554                 case 'V':
555                 case 'v':
556                         if (argvalue == NULL) goto noarg;
557                         printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS;
558                         Lst_Append(variables, argvalue);
559                         Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
560                         Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
561                         break;
562                 case 'W':
563                         parseWarnFatal = TRUE;
564                         break;
565                 case 'X':
566                         varNoExportEnv = TRUE;
567                         Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
568                         break;
569                 case 'd':
570                         if (argvalue == NULL) goto noarg;
571                         /* If '-d-opts' don't pass to children */
572                         if (argvalue[0] == '-')
573                             argvalue++;
574                         else {
575                             Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
576                             Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
577                         }
578                         parse_debug_options(argvalue);
579                         break;
580                 case 'e':
581                         checkEnvFirst = TRUE;
582                         Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
583                         break;
584                 case 'f':
585                         if (argvalue == NULL) goto noarg;
586                         Lst_Append(makefiles, argvalue);
587                         break;
588                 case 'i':
589                         ignoreErrors = TRUE;
590                         Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
591                         break;
592                 case 'j':
593                         if (argvalue == NULL) goto noarg;
594                         forceJobs = TRUE;
595                         maxJobs = strtol(argvalue, &p, 0);
596                         if (*p != '\0' || maxJobs < 1) {
597                                 (void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
598                                     progname);
599                                 exit(1);
600                         }
601                         Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
602                         Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
603                         Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL);
604                         maxJobTokens = maxJobs;
605                         break;
606                 case 'k':
607                         keepgoing = TRUE;
608                         Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
609                         break;
610                 case 'm':
611                         if (argvalue == NULL) goto noarg;
612                         /* look for magic parent directory search string */
613                         if (strncmp(".../", argvalue, 4) == 0) {
614                                 if (!Dir_FindHereOrAbove(curdir, argvalue+4,
615                                     found_path, sizeof(found_path)))
616                                         break;          /* nothing doing */
617                                 (void)Dir_AddDir(sysIncPath, found_path);
618                         } else {
619                                 (void)Dir_AddDir(sysIncPath, argvalue);
620                         }
621                         Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
622                         Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
623                         break;
624                 case 'n':
625                         noExecute = TRUE;
626                         Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
627                         break;
628                 case 'q':
629                         queryFlag = TRUE;
630                         /* Kind of nonsensical, wot? */
631                         Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
632                         break;
633                 case 'r':
634                         noBuiltins = TRUE;
635                         Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
636                         break;
637                 case 's':
638                         beSilent = TRUE;
639                         Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
640                         break;
641                 case 't':
642                         touchFlag = TRUE;
643                         Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
644                         break;
645                 case 'w':
646                         enterFlag = TRUE;
647                         Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
648                         break;
649                 case '-':
650                         dashDash = TRUE;
651                         break;
652                 default:
653                 case '?':
654 #ifndef MAKE_NATIVE
655                         fprintf(stderr, "getopt(%s) -> %d (%c)\n",
656                                 OPTFLAGS, c, c);
657 #endif
658                         usage();
659                 }
660                 argv += arginc;
661                 argc -= arginc;
662         }
663
664         oldVars = TRUE;
665
666         /*
667          * See if the rest of the arguments are variable assignments and
668          * perform them if so. Else take them to be targets and stuff them
669          * on the end of the "create" list.
670          */
671         for (; argc > 1; ++argv, --argc)
672                 if (Parse_IsVar(argv[1])) {
673                         Parse_DoVar(argv[1], VAR_CMD);
674                 } else {
675                         if (!*argv[1])
676                                 Punt("illegal (null) argument.");
677                         if (*argv[1] == '-' && !dashDash)
678                                 goto rearg;
679                         Lst_Append(create, bmake_strdup(argv[1]));
680                 }
681
682         return;
683 noarg:
684         (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
685             progname, c);
686         usage();
687 }
688
689 /*-
690  * Main_ParseArgLine --
691  *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
692  *      is encountered and by main() when reading the .MAKEFLAGS envariable.
693  *      Takes a line of arguments and breaks it into its
694  *      component words and passes those words and the number of them to the
695  *      MainParseArgs function.
696  *      The line should have all its leading whitespace removed.
697  *
698  * Input:
699  *      line            Line to fracture
700  *
701  * Results:
702  *      None
703  *
704  * Side Effects:
705  *      Only those that come from the various arguments.
706  */
707 void
708 Main_ParseArgLine(const char *line)
709 {
710         Words words;
711         char *p1;
712         const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
713         char *buf;
714
715         if (line == NULL)
716                 return;
717         for (; *line == ' '; ++line)
718                 continue;
719         if (!*line)
720                 return;
721
722 #ifndef POSIX
723         {
724                 /*
725                  * $MAKE may simply be naming the make(1) binary
726                  */
727                 char *cp;
728
729                 if (!(cp = strrchr(line, '/')))
730                         cp = line;
731                 if ((cp = strstr(cp, "make")) &&
732                     strcmp(cp, "make") == 0)
733                         return;
734         }
735 #endif
736         buf = str_concat3(argv0, " ", line);
737         free(p1);
738
739         words = Str_Words(buf, TRUE);
740         if (words.words == NULL) {
741                 Error("Unterminated quoted string [%s]", buf);
742                 free(buf);
743                 return;
744         }
745         free(buf);
746         MainParseArgs((int)words.len, words.words);
747
748         Words_Free(words);
749 }
750
751 Boolean
752 Main_SetObjdir(const char *fmt, ...)
753 {
754         struct stat sb;
755         char *path;
756         char buf[MAXPATHLEN + 1];
757         char buf2[MAXPATHLEN + 1];
758         Boolean rc = FALSE;
759         va_list ap;
760
761         va_start(ap, fmt);
762         vsnprintf(path = buf, MAXPATHLEN, fmt, ap);
763         va_end(ap);
764
765         if (path[0] != '/') {
766                 snprintf(buf2, MAXPATHLEN, "%s/%s", curdir, path);
767                 path = buf2;
768         }
769
770         /* look for the directory and try to chdir there */
771         if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
772                 if (chdir(path)) {
773                         (void)fprintf(stderr, "make warning: %s: %s.\n",
774                                       path, strerror(errno));
775                 } else {
776                         snprintf(objdir, sizeof objdir, "%s", path);
777                         Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
778                         setenv("PWD", objdir, 1);
779                         Dir_InitDot();
780                         purge_cached_realpaths();
781                         rc = TRUE;
782                         if (enterFlag && strcmp(objdir, curdir) != 0)
783                                 enterFlagObj = TRUE;
784                 }
785         }
786
787         return rc;
788 }
789
790 static Boolean
791 Main_SetVarObjdir(const char *var, const char *suffix)
792 {
793         char *path_freeIt;
794         const char *path = Var_Value(var, VAR_CMD, &path_freeIt);
795         const char *xpath;
796         char *xpath_freeIt;
797
798         if (path == NULL || path[0] == '\0') {
799                 bmake_free(path_freeIt);
800                 return FALSE;
801         }
802
803         /* expand variable substitutions */
804         xpath = path;
805         xpath_freeIt = NULL;
806         if (strchr(path, '$') != 0)
807                 xpath = xpath_freeIt = Var_Subst(path, VAR_GLOBAL,
808                                                  VARE_WANTRES);
809
810         (void)Main_SetObjdir("%s%s", xpath, suffix);
811
812         bmake_free(xpath_freeIt);
813         bmake_free(path_freeIt);
814         return TRUE;
815 }
816
817 /* Read and parse the makefile.
818  * Return TRUE if reading the makefile succeeded, for Lst_Find. */
819 static Boolean
820 ReadMakefileSucceeded(const void *fname, const void *unused)
821 {
822         return ReadMakefile(fname) == 0;
823 }
824
825 /* Read and parse the makefile.
826  * Return TRUE if reading the makefile failed, for Lst_Find. */
827 static Boolean
828 ReadMakefileFailed(const void *fname, const void *unused)
829 {
830         return ReadMakefile(fname) != 0;
831 }
832
833 int
834 str2Lst_Append(Lst lp, char *str, const char *sep)
835 {
836     char *cp;
837     int n;
838
839     if (!sep)
840         sep = " \t";
841
842     for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
843         Lst_Append(lp, cp);
844         n++;
845     }
846     return n;
847 }
848
849 #ifdef SIGINFO
850 /*ARGSUSED*/
851 static void
852 siginfo(int signo MAKE_ATTR_UNUSED)
853 {
854         char dir[MAXPATHLEN];
855         char str[2 * MAXPATHLEN];
856         int len;
857         if (getcwd(dir, sizeof(dir)) == NULL)
858                 return;
859         len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir);
860         if (len > 0)
861                 (void)write(STDERR_FILENO, str, (size_t)len);
862 }
863 #endif
864
865 /*
866  * Allow makefiles some control over the mode we run in.
867  */
868 void
869 MakeMode(const char *mode)
870 {
871     char *mode_freeIt = NULL;
872
873     if (mode == NULL)
874         mode = mode_freeIt = Var_Subst("${" MAKE_MODE ":tl}",
875                                        VAR_GLOBAL, VARE_WANTRES);
876
877     if (mode[0] != '\0') {
878         if (strstr(mode, "compat")) {
879             compatMake = TRUE;
880             forceJobs = FALSE;
881         }
882 #if USE_META
883         if (strstr(mode, "meta"))
884             meta_mode_init(mode);
885 #endif
886     }
887
888     free(mode_freeIt);
889 }
890
891 static void
892 doPrintVars(void)
893 {
894         LstNode ln;
895         Boolean expandVars;
896
897         if (printVars == EXPAND_VARS)
898                 expandVars = TRUE;
899         else if (debugVflag)
900                 expandVars = FALSE;
901         else
902                 expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
903
904         for (ln = Lst_First(variables); ln != NULL; ln = LstNode_Next(ln)) {
905                 char *var = LstNode_Datum(ln);
906                 const char *value;
907                 char *p1;
908
909                 if (strchr(var, '$')) {
910                         value = p1 = Var_Subst(var, VAR_GLOBAL, VARE_WANTRES);
911                 } else if (expandVars) {
912                         char tmp[128];
913                         int len = snprintf(tmp, sizeof(tmp), "${%s}", var);
914
915                         if (len >= (int)sizeof(tmp))
916                                 Fatal("%s: variable name too big: %s",
917                                     progname, var);
918                         value = p1 = Var_Subst(tmp, VAR_GLOBAL, VARE_WANTRES);
919                 } else {
920                         value = Var_Value(var, VAR_GLOBAL, &p1);
921                 }
922                 printf("%s\n", value ? value : "");
923                 bmake_free(p1);
924         }
925 }
926
927 static Boolean
928 runTargets(void)
929 {
930         Lst targs;      /* target nodes to create -- passed to Make_Init */
931         Boolean outOfDate;      /* FALSE if all targets up to date */
932
933         /*
934          * Have now read the entire graph and need to make a list of
935          * targets to create. If none was given on the command line,
936          * we consult the parsing module to find the main target(s)
937          * to create.
938          */
939         if (Lst_IsEmpty(create))
940                 targs = Parse_MainName();
941         else
942                 targs = Targ_FindList(create, TARG_CREATE);
943
944         if (!compatMake) {
945                 /*
946                  * Initialize job module before traversing the graph
947                  * now that any .BEGIN and .END targets have been read.
948                  * This is done only if the -q flag wasn't given
949                  * (to prevent the .BEGIN from being executed should
950                  * it exist).
951                  */
952                 if (!queryFlag) {
953                         Job_Init();
954                         jobsRunning = TRUE;
955                 }
956
957                 /* Traverse the graph, checking on all the targets */
958                 outOfDate = Make_Run(targs);
959         } else {
960                 /*
961                  * Compat_Init will take care of creating all the
962                  * targets as well as initializing the module.
963                  */
964                 Compat_Run(targs);
965                 outOfDate = FALSE;
966         }
967         Lst_Free(targs);
968         return outOfDate;
969 }
970
971 /*-
972  * main --
973  *      The main function, for obvious reasons. Initializes variables
974  *      and a few modules, then parses the arguments give it in the
975  *      environment and on the command line. Reads the system makefile
976  *      followed by either Makefile, makefile or the file given by the
977  *      -f argument. Sets the .MAKEFLAGS PMake variable based on all the
978  *      flags it has received by then uses either the Make or the Compat
979  *      module to create the initial list of targets.
980  *
981  * Results:
982  *      If -q was given, exits -1 if anything was out-of-date. Else it exits
983  *      0.
984  *
985  * Side Effects:
986  *      The program exits when done. Targets are created. etc. etc. etc.
987  */
988 int
989 main(int argc, char **argv)
990 {
991         Boolean outOfDate;      /* FALSE if all targets up to date */
992         struct stat sb, sa;
993         char *p1, *path;
994         char mdpath[MAXPATHLEN];
995 #ifdef FORCE_MACHINE
996         const char *machine = FORCE_MACHINE;
997 #else
998         const char *machine = getenv("MACHINE");
999 #endif
1000         const char *machine_arch = getenv("MACHINE_ARCH");
1001         char *syspath = getenv("MAKESYSPATH");
1002         Lst sysMkPath;                  /* Path of sys.mk */
1003         char *cp = NULL, *start;
1004                                         /* avoid faults on read-only strings */
1005         static char defsyspath[] = _PATH_DEFSYSPATH;
1006         char found_path[MAXPATHLEN + 1];        /* for searching for sys.mk */
1007         struct timeval rightnow;                /* to initialize random seed */
1008         struct utsname utsname;
1009
1010         /* default to writing debug to stderr */
1011         debug_file = stderr;
1012
1013 #ifdef SIGINFO
1014         (void)bmake_signal(SIGINFO, siginfo);
1015 #endif
1016         /*
1017          * Set the seed to produce a different random sequence
1018          * on each program execution.
1019          */
1020         gettimeofday(&rightnow, NULL);
1021         srandom(rightnow.tv_sec + rightnow.tv_usec);
1022
1023         if ((progname = strrchr(argv[0], '/')) != NULL)
1024                 progname++;
1025         else
1026                 progname = argv[0];
1027 #if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
1028         /*
1029          * get rid of resource limit on file descriptors
1030          */
1031         {
1032                 struct rlimit rl;
1033                 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
1034                     rl.rlim_cur != rl.rlim_max) {
1035                         rl.rlim_cur = rl.rlim_max;
1036                         (void)setrlimit(RLIMIT_NOFILE, &rl);
1037                 }
1038         }
1039 #endif
1040
1041         if (uname(&utsname) == -1) {
1042             (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
1043                 strerror(errno));
1044             exit(2);
1045         }
1046
1047         /*
1048          * Get the name of this type of MACHINE from utsname
1049          * so we can share an executable for similar machines.
1050          * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
1051          *
1052          * Note that both MACHINE and MACHINE_ARCH are decided at
1053          * run-time.
1054          */
1055         if (!machine) {
1056 #ifdef MAKE_NATIVE
1057             machine = utsname.machine;
1058 #else
1059 #ifdef MAKE_MACHINE
1060             machine = MAKE_MACHINE;
1061 #else
1062             machine = "unknown";
1063 #endif
1064 #endif
1065         }
1066
1067         if (!machine_arch) {
1068 #if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL) && defined(CTL_HW) && defined(HW_MACHINE_ARCH)
1069             static char machine_arch_buf[sizeof(utsname.machine)];
1070             int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
1071             size_t len = sizeof(machine_arch_buf);
1072
1073             if (sysctl(mib, __arraycount(mib), machine_arch_buf,
1074                     &len, NULL, 0) < 0) {
1075                 (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
1076                     strerror(errno));
1077                 exit(2);
1078             }
1079
1080             machine_arch = machine_arch_buf;
1081 #else
1082 #ifndef MACHINE_ARCH
1083 #ifdef MAKE_MACHINE_ARCH
1084             machine_arch = MAKE_MACHINE_ARCH;
1085 #else
1086             machine_arch = "unknown";
1087 #endif
1088 #else
1089             machine_arch = MACHINE_ARCH;
1090 #endif
1091 #endif
1092         }
1093
1094         myPid = getpid();               /* remember this for vFork() */
1095
1096         /*
1097          * Just in case MAKEOBJDIR wants us to do something tricky.
1098          */
1099         Var_Init();             /* Initialize the lists of variables for
1100                                  * parsing arguments */
1101         Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL);
1102         Var_Set("MACHINE", machine, VAR_GLOBAL);
1103         Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
1104 #ifdef MAKE_VERSION
1105         Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
1106 #endif
1107         Var_Set(".newline", "\n", VAR_GLOBAL); /* handy for :@ loops */
1108         /*
1109          * This is the traditional preference for makefiles.
1110          */
1111 #ifndef MAKEFILE_PREFERENCE_LIST
1112 # define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
1113 #endif
1114         Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
1115                 VAR_GLOBAL);
1116         Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
1117
1118         create = Lst_Init();
1119         makefiles = Lst_Init();
1120         printVars = 0;
1121         debugVflag = FALSE;
1122         variables = Lst_Init();
1123         beSilent = FALSE;               /* Print commands as executed */
1124         ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
1125         noExecute = FALSE;              /* Execute all commands */
1126         noRecursiveExecute = FALSE;     /* Execute all .MAKE targets */
1127         keepgoing = FALSE;              /* Stop on error */
1128         allPrecious = FALSE;            /* Remove targets when interrupted */
1129         deleteOnError = FALSE;          /* Historical default behavior */
1130         queryFlag = FALSE;              /* This is not just a check-run */
1131         noBuiltins = FALSE;             /* Read the built-in rules */
1132         touchFlag = FALSE;              /* Actually update targets */
1133         debug = 0;                      /* No debug verbosity, please. */
1134         jobsRunning = FALSE;
1135
1136         maxJobs = DEFMAXLOCAL;          /* Set default local max concurrency */
1137         maxJobTokens = maxJobs;
1138         compatMake = FALSE;             /* No compat mode */
1139         ignorePWD = FALSE;
1140
1141         /*
1142          * Initialize the parsing, directory and variable modules to prepare
1143          * for the reading of inclusion paths and variable settings on the
1144          * command line
1145          */
1146
1147         /*
1148          * Initialize various variables.
1149          *      MAKE also gets this name, for compatibility
1150          *      .MAKEFLAGS gets set to the empty string just in case.
1151          *      MFLAGS also gets initialized empty, for compatibility.
1152          */
1153         Parse_Init();
1154         if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) {
1155             /*
1156              * Leave alone if it is an absolute path, or if it does
1157              * not contain a '/' in which case we need to find it in
1158              * the path, like execvp(3) and the shells do.
1159              */
1160             p1 = argv[0];
1161         } else {
1162             /*
1163              * A relative path, canonicalize it.
1164              */
1165             p1 = cached_realpath(argv[0], mdpath);
1166             if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) {
1167                 p1 = argv[0];           /* realpath failed */
1168             }
1169         }
1170         Var_Set("MAKE", p1, VAR_GLOBAL);
1171         Var_Set(".MAKE", p1, VAR_GLOBAL);
1172         Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
1173         Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL);
1174         Var_Set("MFLAGS", "", VAR_GLOBAL);
1175         Var_Set(".ALLTARGETS", "", VAR_GLOBAL);
1176         /* some makefiles need to know this */
1177         Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMD);
1178
1179         /*
1180          * Set some other useful macros
1181          */
1182         {
1183             char tmp[64], *ep;
1184
1185             makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0;
1186             if (makelevel < 0)
1187                 makelevel = 0;
1188             snprintf(tmp, sizeof(tmp), "%d", makelevel);
1189             Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL);
1190             snprintf(tmp, sizeof(tmp), "%u", myPid);
1191             Var_Set(".MAKE.PID", tmp, VAR_GLOBAL);
1192             snprintf(tmp, sizeof(tmp), "%u", getppid());
1193             Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL);
1194         }
1195         if (makelevel > 0) {
1196                 char pn[1024];
1197                 snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel);
1198                 progname = bmake_strdup(pn);
1199         }
1200
1201 #ifdef USE_META
1202         meta_init();
1203 #endif
1204         Dir_Init();
1205
1206         /*
1207          * First snag any flags out of the MAKE environment variable.
1208          * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
1209          * in a different format).
1210          */
1211 #ifdef POSIX
1212         p1 = explode(getenv("MAKEFLAGS"));
1213         Main_ParseArgLine(p1);
1214         free(p1);
1215 #else
1216         Main_ParseArgLine(getenv("MAKE"));
1217 #endif
1218
1219         /*
1220          * Find where we are (now).
1221          * We take care of PWD for the automounter below...
1222          */
1223         if (getcwd(curdir, MAXPATHLEN) == NULL) {
1224                 (void)fprintf(stderr, "%s: getcwd: %s.\n",
1225                     progname, strerror(errno));
1226                 exit(2);
1227         }
1228
1229         MainParseArgs(argc, argv);
1230
1231         if (enterFlag)
1232                 printf("%s: Entering directory `%s'\n", progname, curdir);
1233
1234         /*
1235          * Verify that cwd is sane.
1236          */
1237         if (stat(curdir, &sa) == -1) {
1238             (void)fprintf(stderr, "%s: %s: %s.\n",
1239                  progname, curdir, strerror(errno));
1240             exit(2);
1241         }
1242
1243         /*
1244          * All this code is so that we know where we are when we start up
1245          * on a different machine with pmake.
1246          * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
1247          * since the value of curdir can vary depending on how we got
1248          * here.  Ie sitting at a shell prompt (shell that provides $PWD)
1249          * or via subdir.mk in which case its likely a shell which does
1250          * not provide it.
1251          * So, to stop it breaking this case only, we ignore PWD if
1252          * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
1253          */
1254 #ifndef NO_PWD_OVERRIDE
1255         if (!ignorePWD) {
1256                 char *pwd, *ptmp1 = NULL, *ptmp2 = NULL;
1257
1258                 if ((pwd = getenv("PWD")) != NULL &&
1259                     Var_Value("MAKEOBJDIRPREFIX", VAR_CMD, &ptmp1) == NULL) {
1260                         const char *makeobjdir = Var_Value("MAKEOBJDIR",
1261                             VAR_CMD, &ptmp2);
1262
1263                         if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
1264                                 if (stat(pwd, &sb) == 0 &&
1265                                     sa.st_ino == sb.st_ino &&
1266                                     sa.st_dev == sb.st_dev)
1267                                         (void)strncpy(curdir, pwd, MAXPATHLEN);
1268                         }
1269                 }
1270                 bmake_free(ptmp1);
1271                 bmake_free(ptmp2);
1272         }
1273 #endif
1274         Var_Set(".CURDIR", curdir, VAR_GLOBAL);
1275
1276         /*
1277          * Find the .OBJDIR.  If MAKEOBJDIRPREFIX, or failing that,
1278          * MAKEOBJDIR is set in the environment, try only that value
1279          * and fall back to .CURDIR if it does not exist.
1280          *
1281          * Otherwise, try _PATH_OBJDIR.MACHINE-MACHINE_ARCH, _PATH_OBJDIR.MACHINE,
1282          * and * finally _PATH_OBJDIRPREFIX`pwd`, in that order.  If none
1283          * of these paths exist, just use .CURDIR.
1284          */
1285         Dir_InitDir(curdir);
1286         (void)Main_SetObjdir("%s", curdir);
1287
1288         if (!Main_SetVarObjdir("MAKEOBJDIRPREFIX", curdir) &&
1289             !Main_SetVarObjdir("MAKEOBJDIR", "") &&
1290             !Main_SetObjdir("%s.%s-%s", _PATH_OBJDIR, machine, machine_arch) &&
1291             !Main_SetObjdir("%s.%s", _PATH_OBJDIR, machine) &&
1292             !Main_SetObjdir("%s", _PATH_OBJDIR))
1293                 (void)Main_SetObjdir("%s%s", _PATH_OBJDIRPREFIX, curdir);
1294
1295         /*
1296          * Initialize archive, target and suffix modules in preparation for
1297          * parsing the makefile(s)
1298          */
1299         Arch_Init();
1300         Targ_Init();
1301         Suff_Init();
1302         Trace_Init(tracefile);
1303
1304         DEFAULT = NULL;
1305         (void)time(&now);
1306
1307         Trace_Log(MAKESTART, NULL);
1308
1309         /*
1310          * Set up the .TARGETS variable to contain the list of targets to be
1311          * created. If none specified, make the variable empty -- the parser
1312          * will fill the thing in with the default or .MAIN target.
1313          */
1314         if (!Lst_IsEmpty(create)) {
1315                 LstNode ln;
1316
1317                 for (ln = Lst_First(create); ln != NULL; ln = LstNode_Next(ln)) {
1318                         char *name = LstNode_Datum(ln);
1319                         Var_Append(".TARGETS", name, VAR_GLOBAL);
1320                 }
1321         } else
1322                 Var_Set(".TARGETS", "", VAR_GLOBAL);
1323
1324
1325         /*
1326          * If no user-supplied system path was given (through the -m option)
1327          * add the directories from the DEFSYSPATH (more than one may be given
1328          * as dir1:...:dirn) to the system include path.
1329          */
1330         /* XXX: mismatch: the -m option sets sysIncPath, not syspath */
1331         if (syspath == NULL || syspath[0] == '\0')
1332                 syspath = defsyspath;
1333         else
1334                 syspath = bmake_strdup(syspath);
1335
1336         for (start = syspath; *start != '\0'; start = cp) {
1337                 for (cp = start; *cp != '\0' && *cp != ':'; cp++)
1338                         continue;
1339                 if (*cp == ':') {
1340                         *cp++ = '\0';
1341                 }
1342                 /* look for magic parent directory search string */
1343                 if (strncmp(".../", start, 4) != 0) {
1344                         (void)Dir_AddDir(defIncPath, start);
1345                 } else {
1346                         if (Dir_FindHereOrAbove(curdir, start+4,
1347                             found_path, sizeof(found_path))) {
1348                                 (void)Dir_AddDir(defIncPath, found_path);
1349                         }
1350                 }
1351         }
1352         if (syspath != defsyspath)
1353                 free(syspath);
1354
1355         /*
1356          * Read in the built-in rules first, followed by the specified
1357          * makefiles, or the default makefile and Makefile, in that order,
1358          * if no makefiles were given on the command line.
1359          */
1360         if (!noBuiltins) {
1361                 LstNode ln;
1362
1363                 sysMkPath = Lst_Init();
1364                 Dir_Expand(_PATH_DEFSYSMK,
1365                            Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
1366                            sysMkPath);
1367                 if (Lst_IsEmpty(sysMkPath))
1368                         Fatal("%s: no system rules (%s).", progname,
1369                             _PATH_DEFSYSMK);
1370                 ln = Lst_Find(sysMkPath, ReadMakefileSucceeded, NULL);
1371                 if (ln == NULL)
1372                         Fatal("%s: cannot open %s.", progname,
1373                             (char *)LstNode_Datum(Lst_First(sysMkPath)));
1374         }
1375
1376         if (!Lst_IsEmpty(makefiles)) {
1377                 LstNode ln;
1378
1379                 ln = Lst_Find(makefiles, ReadMakefileFailed, NULL);
1380                 if (ln != NULL)
1381                         Fatal("%s: cannot open %s.", progname,
1382                             (char *)LstNode_Datum(ln));
1383         } else {
1384                 p1 = Var_Subst("${" MAKEFILE_PREFERENCE "}",
1385                                VAR_CMD, VARE_WANTRES);
1386                 (void)str2Lst_Append(makefiles, p1, NULL);
1387                 (void)Lst_Find(makefiles, ReadMakefileSucceeded, NULL);
1388                 free(p1);
1389         }
1390
1391         /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
1392         if (!noBuiltins || !printVars) {
1393             makeDependfile = Var_Subst("${.MAKE.DEPENDFILE:T}",
1394                 VAR_CMD, VARE_WANTRES);
1395             doing_depend = TRUE;
1396             (void)ReadMakefile(makeDependfile);
1397             doing_depend = FALSE;
1398         }
1399
1400         if (enterFlagObj)
1401                 printf("%s: Entering directory `%s'\n", progname, objdir);
1402
1403         MakeMode(NULL);
1404
1405         Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
1406         bmake_free(p1);
1407
1408         if (!forceJobs && !compatMake &&
1409             Var_Exists(".MAKE.JOBS", VAR_GLOBAL)) {
1410             char *value;
1411             int n;
1412
1413             value = Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES);
1414             n = strtol(value, NULL, 0);
1415             if (n < 1) {
1416                 (void)fprintf(stderr, "%s: illegal value for .MAKE.JOBS -- must be positive integer!\n",
1417                     progname);
1418                 exit(1);
1419             }
1420             if (n != maxJobs) {
1421                 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
1422                 Var_Append(MAKEFLAGS, value, VAR_GLOBAL);
1423             }
1424             maxJobs = n;
1425             maxJobTokens = maxJobs;
1426             forceJobs = TRUE;
1427             free(value);
1428         }
1429
1430         /*
1431          * Be compatible if user did not specify -j and did not explicitly
1432          * turned compatibility on
1433          */
1434         if (!compatMake && !forceJobs) {
1435             compatMake = TRUE;
1436         }
1437
1438         if (!compatMake)
1439             Job_ServerStart(maxJobTokens, jp_0, jp_1);
1440         if (DEBUG(JOB))
1441             fprintf(debug_file,
1442                     "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
1443                     jp_0, jp_1, maxJobs, maxJobTokens, compatMake ? 1 : 0);
1444
1445         if (!printVars)
1446             Main_ExportMAKEFLAGS(TRUE); /* initial export */
1447
1448
1449         /*
1450          * For compatibility, look at the directories in the VPATH variable
1451          * and add them to the search path, if the variable is defined. The
1452          * variable's value is in the same format as the PATH envariable, i.e.
1453          * <directory>:<directory>:<directory>...
1454          */
1455         if (Var_Exists("VPATH", VAR_CMD)) {
1456                 char *vpath, savec;
1457                 /*
1458                  * GCC stores string constants in read-only memory, but
1459                  * Var_Subst will want to write this thing, so store it
1460                  * in an array
1461                  */
1462                 static char VPATH[] = "${VPATH}";
1463
1464                 vpath = Var_Subst(VPATH, VAR_CMD, VARE_WANTRES);
1465                 path = vpath;
1466                 do {
1467                         /* skip to end of directory */
1468                         for (cp = path; *cp != ':' && *cp != '\0'; cp++)
1469                                 continue;
1470                         /* Save terminator character so know when to stop */
1471                         savec = *cp;
1472                         *cp = '\0';
1473                         /* Add directory to search path */
1474                         (void)Dir_AddDir(dirSearchPath, path);
1475                         *cp = savec;
1476                         path = cp + 1;
1477                 } while (savec == ':');
1478                 free(vpath);
1479         }
1480
1481         /*
1482          * Now that all search paths have been read for suffixes et al, it's
1483          * time to add the default search path to their lists...
1484          */
1485         Suff_DoPaths();
1486
1487         /*
1488          * Propagate attributes through :: dependency lists.
1489          */
1490         Targ_Propagate();
1491
1492         /* print the initial graph, if the user requested it */
1493         if (DEBUG(GRAPH1))
1494                 Targ_PrintGraph(1);
1495
1496         /* print the values of any variables requested by the user */
1497         if (printVars) {
1498                 doPrintVars();
1499                 outOfDate = FALSE;
1500         } else {
1501                 outOfDate = runTargets();
1502         }
1503
1504 #ifdef CLEANUP
1505         Lst_Free(variables);
1506         Lst_Free(makefiles);
1507         Lst_Destroy(create, free);
1508 #endif
1509
1510         /* print the graph now it's been processed if the user requested it */
1511         if (DEBUG(GRAPH2))
1512                 Targ_PrintGraph(2);
1513
1514         Trace_Log(MAKEEND, 0);
1515
1516         if (enterFlagObj)
1517                 printf("%s: Leaving directory `%s'\n", progname, objdir);
1518         if (enterFlag)
1519                 printf("%s: Leaving directory `%s'\n", progname, curdir);
1520
1521 #ifdef USE_META
1522         meta_finish();
1523 #endif
1524         Suff_End();
1525         Targ_End();
1526         Arch_End();
1527         Var_End();
1528         Parse_End();
1529         Dir_End();
1530         Job_End();
1531         Trace_End();
1532
1533         return outOfDate ? 1 : 0;
1534 }
1535
1536 /* Open and parse the given makefile, with all its side effects.
1537  *
1538  * Results:
1539  *      0 if ok. -1 if couldn't open file.
1540  */
1541 static int
1542 ReadMakefile(const char *fname)
1543 {
1544         int fd;
1545         char *name, *path = NULL;
1546
1547         if (!strcmp(fname, "-")) {
1548                 Parse_File(NULL /*stdin*/, -1);
1549                 Var_Set("MAKEFILE", "", VAR_INTERNAL);
1550         } else {
1551                 /* if we've chdir'd, rebuild the path name */
1552                 if (strcmp(curdir, objdir) && *fname != '/') {
1553                         path = str_concat3(curdir, "/", fname);
1554                         fd = open(path, O_RDONLY);
1555                         if (fd != -1) {
1556                                 fname = path;
1557                                 goto found;
1558                         }
1559                         free(path);
1560
1561                         /* If curdir failed, try objdir (ala .depend) */
1562                         path = str_concat3(objdir, "/", fname);
1563                         fd = open(path, O_RDONLY);
1564                         if (fd != -1) {
1565                                 fname = path;
1566                                 goto found;
1567                         }
1568                 } else {
1569                         fd = open(fname, O_RDONLY);
1570                         if (fd != -1)
1571                                 goto found;
1572                 }
1573                 /* look in -I and system include directories. */
1574                 name = Dir_FindFile(fname, parseIncPath);
1575                 if (!name)
1576                         name = Dir_FindFile(fname,
1577                                 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
1578                 if (!name || (fd = open(name, O_RDONLY)) == -1) {
1579                         free(name);
1580                         free(path);
1581                         return -1;
1582                 }
1583                 fname = name;
1584                 /*
1585                  * set the MAKEFILE variable desired by System V fans -- the
1586                  * placement of the setting here means it gets set to the last
1587                  * makefile specified, as it is set by SysV make.
1588                  */
1589 found:
1590                 if (!doing_depend)
1591                         Var_Set("MAKEFILE", fname, VAR_INTERNAL);
1592                 Parse_File(fname, fd);
1593         }
1594         free(path);
1595         return 0;
1596 }
1597
1598
1599
1600 /*-
1601  * Cmd_Exec --
1602  *      Execute the command in cmd, and return the output of that command
1603  *      in a string.  In the output, newlines are replaced with spaces.
1604  *
1605  * Results:
1606  *      A string containing the output of the command, or the empty string.
1607  *      *errfmt returns a format string describing the command failure,
1608  *      if any, using a single %s conversion specification.
1609  *
1610  * Side Effects:
1611  *      The string must be freed by the caller.
1612  */
1613 char *
1614 Cmd_Exec(const char *cmd, const char **errfmt)
1615 {
1616     const char  *args[4];       /* Args for invoking the shell */
1617     int         fds[2];         /* Pipe streams */
1618     int         cpid;           /* Child PID */
1619     int         pid;            /* PID from wait() */
1620     WAIT_T      status;         /* command exit status */
1621     Buffer      buf;            /* buffer to store the result */
1622     ssize_t     bytes_read;
1623     char        *res;           /* result */
1624     size_t      res_len;
1625     char        *cp;
1626     int         savederr;       /* saved errno */
1627
1628     *errfmt = NULL;
1629
1630     if (!shellName)
1631         Shell_Init();
1632     /*
1633      * Set up arguments for shell
1634      */
1635     args[0] = shellName;
1636     args[1] = "-c";
1637     args[2] = cmd;
1638     args[3] = NULL;
1639
1640     /*
1641      * Open a pipe for fetching its output
1642      */
1643     if (pipe(fds) == -1) {
1644         *errfmt = "Couldn't create pipe for \"%s\"";
1645         goto bad;
1646     }
1647
1648     /*
1649      * Fork
1650      */
1651     switch (cpid = vFork()) {
1652     case 0:
1653         /*
1654          * Close input side of pipe
1655          */
1656         (void)close(fds[0]);
1657
1658         /*
1659          * Duplicate the output stream to the shell's output, then
1660          * shut the extra thing down. Note we don't fetch the error
1661          * stream...why not? Why?
1662          */
1663         (void)dup2(fds[1], 1);
1664         (void)close(fds[1]);
1665
1666         Var_ExportVars();
1667
1668         (void)execv(shellPath, UNCONST(args));
1669         _exit(1);
1670         /*NOTREACHED*/
1671
1672     case -1:
1673         *errfmt = "Couldn't exec \"%s\"";
1674         goto bad;
1675
1676     default:
1677         /*
1678          * No need for the writing half
1679          */
1680         (void)close(fds[1]);
1681
1682         savederr = 0;
1683         Buf_Init(&buf, 0);
1684
1685         do {
1686             char   result[BUFSIZ];
1687             bytes_read = read(fds[0], result, sizeof(result));
1688             if (bytes_read > 0)
1689                 Buf_AddBytes(&buf, result, (size_t)bytes_read);
1690         }
1691         while (bytes_read > 0 || (bytes_read == -1 && errno == EINTR));
1692         if (bytes_read == -1)
1693             savederr = errno;
1694
1695         /*
1696          * Close the input side of the pipe.
1697          */
1698         (void)close(fds[0]);
1699
1700         /*
1701          * Wait for the process to exit.
1702          */
1703         while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) {
1704             JobReapChild(pid, status, FALSE);
1705             continue;
1706         }
1707         res_len = Buf_Size(&buf);
1708         res = Buf_Destroy(&buf, FALSE);
1709
1710         if (savederr != 0)
1711             *errfmt = "Couldn't read shell's output for \"%s\"";
1712
1713         if (WIFSIGNALED(status))
1714             *errfmt = "\"%s\" exited on a signal";
1715         else if (WEXITSTATUS(status) != 0)
1716             *errfmt = "\"%s\" returned non-zero status";
1717
1718         /* Convert newlines to spaces.  A final newline is just stripped */
1719         if (res_len > 0 && res[res_len - 1] == '\n')
1720             res[res_len - 1] = '\0';
1721         for (cp = res; *cp != '\0'; cp++)
1722             if (*cp == '\n')
1723                 *cp = ' ';
1724         break;
1725     }
1726     return res;
1727 bad:
1728     return bmake_strdup("");
1729 }
1730
1731 /*-
1732  * Error --
1733  *      Print an error message given its format.
1734  *
1735  * Results:
1736  *      None.
1737  *
1738  * Side Effects:
1739  *      The message is printed.
1740  */
1741 /* VARARGS */
1742 void
1743 Error(const char *fmt, ...)
1744 {
1745         va_list ap;
1746         FILE *err_file;
1747
1748         err_file = debug_file;
1749         if (err_file == stdout)
1750                 err_file = stderr;
1751         (void)fflush(stdout);
1752         for (;;) {
1753                 va_start(ap, fmt);
1754                 fprintf(err_file, "%s: ", progname);
1755                 (void)vfprintf(err_file, fmt, ap);
1756                 va_end(ap);
1757                 (void)fprintf(err_file, "\n");
1758                 (void)fflush(err_file);
1759                 if (err_file == stderr)
1760                         break;
1761                 err_file = stderr;
1762         }
1763 }
1764
1765 /*-
1766  * Fatal --
1767  *      Produce a Fatal error message. If jobs are running, waits for them
1768  *      to finish.
1769  *
1770  * Results:
1771  *      None
1772  *
1773  * Side Effects:
1774  *      The program exits
1775  */
1776 /* VARARGS */
1777 void
1778 Fatal(const char *fmt, ...)
1779 {
1780         va_list ap;
1781
1782         va_start(ap, fmt);
1783         if (jobsRunning)
1784                 Job_Wait();
1785
1786         (void)fflush(stdout);
1787         (void)vfprintf(stderr, fmt, ap);
1788         va_end(ap);
1789         (void)fprintf(stderr, "\n");
1790         (void)fflush(stderr);
1791
1792         PrintOnError(NULL, NULL);
1793
1794         if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
1795                 Targ_PrintGraph(2);
1796         Trace_Log(MAKEERROR, 0);
1797         exit(2);                /* Not 1 so -q can distinguish error */
1798 }
1799
1800 /*
1801  * Punt --
1802  *      Major exception once jobs are being created. Kills all jobs, prints
1803  *      a message and exits.
1804  *
1805  * Results:
1806  *      None
1807  *
1808  * Side Effects:
1809  *      All children are killed indiscriminately and the program Lib_Exits
1810  */
1811 /* VARARGS */
1812 void
1813 Punt(const char *fmt, ...)
1814 {
1815         va_list ap;
1816
1817         va_start(ap, fmt);
1818         (void)fflush(stdout);
1819         (void)fprintf(stderr, "%s: ", progname);
1820         (void)vfprintf(stderr, fmt, ap);
1821         va_end(ap);
1822         (void)fprintf(stderr, "\n");
1823         (void)fflush(stderr);
1824
1825         PrintOnError(NULL, NULL);
1826
1827         DieHorribly();
1828 }
1829
1830 /*-
1831  * DieHorribly --
1832  *      Exit without giving a message.
1833  *
1834  * Results:
1835  *      None
1836  *
1837  * Side Effects:
1838  *      A big one...
1839  */
1840 void
1841 DieHorribly(void)
1842 {
1843         if (jobsRunning)
1844                 Job_AbortAll();
1845         if (DEBUG(GRAPH2))
1846                 Targ_PrintGraph(2);
1847         Trace_Log(MAKEERROR, 0);
1848         exit(2);                /* Not 1, so -q can distinguish error */
1849 }
1850
1851 /*
1852  * Finish --
1853  *      Called when aborting due to errors in child shell to signal
1854  *      abnormal exit.
1855  *
1856  * Results:
1857  *      None
1858  *
1859  * Side Effects:
1860  *      The program exits
1861  */
1862 void
1863 Finish(int errors)
1864                         /* number of errors encountered in Make_Make */
1865 {
1866         if (dieQuietly(NULL, -1))
1867                 exit(2);
1868         Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1869 }
1870
1871 /*
1872  * eunlink --
1873  *      Remove a file carefully, avoiding directories.
1874  */
1875 int
1876 eunlink(const char *file)
1877 {
1878         struct stat st;
1879
1880         if (lstat(file, &st) == -1)
1881                 return -1;
1882
1883         if (S_ISDIR(st.st_mode)) {
1884                 errno = EISDIR;
1885                 return -1;
1886         }
1887         return unlink(file);
1888 }
1889
1890 /*
1891  * execError --
1892  *      Print why exec failed, avoiding stdio.
1893  */
1894 void
1895 execError(const char *af, const char *av)
1896 {
1897 #ifdef USE_IOVEC
1898         int i = 0;
1899         struct iovec iov[8];
1900 #define IOADD(s) \
1901         (void)(iov[i].iov_base = UNCONST(s), \
1902             iov[i].iov_len = strlen(iov[i].iov_base), \
1903             i++)
1904 #else
1905 #define IOADD(s) (void)write(2, s, strlen(s))
1906 #endif
1907
1908         IOADD(progname);
1909         IOADD(": ");
1910         IOADD(af);
1911         IOADD("(");
1912         IOADD(av);
1913         IOADD(") failed (");
1914         IOADD(strerror(errno));
1915         IOADD(")\n");
1916
1917 #ifdef USE_IOVEC
1918         while (writev(2, iov, 8) == -1 && errno == EAGAIN)
1919             continue;
1920 #endif
1921 }
1922
1923 /*
1924  * usage --
1925  *      exit with usage message
1926  */
1927 static void
1928 usage(void)
1929 {
1930         char *p;
1931         if ((p = strchr(progname, '[')) != NULL)
1932                 *p = '\0';
1933
1934         (void)fprintf(stderr,
1935 "usage: %s [-BeikNnqrstWwX] \n"
1936 "            [-C directory] [-D variable] [-d flags] [-f makefile]\n"
1937 "            [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n"
1938 "            [-V variable] [-v variable] [variable=value] [target ...]\n",
1939             progname);
1940         exit(2);
1941 }
1942
1943 /*
1944  * realpath(3) can get expensive, cache results...
1945  */
1946 static GNode *cached_realpaths = NULL;
1947
1948 static GNode *
1949 get_cached_realpaths(void)
1950 {
1951
1952     if (!cached_realpaths) {
1953         cached_realpaths = Targ_NewGN("Realpath");
1954 #ifndef DEBUG_REALPATH_CACHE
1955         cached_realpaths->flags = INTERNAL;
1956 #endif
1957     }
1958
1959     return cached_realpaths;
1960 }
1961
1962 /* purge any relative paths */
1963 static void
1964 purge_cached_realpaths(void)
1965 {
1966     GNode *cache = get_cached_realpaths();
1967     Hash_Entry *he, *nhe;
1968     Hash_Search hs;
1969
1970     he = Hash_EnumFirst(&cache->context, &hs);
1971     while (he) {
1972         nhe = Hash_EnumNext(&hs);
1973         if (he->name[0] != '/') {
1974             if (DEBUG(DIR))
1975                 fprintf(stderr, "cached_realpath: purging %s\n", he->name);
1976             Hash_DeleteEntry(&cache->context, he);
1977         }
1978         he = nhe;
1979     }
1980 }
1981
1982 char *
1983 cached_realpath(const char *pathname, char *resolved)
1984 {
1985     GNode *cache;
1986     const char *rp;
1987     char *cp;
1988
1989     if (!pathname || !pathname[0])
1990         return NULL;
1991
1992     cache = get_cached_realpaths();
1993
1994     if ((rp = Var_Value(pathname, cache, &cp)) != NULL) {
1995         /* a hit */
1996         strlcpy(resolved, rp, MAXPATHLEN);
1997     } else if ((rp = realpath(pathname, resolved)) != NULL) {
1998         Var_Set(pathname, rp, cache);
1999     } /* else should we negative-cache? */
2000
2001     bmake_free(cp);
2002     return rp ? resolved : NULL;
2003 }
2004
2005 int
2006 PrintAddr(void *a, void *b)
2007 {
2008     printf("%lx ", (unsigned long) a);
2009     return b ? 0 : 0;
2010 }
2011
2012
2013 static int
2014 addErrorCMD(void *cmdp, void *gnp MAKE_ATTR_UNUSED)
2015 {
2016     if (cmdp == NULL)
2017         return 1;                       /* stop */
2018     Var_Append(".ERROR_CMD", cmdp, VAR_GLOBAL);
2019     return 0;
2020 }
2021
2022 /*
2023  * Return true if we should die without noise.
2024  * For example our failing child was a sub-make
2025  * or failure happend elsewhere.
2026  */
2027 int
2028 dieQuietly(GNode *gn, int bf)
2029 {
2030     static int quietly = -1;
2031
2032     if (quietly < 0) {
2033         if (DEBUG(JOB) || getBoolean(".MAKE.DIE_QUIETLY", 1) == 0)
2034             quietly = 0;
2035         else if (bf >= 0)
2036             quietly = bf;
2037         else
2038             quietly = (gn) ? ((gn->type  & (OP_MAKE)) != 0) : 0;
2039     }
2040     return quietly;
2041 }
2042
2043 void
2044 PrintOnError(GNode *gn, const char *s)
2045 {
2046     static GNode *en = NULL;
2047     const char *expr;
2048     char *cp;
2049
2050     if (DEBUG(HASH)) {
2051         Targ_Stats();
2052         Var_Stats();
2053     }
2054
2055     /* we generally want to keep quiet if a sub-make died */
2056     if (dieQuietly(gn, -1))
2057         return;
2058
2059     if (s)
2060         printf("%s", s);
2061
2062     printf("\n%s: stopped in %s\n", progname, curdir);
2063
2064     if (en)
2065         return;                         /* we've been here! */
2066     if (gn) {
2067         /*
2068          * We can print this even if there is no .ERROR target.
2069          */
2070         Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL);
2071         Var_Delete(".ERROR_CMD", VAR_GLOBAL);
2072         Lst_ForEach(gn->commands, addErrorCMD, gn);
2073     }
2074     expr = "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}";
2075     cp = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
2076     printf("%s", cp);
2077     free(cp);
2078     fflush(stdout);
2079
2080     /*
2081      * Finally, see if there is a .ERROR target, and run it if so.
2082      */
2083     en = Targ_FindNode(".ERROR", TARG_NOCREATE);
2084     if (en) {
2085         en->type |= OP_SPECIAL;
2086         Compat_Make(en, en);
2087     }
2088 }
2089
2090 void
2091 Main_ExportMAKEFLAGS(Boolean first)
2092 {
2093     static Boolean once = TRUE;
2094     const char *expr;
2095     char *s;
2096
2097     if (once != first)
2098         return;
2099     once = FALSE;
2100
2101     expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
2102     s = Var_Subst(expr, VAR_CMD, VARE_WANTRES);
2103     if (s[0] != '\0') {
2104 #ifdef POSIX
2105         setenv("MAKEFLAGS", s, 1);
2106 #else
2107         setenv("MAKE", s, 1);
2108 #endif
2109     }
2110 }
2111
2112 char *
2113 getTmpdir(void)
2114 {
2115     static char *tmpdir = NULL;
2116
2117     if (!tmpdir) {
2118         struct stat st;
2119
2120         /*
2121          * Honor $TMPDIR but only if it is valid.
2122          * Ensure it ends with /.
2123          */
2124         tmpdir = Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
2125                            VARE_WANTRES);
2126         if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
2127             free(tmpdir);
2128             tmpdir = bmake_strdup(_PATH_TMP);
2129         }
2130     }
2131     return tmpdir;
2132 }
2133
2134 /*
2135  * Create and open a temp file using "pattern".
2136  * If "fnamep" is provided set it to a copy of the filename created.
2137  * Otherwise unlink the file once open.
2138  */
2139 int
2140 mkTempFile(const char *pattern, char **fnamep)
2141 {
2142     static char *tmpdir = NULL;
2143     char tfile[MAXPATHLEN];
2144     int fd;
2145
2146     if (!pattern)
2147         pattern = TMPPAT;
2148     if (!tmpdir)
2149         tmpdir = getTmpdir();
2150     if (pattern[0] == '/') {
2151         snprintf(tfile, sizeof(tfile), "%s", pattern);
2152     } else {
2153         snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern);
2154     }
2155     if ((fd = mkstemp(tfile)) < 0)
2156         Punt("Could not create temporary file %s: %s", tfile, strerror(errno));
2157     if (fnamep) {
2158         *fnamep = bmake_strdup(tfile);
2159     } else {
2160         unlink(tfile);                  /* we just want the descriptor */
2161     }
2162     return fd;
2163 }
2164
2165 /*
2166  * Convert a string representation of a boolean.
2167  * Anything that looks like "No", "False", "Off", "0" etc,
2168  * is FALSE, otherwise TRUE.
2169  */
2170 Boolean
2171 s2Boolean(const char *s, Boolean bf)
2172 {
2173     if (s) {
2174         switch(*s) {
2175         case '\0':                      /* not set - the default wins */
2176             break;
2177         case '0':
2178         case 'F':
2179         case 'f':
2180         case 'N':
2181         case 'n':
2182             bf = FALSE;
2183             break;
2184         case 'O':
2185         case 'o':
2186             switch (s[1]) {
2187             case 'F':
2188             case 'f':
2189                 bf = FALSE;
2190                 break;
2191             default:
2192                 bf = TRUE;
2193                 break;
2194             }
2195             break;
2196         default:
2197             bf = TRUE;
2198             break;
2199         }
2200     }
2201     return bf;
2202 }
2203
2204 /*
2205  * Return a Boolean based on setting of a knob.
2206  *
2207  * If the knob is not set, the supplied default is the return value.
2208  * If set, anything that looks or smells like "No", "False", "Off", "0" etc,
2209  * is FALSE, otherwise TRUE.
2210  */
2211 Boolean
2212 getBoolean(const char *name, Boolean fallback)
2213 {
2214     char *expr = str_concat3("${", name, ":U:tl}");
2215     char *value = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
2216     Boolean res = s2Boolean(value, fallback);
2217     free(value);
2218     free(expr);
2219     return res;
2220 }