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