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