main.c revision 140870
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1988, 1989, 1990, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes * Copyright (c) 1989 by Berkeley Softworks
51590Srgrimes * All rights reserved.
61590Srgrimes *
71590Srgrimes * This code is derived from software contributed to Berkeley by
81590Srgrimes * Adam de Boor.
91590Srgrimes *
101590Srgrimes * Redistribution and use in source and binary forms, with or without
111590Srgrimes * modification, are permitted provided that the following conditions
121590Srgrimes * are met:
131590Srgrimes * 1. Redistributions of source code must retain the above copyright
141590Srgrimes *    notice, this list of conditions and the following disclaimer.
151590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161590Srgrimes *    notice, this list of conditions and the following disclaimer in the
171590Srgrimes *    documentation and/or other materials provided with the distribution.
181590Srgrimes * 3. All advertising materials mentioning features or use of this software
191590Srgrimes *    must display the following acknowledgement:
201590Srgrimes *	This product includes software developed by the University of
211590Srgrimes *	California, Berkeley and its contributors.
221590Srgrimes * 4. Neither the name of the University nor the names of its contributors
231590Srgrimes *    may be used to endorse or promote products derived from this software
241590Srgrimes *    without specific prior written permission.
251590Srgrimes *
261590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
271590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
281590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
291590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
301590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
311590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
321590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
331590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
341590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
351590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
361590Srgrimes * SUCH DAMAGE.
3762833Swsanchez *
3862833Swsanchez * @(#)main.c      8.3 (Berkeley) 3/19/94
391590Srgrimes */
401590Srgrimes
411590Srgrimes#ifndef lint
4294595Sobrien#if 0
4394589Sobrienstatic char copyright[] =
4494589Sobrien"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
4594589Sobrien	The Regents of the University of California.  All rights reserved.\n";
4694595Sobrien#endif
471590Srgrimes#endif /* not lint */
4894589Sobrien#include <sys/cdefs.h>
4994587Sobrien__FBSDID("$FreeBSD: head/usr.bin/make/main.c 140870 2005-01-26 18:19:39Z harti $");
501590Srgrimes
511590Srgrimes/*-
521590Srgrimes * main.c --
531590Srgrimes *	The main file for this entire program. Exit routines etc
541590Srgrimes *	reside here.
551590Srgrimes *
561590Srgrimes * Utility functions defined in this file:
571590Srgrimes *	Main_ParseArgLine	Takes a line of arguments, breaks them and
581590Srgrimes *				treats them as if they were given when first
591590Srgrimes *				invoked. Used by the parse module to implement
601590Srgrimes *				the .MFLAGS target.
611590Srgrimes */
621590Srgrimes
631590Srgrimes#include <sys/param.h>
641590Srgrimes#include <sys/signal.h>
651590Srgrimes#include <sys/stat.h>
6639006Skato#include <sys/sysctl.h>
67127880Sdes#include <sys/time.h>
68127899Sru#include <sys/resource.h>
6918730Ssteve#ifndef MACHINE
705814Sjkh#include <sys/utsname.h>
7118730Ssteve#endif
7218730Ssteve#include <sys/wait.h>
73127880Sdes
7427644Scharnier#include <err.h>
751590Srgrimes#include <errno.h>
761590Srgrimes#include <fcntl.h>
77127880Sdes#include <signal.h>
78127880Sdes#include <stdarg.h>
791590Srgrimes#include <stdio.h>
80127880Sdes#include <stdlib.h>
8149331Shoek#include <sysexits.h>
8263955Simp#include <unistd.h>
83127880Sdes
841590Srgrimes#include "make.h"
851590Srgrimes#include "hash.h"
861590Srgrimes#include "dir.h"
871590Srgrimes#include "job.h"
881590Srgrimes#include "pathnames.h"
891590Srgrimes
90104395Sjmallett#define WANT_ENV_MKLVL	1
91138071Sjmallett#define	MKLVL_MAXVAL	500
92138071Sjmallett#define	MKLVL_ENVVAR	"__MKLVL__"
93104395Sjmallett
941590Srgrimes#define	MAKEFLAGS	".MAKEFLAGS"
951590Srgrimes
96138916Sharti/* Targets to be made */
97138916ShartiLst create = Lst_Initializer(create);
98138916Sharti
991590Srgrimestime_t			now;		/* Time at start of make */
1001590SrgrimesGNode			*DEFAULT;	/* .DEFAULT node */
1011590SrgrimesBoolean			allPrecious;	/* .PRECIOUS given on line by itself */
1021590Srgrimes
1031590Srgrimesstatic Boolean		noBuiltins;	/* -r flag */
104138916Sharti
105138916Sharti/* ordered list of makefiles to read */
106138916Shartistatic Lst makefiles = Lst_Initializer(makefiles);
107138916Sharti
10866365Speterstatic Boolean		expandVars;	/* fully expand printed variables */
109138916Sharti
110138916Sharti/* list of variables to print */
111138916Shartistatic Lst variables = Lst_Initializer(variables);
112138916Sharti
11318730Ssteveint			maxJobs;	/* -j argument */
11428228Sfsmpstatic Boolean          forceJobs;      /* -j argument given */
1151590SrgrimesBoolean			compatMake;	/* -B argument */
1161590SrgrimesBoolean			debug;		/* -d flag */
1171590SrgrimesBoolean			noExecute;	/* -n flag */
1181590SrgrimesBoolean			keepgoing;	/* -k flag */
1191590SrgrimesBoolean			queryFlag;	/* -q flag */
1201590SrgrimesBoolean			touchFlag;	/* -t flag */
1211590SrgrimesBoolean			usePipes;	/* !-P flag */
1221590SrgrimesBoolean			ignoreErrors;	/* -i flag */
1231590SrgrimesBoolean			beSilent;	/* -s flag */
12441151SdgBoolean			beVerbose;	/* -v flag */
1251590SrgrimesBoolean			oldVars;	/* variable substitution style */
1261590SrgrimesBoolean			checkEnvFirst;	/* -e flag */
127138916Sharti
128138916Sharti/* (-E) vars to override from env */
129138916ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
130138916Sharti
131104818SjmallettBoolean			jobsRunning;	/* TRUE if the jobs might be running */
1321590Srgrimes
13392921Simpstatic void		MainParseArgs(int, char **);
13492921Simpchar *			chdir_verify_path(char *, char *);
135138561Shartistatic int		ReadMakefile(const void *, const void *);
13692921Simpstatic void		usage(void);
1371590Srgrimes
1381590Srgrimesstatic char *curdir;			/* startup directory */
1391590Srgrimesstatic char *objdir;			/* where we chdir'ed to */
1401590Srgrimes
141133085Sharti/*
142133085Sharti * Append a flag with an optional argument to MAKEFLAGS and MFLAGS
143133085Sharti */
144133085Shartistatic void
145133085ShartiMFLAGS_append(char *flag, char *arg)
146133085Sharti{
147140870Sharti	char *str;
148138232Sharti
149133085Sharti	Var_Append(MAKEFLAGS, flag, VAR_GLOBAL);
150140870Sharti	if (arg != NULL) {
151140870Sharti		str = MAKEFLAGS_quote(arg);
152140870Sharti		Var_Append(MAKEFLAGS, str, VAR_GLOBAL);
153140870Sharti		free(str);
154140870Sharti	}
155133085Sharti
156133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
157140870Sharti	if (arg != NULL) {
158140870Sharti		str = MAKEFLAGS_quote(arg);
159140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
160140870Sharti		free(str);
161140870Sharti	}
162133085Sharti}
163133085Sharti
1641590Srgrimes/*-
1651590Srgrimes * MainParseArgs --
1661590Srgrimes *	Parse a given argument vector. Called from main() and from
1671590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
1681590Srgrimes *
1691590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
1701590Srgrimes *
1711590Srgrimes * Results:
1721590Srgrimes *	None
1731590Srgrimes *
1741590Srgrimes * Side Effects:
1751590Srgrimes *	Various global and local flags will be set depending on the flags
1761590Srgrimes *	given
1771590Srgrimes */
1781590Srgrimesstatic void
179104696SjmallettMainParseArgs(int argc, char **argv)
1801590Srgrimes{
1815814Sjkh	int c;
1821590Srgrimes
1831590Srgrimes	optind = 1;	/* since we're called more than once */
184137202Sharti#define OPTFLAGS "BC:D:E:I:PSV:Xd:ef:ij:km:nqrstv"
18524360Simprearg:	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
1861590Srgrimes		switch(c) {
187102393Sjmallett		case 'C':
188107964Sseanc			if (chdir(optarg) == -1)
189107964Sseanc				err(1, "chdir %s", optarg);
190102393Sjmallett			break;
1911590Srgrimes		case 'D':
1921590Srgrimes			Var_Set(optarg, "1", VAR_GLOBAL);
193133085Sharti			MFLAGS_append("-D", optarg);
1941590Srgrimes			break;
1951590Srgrimes		case 'I':
1961590Srgrimes			Parse_AddIncludeDir(optarg);
197133085Sharti			MFLAGS_append("-I", optarg);
1981590Srgrimes			break;
19917193Sbde		case 'V':
200138920Sru			Lst_AtEnd(&variables, estrdup(optarg));
201133085Sharti			MFLAGS_append("-V", optarg);
20217193Sbde			break;
20366365Speter		case 'X':
20466365Speter			expandVars = FALSE;
20566365Speter			break;
2061590Srgrimes		case 'B':
2071590Srgrimes			compatMake = TRUE;
208133085Sharti			MFLAGS_append("-B", NULL);
209137626Sphk			unsetenv("MAKE_JOBS_FIFO");
2101590Srgrimes			break;
2111590Srgrimes		case 'P':
2121590Srgrimes			usePipes = FALSE;
213133085Sharti			MFLAGS_append("-P", NULL);
2141590Srgrimes			break;
2151590Srgrimes		case 'S':
2161590Srgrimes			keepgoing = FALSE;
217133085Sharti			MFLAGS_append("-S", NULL);
2181590Srgrimes			break;
2191590Srgrimes		case 'd': {
2201590Srgrimes			char *modules = optarg;
2211590Srgrimes
2221590Srgrimes			for (; *modules; ++modules)
2231590Srgrimes				switch (*modules) {
2241590Srgrimes				case 'A':
2251590Srgrimes					debug = ~0;
2261590Srgrimes					break;
2271590Srgrimes				case 'a':
2281590Srgrimes					debug |= DEBUG_ARCH;
2291590Srgrimes					break;
2301590Srgrimes				case 'c':
2311590Srgrimes					debug |= DEBUG_COND;
2321590Srgrimes					break;
2331590Srgrimes				case 'd':
2341590Srgrimes					debug |= DEBUG_DIR;
2351590Srgrimes					break;
2361590Srgrimes				case 'f':
2371590Srgrimes					debug |= DEBUG_FOR;
2381590Srgrimes					break;
2391590Srgrimes				case 'g':
2401590Srgrimes					if (modules[1] == '1') {
2411590Srgrimes						debug |= DEBUG_GRAPH1;
2421590Srgrimes						++modules;
2431590Srgrimes					}
2441590Srgrimes					else if (modules[1] == '2') {
2451590Srgrimes						debug |= DEBUG_GRAPH2;
2461590Srgrimes						++modules;
2471590Srgrimes					}
2481590Srgrimes					break;
2491590Srgrimes				case 'j':
2501590Srgrimes					debug |= DEBUG_JOB;
2511590Srgrimes					break;
25260569Swill				case 'l':
25360569Swill					debug |= DEBUG_LOUD;
25460569Swill					break;
2551590Srgrimes				case 'm':
2561590Srgrimes					debug |= DEBUG_MAKE;
2571590Srgrimes					break;
2581590Srgrimes				case 's':
2591590Srgrimes					debug |= DEBUG_SUFF;
2601590Srgrimes					break;
2611590Srgrimes				case 't':
2621590Srgrimes					debug |= DEBUG_TARG;
2631590Srgrimes					break;
2641590Srgrimes				case 'v':
2651590Srgrimes					debug |= DEBUG_VAR;
2661590Srgrimes					break;
2671590Srgrimes				default:
26827644Scharnier					warnx("illegal argument to d option -- %c", *modules);
2691590Srgrimes					usage();
2701590Srgrimes				}
271133085Sharti			MFLAGS_append("-d", optarg);
2721590Srgrimes			break;
2731590Srgrimes		}
27449332Shoek		case 'E':
275138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
276133085Sharti			MFLAGS_append("-E", optarg);
27749332Shoek			break;
2781590Srgrimes		case 'e':
2791590Srgrimes			checkEnvFirst = TRUE;
280133085Sharti			MFLAGS_append("-e", NULL);
2811590Srgrimes			break;
2821590Srgrimes		case 'f':
283138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
2841590Srgrimes			break;
2851590Srgrimes		case 'i':
2861590Srgrimes			ignoreErrors = TRUE;
287133085Sharti			MFLAGS_append("-i", NULL);
2881590Srgrimes			break;
28949331Shoek		case 'j': {
29049331Shoek			char *endptr;
29149331Shoek
29218730Ssteve			forceJobs = TRUE;
29349331Shoek			maxJobs = strtol(optarg, &endptr, 10);
29449331Shoek			if (maxJobs <= 0 || *endptr != '\0') {
29549938Shoek				warnx("illegal number, -j argument -- %s",
29649938Shoek				    optarg);
29749938Shoek				usage();
29849331Shoek			}
299133085Sharti			MFLAGS_append("-j", optarg);
3001590Srgrimes			break;
30149331Shoek		}
3021590Srgrimes		case 'k':
3031590Srgrimes			keepgoing = TRUE;
304133085Sharti			MFLAGS_append("-k", NULL);
3051590Srgrimes			break;
30618730Ssteve		case 'm':
307138916Sharti			Dir_AddDir(&sysIncPath, optarg);
308133085Sharti			MFLAGS_append("-m", optarg);
30918730Ssteve			break;
3101590Srgrimes		case 'n':
3111590Srgrimes			noExecute = TRUE;
312133085Sharti			MFLAGS_append("-n", NULL);
3131590Srgrimes			break;
3141590Srgrimes		case 'q':
3151590Srgrimes			queryFlag = TRUE;
3161590Srgrimes			/* Kind of nonsensical, wot? */
317133085Sharti			MFLAGS_append("-q", NULL);
3181590Srgrimes			break;
3191590Srgrimes		case 'r':
3201590Srgrimes			noBuiltins = TRUE;
321133085Sharti			MFLAGS_append("-r", NULL);
3221590Srgrimes			break;
3231590Srgrimes		case 's':
3241590Srgrimes			beSilent = TRUE;
325133085Sharti			MFLAGS_append("-s", NULL);
3261590Srgrimes			break;
3271590Srgrimes		case 't':
3281590Srgrimes			touchFlag = TRUE;
329133085Sharti			MFLAGS_append("-t", NULL);
3301590Srgrimes			break;
33141151Sdg		case 'v':
33241151Sdg			beVerbose = TRUE;
333133085Sharti			MFLAGS_append("-v", NULL);
33441151Sdg			break;
3351590Srgrimes		default:
3361590Srgrimes		case '?':
3371590Srgrimes			usage();
3381590Srgrimes		}
3391590Srgrimes	}
3401590Srgrimes
3411590Srgrimes	oldVars = TRUE;
3421590Srgrimes
3431590Srgrimes	/*
3441590Srgrimes	 * See if the rest of the arguments are variable assignments and
3451590Srgrimes	 * perform them if so. Else take them to be targets and stuff them
3461590Srgrimes	 * on the end of the "create" list.
3471590Srgrimes	 */
3481590Srgrimes	for (argv += optind, argc -= optind; *argv; ++argv, --argc)
349133562Sharti		if (Parse_IsVar(*argv)) {
350140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
351133562Sharti
352133562Sharti			Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
353133562Sharti			free(ptr);
354133562Sharti
3551590Srgrimes			Parse_DoVar(*argv, VAR_CMD);
356133562Sharti		} else {
3571590Srgrimes			if (!**argv)
3581590Srgrimes				Punt("illegal (null) argument.");
3591590Srgrimes			if (**argv == '-') {
3601590Srgrimes				if ((*argv)[1])
3611590Srgrimes					optind = 0;     /* -flag... */
3621590Srgrimes				else
3631590Srgrimes					optind = 1;     /* - */
3641590Srgrimes				goto rearg;
3651590Srgrimes			}
366138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
3671590Srgrimes		}
3681590Srgrimes}
3691590Srgrimes
3701590Srgrimes/*-
3711590Srgrimes * Main_ParseArgLine --
3721590Srgrimes *  	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
3731590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
3741590Srgrimes *	Takes a line of arguments and breaks it into its
3751590Srgrimes * 	component words and passes those words and the number of them to the
3761590Srgrimes *	MainParseArgs function.
3771590Srgrimes *	The line should have all its leading whitespace removed.
3781590Srgrimes *
3791590Srgrimes * Results:
3801590Srgrimes *	None
3811590Srgrimes *
3821590Srgrimes * Side Effects:
3831590Srgrimes *	Only those that come from the various arguments.
3841590Srgrimes */
3851590Srgrimesvoid
386140870ShartiMain_ParseArgLine(char *line, int mflags)
3871590Srgrimes{
3881590Srgrimes	char **argv;			/* Manufactured argument vector */
3891590Srgrimes	int argc;			/* Number of arguments in argv */
3901590Srgrimes
3911590Srgrimes	if (line == NULL)
3921590Srgrimes		return;
3931590Srgrimes	for (; *line == ' '; ++line)
3941590Srgrimes		continue;
3951590Srgrimes	if (!*line)
3961590Srgrimes		return;
3971590Srgrimes
398140870Sharti	if (mflags)
399140870Sharti		argv = MAKEFLAGS_break(line, &argc);
400140870Sharti	else
401140870Sharti		argv = brk_string(line, &argc, TRUE);
402140870Sharti
4031590Srgrimes	MainParseArgs(argc, argv);
4041590Srgrimes}
4051590Srgrimes
40618339Sswallacechar *
407104696Sjmallettchdir_verify_path(char *path, char *obpath)
40818339Sswallace{
40918339Sswallace	struct stat sb;
41018339Sswallace
41118339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
41275973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
41327644Scharnier			warn("warning: %s", path);
414138232Sharti			return (0);
41518339Sswallace		}
416138232Sharti		return (obpath);
41718339Sswallace	}
41818339Sswallace
419138232Sharti	return (0);
42018339Sswallace}
42118339Sswallace
422133082Shartistatic void
423133082Sharticatch_child(int sig __unused)
424123513Sdes{
425123513Sdes}
42618339Sswallace
427138071Sjmallett/*
428138071Sjmallett * In lieu of a good way to prevent every possible looping in
429138071Sjmallett * make(1), stop there from being more than MKLVL_MAXVAL processes forked
430138071Sjmallett * by make(1), to prevent a forkbomb from happening, in a dumb and
431138071Sjmallett * mechanical way.
432138071Sjmallett */
433138071Sjmallettstatic void
434138071Sjmallettcheck_make_level(void)
435138071Sjmallett{
436138071Sjmallett#ifdef WANT_ENV_MKLVL
437138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
438138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
439138071Sjmallett
440138071Sjmallett	if (level < 0) {
441138071Sjmallett		errc(2, EAGAIN, "Invalid value for recursion level (%d).", level);
442138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
443138071Sjmallett		errc(2, EAGAIN, "Max recursion level (%d) exceeded.", MKLVL_MAXVAL);
444138071Sjmallett	} else {
445138071Sjmallett		char new_value[32];
446138071Sjmallett		sprintf(new_value, "%d", level + 1);
447138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
448138071Sjmallett	}
449138071Sjmallett#endif /* WANT_ENV_MKLVL */
450138071Sjmallett}
451138071Sjmallett
4521590Srgrimes/*-
4531590Srgrimes * main --
4541590Srgrimes *	The main function, for obvious reasons. Initializes variables
4551590Srgrimes *	and a few modules, then parses the arguments give it in the
4561590Srgrimes *	environment and on the command line. Reads the system makefile
4571590Srgrimes *	followed by either Makefile, makefile or the file given by the
4581590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
4591590Srgrimes *	flags it has received by then uses either the Make or the Compat
4601590Srgrimes *	module to create the initial list of targets.
4611590Srgrimes *
4621590Srgrimes * Results:
4631590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
4641590Srgrimes *	0.
4651590Srgrimes *
4661590Srgrimes * Side Effects:
4671590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
4681590Srgrimes */
4691590Srgrimesint
470104696Sjmallettmain(int argc, char **argv)
4711590Srgrimes{
4721590Srgrimes	Boolean outOfDate = TRUE; 	/* FALSE if all targets up to date */
47340500Sobrien	struct stat sa;
47440500Sobrien	char *p, *p1, *path, *pathp;
47573262Simp	char mdpath[MAXPATHLEN];
47673262Simp	char obpath[MAXPATHLEN];
47773262Simp	char cdpath[MAXPATHLEN];
4785814Sjkh    	char *machine = getenv("MACHINE");
47944362Simp	char *machine_arch = getenv("MACHINE_ARCH");
48072679Skris	char *machine_cpu = getenv("MACHINE_CPU");
48118730Ssteve	char *cp = NULL, *start;
48218730Ssteve					/* avoid faults on read-only strings */
48318730Ssteve	static char syspath[] = _PATH_DEFSYSPATH;
4841590Srgrimes
485123513Sdes	{
486123513Sdes	/*
487123513Sdes	 * Catch SIGCHLD so that we get kicked out of select() when we
488123513Sdes	 * need to look at a child.  This is only known to matter for the
489123513Sdes	 * -j case (perhaps without -P).
490123513Sdes	 *
491123513Sdes	 * XXX this is intentionally misplaced.
492123513Sdes	 */
493123513Sdes	struct sigaction sa;
494123513Sdes
495123513Sdes	sigemptyset(&sa.sa_mask);
496123513Sdes	sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
497123513Sdes	sa.sa_handler = catch_child;
498123513Sdes	sigaction(SIGCHLD, &sa, NULL);
499123513Sdes	}
500123513Sdes
501138071Sjmallett	check_make_level();
502104395Sjmallett
50364739Sgreen#if DEFSHELL == 2
50464739Sgreen	/*
50564739Sgreen	 * Turn off ENV to make ksh happier.
50664739Sgreen	 */
50764739Sgreen	unsetenv("ENV");
50864739Sgreen#endif
50964739Sgreen
51018730Ssteve#ifdef RLIMIT_NOFILE
5111590Srgrimes	/*
51218730Ssteve	 * get rid of resource limit on file descriptors
51318730Ssteve	 */
51418730Ssteve	{
51518730Ssteve		struct rlimit rl;
51618730Ssteve		if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
51718730Ssteve		    rl.rlim_cur != rl.rlim_max) {
51818730Ssteve			rl.rlim_cur = rl.rlim_max;
519138232Sharti			setrlimit(RLIMIT_NOFILE, &rl);
52018730Ssteve		}
52118730Ssteve	}
52218730Ssteve#endif
5231590Srgrimes
5245814Sjkh	/*
52539006Skato	 * PC-98 kernel sets the `i386' string to the utsname.machine and
52639006Skato	 * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
52739006Skato	 * we check machine.ispc98 and adjust the machine variable before
52839006Skato	 * using usname(3) below.
52953631Smarcel	 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
53053631Smarcel	 * __FreeBSD_version was defined as 300003. So, this check can
53153631Smarcel	 * safely be done with any kernel with version > 300003.
53239006Skato	 */
53339006Skato	if (!machine) {
53439006Skato		int	ispc98;
53539006Skato		size_t	len;
53639006Skato
53739006Skato		len = sizeof(ispc98);
53839006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
53939006Skato			if (ispc98)
54039006Skato				machine = "pc98";
54139006Skato		}
54239006Skato	}
54339006Skato
54439006Skato	/*
5455814Sjkh	 * Get the name of this type of MACHINE from utsname
5465814Sjkh	 * so we can share an executable for similar machines.
5475814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
5485814Sjkh	 *
5495814Sjkh	 * Note that while MACHINE is decided at run-time,
5505814Sjkh	 * MACHINE_ARCH is always known at compile time.
5515814Sjkh	 */
55218864Ssteve	if (!machine) {
55318339Sswallace#ifndef MACHINE
55418730Ssteve	    struct utsname utsname;
55518730Ssteve
55694506Scharnier	    if (uname(&utsname) == -1)
55794506Scharnier		    err(2, "uname");
5585814Sjkh	    machine = utsname.machine;
55918339Sswallace#else
56018339Sswallace	    machine = MACHINE;
56118339Sswallace#endif
5625814Sjkh	}
5631590Srgrimes
56444362Simp	if (!machine_arch) {
56544362Simp#ifndef MACHINE_ARCH
56644362Simp		machine_arch = "unknown";
56744362Simp#else
56844362Simp		machine_arch = MACHINE_ARCH;
56944362Simp#endif
57044362Simp	}
57144362Simp
5721590Srgrimes	/*
57372679Skris	 * Set machine_cpu to the minumum supported CPU revision based
57472679Skris	 * on the target architecture, if not already set.
57572679Skris	 */
57672679Skris	if (!machine_cpu) {
57772679Skris		if (!strcmp(machine_arch, "i386"))
57872679Skris			machine_cpu = "i386";
57972679Skris		else if (!strcmp(machine_arch, "alpha"))
58072679Skris			machine_cpu = "ev4";
58172679Skris		else
58272679Skris			machine_cpu = "unknown";
58372679Skris	}
5841590Srgrimes
58566365Speter	expandVars = TRUE;
5861590Srgrimes	beSilent = FALSE;		/* Print commands as executed */
5871590Srgrimes	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
5881590Srgrimes	noExecute = FALSE;		/* Execute all commands */
5891590Srgrimes	keepgoing = FALSE;		/* Stop on error */
5901590Srgrimes	allPrecious = FALSE;		/* Remove targets when interrupted */
5911590Srgrimes	queryFlag = FALSE;		/* This is not just a check-run */
5921590Srgrimes	noBuiltins = FALSE;		/* Read the built-in rules */
5931590Srgrimes	touchFlag = FALSE;		/* Actually update targets */
5941590Srgrimes	usePipes = TRUE;		/* Catch child output in pipes */
5951590Srgrimes	debug = 0;			/* No debug verbosity, please. */
5961590Srgrimes	jobsRunning = FALSE;
5971590Srgrimes
598137571Sphk	maxJobs = DEFMAXJOBS;
59928228Sfsmp	forceJobs = FALSE;              /* No -j flag */
60018730Ssteve	compatMake = FALSE;		/* No compat mode */
6011590Srgrimes
6021590Srgrimes	/*
6031590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
6041590Srgrimes	 * for the reading of inclusion paths and variable settings on the
6051590Srgrimes	 * command line
6061590Srgrimes	 */
6071590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
6081590Srgrimes				 * can be processed correctly */
6091590Srgrimes	Parse_Init();		/* Need to initialize the paths of #include
6101590Srgrimes				 * directories */
6111590Srgrimes	Var_Init();		/* As well as the lists of variables for
6121590Srgrimes				 * parsing arguments */
6135814Sjkh        str_init();
6141590Srgrimes
6151590Srgrimes	/*
6161590Srgrimes	 * Initialize various variables.
6171590Srgrimes	 *	MAKE also gets this name, for compatibility
6181590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
6191590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
6201590Srgrimes	 */
6211590Srgrimes	Var_Set("MAKE", argv[0], VAR_GLOBAL);
6221590Srgrimes	Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
6231590Srgrimes	Var_Set("MFLAGS", "", VAR_GLOBAL);
6245814Sjkh	Var_Set("MACHINE", machine, VAR_GLOBAL);
62544362Simp	Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
62672679Skris	Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
62797121Sru#ifdef MAKE_VERSION
62897121Sru	Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
62997121Sru#endif
6301590Srgrimes
6311590Srgrimes	/*
6321590Srgrimes	 * First snag any flags out of the MAKE environment variable.
6331590Srgrimes	 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
6341590Srgrimes	 * in a different format).
6351590Srgrimes	 */
636140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
6378874Srgrimes
6381590Srgrimes	MainParseArgs(argc, argv);
6391590Srgrimes
6401590Srgrimes	/*
641120053Sru	 * Find where we are...
642120053Sru	 * All this code is so that we know where we are when we start up
643120053Sru	 * on a different machine with pmake.
644120053Sru	 */
645120053Sru	curdir = cdpath;
646120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
647120053Sru		err(2, NULL);
648120053Sru
649120053Sru	if (stat(curdir, &sa) == -1)
650120053Sru	    err(2, "%s", curdir);
651120053Sru
652120053Sru	/*
653120053Sru	 * The object directory location is determined using the
654120053Sru	 * following order of preference:
655120053Sru	 *
656120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
657120053Sru	 *	2. MAKEOBJDIR
658120053Sru	 *	3. _PATH_OBJDIR.${MACHINE}
659120053Sru	 *	4. _PATH_OBJDIR
660120053Sru	 *	5. _PATH_OBJDIRPREFIX`cwd`
661120053Sru	 *
662120053Sru	 * If one of the first two fails, use the current directory.
663120053Sru	 * If the remaining three all fail, use the current directory.
664120053Sru	 *
665120053Sru	 * Once things are initted,
666120053Sru	 * have to add the original directory to the search path,
667120053Sru	 * and modify the paths for the Makefiles apropriately.  The
668120053Sru	 * current directory is also placed as a variable for make scripts.
669120053Sru	 */
670120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
671120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
672120053Sru			path = _PATH_OBJDIR;
673120053Sru			pathp = _PATH_OBJDIRPREFIX;
674138232Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s",
675120053Sru					path, machine);
676120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
677120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
678138232Sharti					snprintf(mdpath, MAXPATHLEN,
679120053Sru							"%s%s", pathp, curdir);
680120053Sru					if (!(objdir=chdir_verify_path(mdpath,
681120053Sru								       obpath)))
682120053Sru						objdir = curdir;
683120053Sru				}
684120053Sru		}
685120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
686120053Sru			objdir = curdir;
687120053Sru	}
688120053Sru	else {
689138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
690120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
691120053Sru			objdir = curdir;
692120053Sru	}
693120053Sru	Dir_InitDot();		/* Initialize the "." directory */
694120053Sru	if (objdir != curdir)
695138916Sharti		Dir_AddDir(&dirSearchPath, curdir);
696120053Sru	Var_Set(".CURDIR", curdir, VAR_GLOBAL);
697120053Sru	Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
698120053Sru
699137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
700137606Sphk		forceJobs = TRUE;
701120053Sru	/*
70228228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
70328228Sfsmp	 * turned compatibility on
70428228Sfsmp	 */
70528228Sfsmp	if (!compatMake && !forceJobs)
70628228Sfsmp		compatMake = TRUE;
70728228Sfsmp
70828228Sfsmp	/*
7091590Srgrimes	 * Initialize archive, target and suffix modules in preparation for
7101590Srgrimes	 * parsing the makefile(s)
7111590Srgrimes	 */
7121590Srgrimes	Arch_Init();
7131590Srgrimes	Targ_Init();
7141590Srgrimes	Suff_Init();
7151590Srgrimes
71669527Swill	DEFAULT = NULL;
717138232Sharti	time(&now);
7181590Srgrimes
7191590Srgrimes	/*
7201590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
7211590Srgrimes	 * created. If none specified, make the variable empty -- the parser
7221590Srgrimes	 * will fill the thing in with the default or .MAIN target.
7231590Srgrimes	 */
724138916Sharti	if (!Lst_IsEmpty(&create)) {
725138512Sharti		LstNode *ln;
7261590Srgrimes
727138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
728138264Sharti			char *name = Lst_Datum(ln);
7291590Srgrimes
7301590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
7311590Srgrimes		}
7321590Srgrimes	} else
7331590Srgrimes		Var_Set(".TARGETS", "", VAR_GLOBAL);
7341590Srgrimes
73518730Ssteve
7361590Srgrimes	/*
73718730Ssteve	 * If no user-supplied system path was given (through the -m option)
73818730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
73918730Ssteve	 * as dir1:...:dirn) to the system include path.
7401590Srgrimes	 */
741138916Sharti	if (Lst_IsEmpty(&sysIncPath)) {
74218730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
74318730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
74418730Ssteve				continue;
74518730Ssteve			if (*cp == '\0') {
746138916Sharti				Dir_AddDir(&sysIncPath, start);
74718730Ssteve			} else {
74818730Ssteve				*cp++ = '\0';
749138916Sharti				Dir_AddDir(&sysIncPath, start);
75018730Ssteve			}
75118730Ssteve		}
75218730Ssteve	}
7531590Srgrimes
75418730Ssteve	/*
75518730Ssteve	 * Read in the built-in rules first, followed by the specified
75618730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
75718730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
75818730Ssteve	 */
75918730Ssteve	if (!noBuiltins) {
760138916Sharti		/* Path of sys.mk */
761138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
762138512Sharti		LstNode *ln;
76318730Ssteve
764138916Sharti		Dir_Expand(_PATH_DEFSYSMK, &sysIncPath, &sysMkPath);
765138916Sharti		if (Lst_IsEmpty(&sysMkPath))
76618730Ssteve			Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
767138916Sharti		ln = Lst_Find(&sysMkPath, NULL, ReadMakefile);
76869527Swill		if (ln != NULL)
76918730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
770138916Sharti		Lst_Destroy(&sysMkPath, free);
77118730Ssteve	}
77218730Ssteve
773138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
774138512Sharti		LstNode *ln;
7751590Srgrimes
776138916Sharti		ln = Lst_Find(&makefiles, NULL, ReadMakefile);
77769527Swill		if (ln != NULL)
7781590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
77994594Sobrien	} else if (!ReadMakefile("BSDmakefile", NULL))
78094594Sobrien	    if (!ReadMakefile("makefile", NULL))
781138232Sharti		ReadMakefile("Makefile", NULL);
7821590Srgrimes
783138232Sharti	ReadMakefile(".depend", NULL);
7841590Srgrimes
7851590Srgrimes	/* Install all the flags into the MAKE envariable. */
7865814Sjkh	if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
7871590Srgrimes		setenv("MAKEFLAGS", p, 1);
788105826Sjmallett	free(p1);
7891590Srgrimes
7901590Srgrimes	/*
7911590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
7921590Srgrimes	 * and add them to the search path, if the variable is defined. The
7931590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
7941590Srgrimes	 * <directory>:<directory>:<directory>...
7951590Srgrimes	 */
7961590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
797104692Sjmallett		char *vpath, savec;
7981590Srgrimes		/*
7991590Srgrimes		 * GCC stores string constants in read-only memory, but
8001590Srgrimes		 * Var_Subst will want to write this thing, so store it
8011590Srgrimes		 * in an array
8021590Srgrimes		 */
8031590Srgrimes		static char VPATH[] = "${VPATH}";
8041590Srgrimes
8051590Srgrimes		vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
806104692Sjmallett		path = vpath;
8071590Srgrimes		do {
8081590Srgrimes			/* skip to end of directory */
809104692Sjmallett			for (cp = path; *cp != ':' && *cp != '\0'; cp++)
8101590Srgrimes				continue;
8111590Srgrimes			/* Save terminator character so know when to stop */
812104692Sjmallett			savec = *cp;
813104692Sjmallett			*cp = '\0';
8141590Srgrimes			/* Add directory to search path */
815138916Sharti			Dir_AddDir(&dirSearchPath, path);
816104692Sjmallett			*cp = savec;
817104692Sjmallett			path = cp + 1;
8181590Srgrimes		} while (savec == ':');
819138232Sharti		free(vpath);
8201590Srgrimes	}
8211590Srgrimes
8221590Srgrimes	/*
8231590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
8241590Srgrimes	 * time to add the default search path to their lists...
8251590Srgrimes	 */
8261590Srgrimes	Suff_DoPaths();
8271590Srgrimes
8281590Srgrimes	/* print the initial graph, if the user requested it */
8291590Srgrimes	if (DEBUG(GRAPH1))
8301590Srgrimes		Targ_PrintGraph(1);
8311590Srgrimes
83217193Sbde	/* print the values of any variables requested by the user */
833138916Sharti	if (!Lst_IsEmpty(&variables)) {
834138512Sharti		LstNode *ln;
83517193Sbde
836138916Sharti		for (ln = Lst_First(&variables); ln != NULL;
83717193Sbde		    ln = Lst_Succ(ln)) {
83866365Speter			char *value;
83966365Speter			if (expandVars) {
840138264Sharti				p1 = emalloc(strlen(Lst_Datum(ln)) + 1 + 3);
84166365Speter				/* This sprintf is safe, because of the malloc above */
842138232Sharti				sprintf(p1, "${%s}", (char *)Lst_Datum(ln));
84366365Speter				value = Var_Subst(NULL, p1, VAR_GLOBAL, FALSE);
84466365Speter			} else {
845138264Sharti				value = Var_Value(Lst_Datum(ln),
84666365Speter						  VAR_GLOBAL, &p1);
84766365Speter			}
84817193Sbde			printf("%s\n", value ? value : "");
84966365Speter			if (p1)
85066365Speter				free(p1);
85117193Sbde		}
852101460Sru	} else {
85317193Sbde
8541590Srgrimes		/*
855101460Sru		 * Have now read the entire graph and need to make a list of targets
856101460Sru		 * to create. If none was given on the command line, we consult the
857101460Sru		 * parsing module to find the main target(s) to create.
8581590Srgrimes		 */
859138916Sharti		Lst targs = Lst_Initializer(targs);
860138916Sharti
861138916Sharti		if (Lst_IsEmpty(&create))
862138916Sharti			Parse_MainName(&targs);
863101460Sru		else
864138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
865101460Sru
866101460Sru		if (!compatMake) {
867101460Sru			/*
868101460Sru			 * Initialize job module before traversing the graph, now that
869101460Sru			 * any .BEGIN and .END targets have been read.  This is done
870101460Sru			 * only if the -q flag wasn't given (to prevent the .BEGIN from
871101460Sru			 * being executed should it exist).
872101460Sru			 */
873101460Sru			if (!queryFlag) {
874137572Sphk				Job_Init(maxJobs);
875101460Sru				jobsRunning = TRUE;
876101460Sru			}
877101460Sru
878101460Sru			/* Traverse the graph, checking on all the targets */
879138916Sharti			outOfDate = Make_Run(&targs);
880101460Sru		} else {
881101460Sru			/*
882101460Sru			 * Compat_Init will take care of creating all the targets as
883101460Sru			 * well as initializing the module.
884101460Sru			 */
885138916Sharti			Compat_Run(&targs);
886120718Sru			outOfDate = 0;
8871590Srgrimes		}
888138916Sharti		Lst_Destroy(&targs, NOFREE);
88917193Sbde	}
8908874Srgrimes
891138920Sru	Lst_Destroy(&variables, free);
892138920Sru	Lst_Destroy(&makefiles, free);
893138916Sharti	Lst_Destroy(&create, free);
8945814Sjkh
8951590Srgrimes	/* print the graph now it's been processed if the user requested it */
8961590Srgrimes	if (DEBUG(GRAPH2))
8971590Srgrimes		Targ_PrintGraph(2);
8981590Srgrimes
8991590Srgrimes	if (queryFlag && outOfDate)
900138232Sharti		return (1);
9011590Srgrimes	else
902138232Sharti		return (0);
9031590Srgrimes}
9041590Srgrimes
9051590Srgrimes/*-
9061590Srgrimes * ReadMakefile  --
9071590Srgrimes *	Open and parse the given makefile.
9081590Srgrimes *
9091590Srgrimes * Results:
9101590Srgrimes *	TRUE if ok. FALSE if couldn't open file.
9111590Srgrimes *
9121590Srgrimes * Side Effects:
9131590Srgrimes *	lots
9141590Srgrimes */
9151590Srgrimesstatic Boolean
916138561ShartiReadMakefile(const void *p, const void *q __unused)
9171590Srgrimes{
918104696Sjmallett	char *fname;			/* makefile to read */
9191590Srgrimes	FILE *stream;
92073262Simp	char *name, path[MAXPATHLEN];
92197163Sjmallett	char *MAKEFILE;
92294990Sru	int setMAKEFILE;
9231590Srgrimes
924138561Sharti	/* XXX - remove this once constification is done */
925138561Sharti	fname = estrdup(p);
926104696Sjmallett
9271590Srgrimes	if (!strcmp(fname, "-")) {
9281590Srgrimes		Parse_File("(stdin)", stdin);
9291590Srgrimes		Var_Set("MAKEFILE", "", VAR_GLOBAL);
9301590Srgrimes	} else {
93194990Sru		setMAKEFILE = strcmp(fname, ".depend");
93294990Sru
9331590Srgrimes		/* if we've chdir'd, rebuild the path name */
9341590Srgrimes		if (curdir != objdir && *fname != '/') {
935138232Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
936100733Simp			/*
937100733Simp			 * XXX The realpath stuff breaks relative includes
938100733Simp			 * XXX in some cases.   The problem likely is in
939100733Simp			 * XXX parse.c where it does special things in
940100733Simp			 * XXX ParseDoInclude if the file is relateive
941100733Simp			 * XXX or absolute and not a system file.  There
942100733Simp			 * XXX it assumes that if the current file that's
943100733Simp			 * XXX being included is absolute, that any files
944100733Simp			 * XXX that it includes shouldn't do the -I path
945100733Simp			 * XXX stuff, which is inconsistant with historical
946100733Simp			 * XXX behavior.  However, I can't pentrate the mists
947100733Simp			 * XXX further, so I'm putting this workaround in
948100733Simp			 * XXX here until such time as the underlying bug
949100733Simp			 * XXX can be fixed.
950100733Simp			 */
951100733Simp#if THIS_BREAKS_THINGS
95297077Sjmallett			if (realpath(path, path) != NULL &&
95397077Sjmallett			    (stream = fopen(path, "r")) != NULL) {
95497163Sjmallett				MAKEFILE = fname;
9551590Srgrimes				fname = path;
9561590Srgrimes				goto found;
9571590Srgrimes			}
95897077Sjmallett		} else if (realpath(fname, path) != NULL) {
95997163Sjmallett			MAKEFILE = fname;
96097077Sjmallett			fname = path;
96197077Sjmallett			if ((stream = fopen(fname, "r")) != NULL)
96297077Sjmallett				goto found;
96397077Sjmallett		}
964100733Simp#else
965100733Simp			if ((stream = fopen(path, "r")) != NULL) {
966100733Simp				MAKEFILE = fname;
967100733Simp				fname = path;
968100733Simp				goto found;
969100733Simp			}
970100733Simp		} else {
971100733Simp			MAKEFILE = fname;
972100733Simp			if ((stream = fopen(fname, "r")) != NULL)
973100733Simp				goto found;
974100733Simp		}
975100733Simp#endif
9761590Srgrimes		/* look in -I and system include directories. */
977138916Sharti		name = Dir_FindFile(fname, &parseIncPath);
9781590Srgrimes		if (!name)
979138916Sharti			name = Dir_FindFile(fname, &sysIncPath);
9801590Srgrimes		if (!name || !(stream = fopen(name, "r")))
981138232Sharti			return (FALSE);
98297163Sjmallett		MAKEFILE = fname = name;
9831590Srgrimes		/*
9841590Srgrimes		 * set the MAKEFILE variable desired by System V fans -- the
9851590Srgrimes		 * placement of the setting here means it gets set to the last
9861590Srgrimes		 * makefile specified, as it is set by SysV make.
9871590Srgrimes		 */
98894990Srufound:
98994990Sru		if (setMAKEFILE)
99097163Sjmallett			Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
9911590Srgrimes		Parse_File(fname, stream);
992138232Sharti		fclose(stream);
9931590Srgrimes	}
994138232Sharti	return (TRUE);
9951590Srgrimes}
9961590Srgrimes
9971590Srgrimes/*-
99818730Ssteve * Cmd_Exec --
99918730Ssteve *	Execute the command in cmd, and return the output of that command
100018730Ssteve *	in a string.
100118730Ssteve *
100218730Ssteve * Results:
100318730Ssteve *	A string containing the output of the command, or the empty string
1004104121Sjmallett *	If error is not NULL, it contains the reason for the command failure
100518730Ssteve *
100618730Ssteve * Side Effects:
100718730Ssteve *	The string must be freed by the caller.
100818730Ssteve */
100918730Sstevechar *
1010104696SjmallettCmd_Exec(char *cmd, char **error)
101118730Ssteve{
101218730Ssteve    char	*args[4];   	/* Args for invoking the shell */
101318730Ssteve    int 	fds[2];	    	/* Pipe streams */
101418730Ssteve    int 	cpid;	    	/* Child PID */
101518730Ssteve    int 	pid;	    	/* PID from wait() */
101618730Ssteve    char	*res;		/* result */
101718730Ssteve    int		status;		/* command exit status */
101818730Ssteve    Buffer	buf;		/* buffer to store the result */
101918730Ssteve    char	*cp;
1020138346Sharti    size_t blen;
1021138346Sharti    ssize_t rcnt;
102218730Ssteve
1023104121Sjmallett    *error = NULL;
102418730Ssteve
1025136840Sru    if (shellPath == NULL)
1026136840Sru	Shell_Init();
102718730Ssteve    /*
102818730Ssteve     * Set up arguments for shell
102918730Ssteve     */
1030136840Sru    args[0] = shellName;
103118730Ssteve    args[1] = "-c";
103218730Ssteve    args[2] = cmd;
103318730Ssteve    args[3] = NULL;
103418730Ssteve
103518730Ssteve    /*
103618730Ssteve     * Open a pipe for fetching its output
103718730Ssteve     */
103818730Ssteve    if (pipe(fds) == -1) {
1039104121Sjmallett	*error = "Couldn't create pipe for \"%s\"";
104018730Ssteve	goto bad;
104118730Ssteve    }
104218730Ssteve
104318730Ssteve    /*
104418730Ssteve     * Fork
104518730Ssteve     */
104618730Ssteve    switch (cpid = vfork()) {
104718730Ssteve    case 0:
104818730Ssteve	/*
104918730Ssteve	 * Close input side of pipe
105018730Ssteve	 */
1051138232Sharti	close(fds[0]);
105218730Ssteve
105318730Ssteve	/*
105418730Ssteve	 * Duplicate the output stream to the shell's output, then
105518730Ssteve	 * shut the extra thing down. Note we don't fetch the error
105618730Ssteve	 * stream...why not? Why?
105718730Ssteve	 */
1058138232Sharti	dup2(fds[1], 1);
1059138232Sharti	close(fds[1]);
106018730Ssteve
1061138232Sharti	execv(shellPath, args);
106218730Ssteve	_exit(1);
106318730Ssteve	/*NOTREACHED*/
106418730Ssteve
106518730Ssteve    case -1:
1066104121Sjmallett	*error = "Couldn't exec \"%s\"";
106718730Ssteve	goto bad;
106818730Ssteve
106918730Ssteve    default:
107018730Ssteve	/*
107118730Ssteve	 * No need for the writing half
107218730Ssteve	 */
1073138232Sharti	close(fds[1]);
107418730Ssteve
1075138232Sharti	buf = Buf_Init(MAKE_BSIZE);
107618730Ssteve
107718730Ssteve	do {
107818730Ssteve	    char   result[BUFSIZ];
1079138346Sharti	    rcnt = read(fds[0], result, sizeof(result));
1080138346Sharti	    if (rcnt != -1)
1081138346Sharti		Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result);
1082138346Sharti	} while (rcnt > 0 || (rcnt == -1 && errno == EINTR));
108318730Ssteve	/*
108418730Ssteve	 * Close the input side of the pipe.
108518730Ssteve	 */
1086138232Sharti	close(fds[0]);
108718730Ssteve
108818730Ssteve	/*
108918730Ssteve	 * Wait for the process to exit.
109018730Ssteve	 */
1091138232Sharti	while (((pid = wait(&status)) != cpid) && (pid >= 0))
109218730Ssteve	    continue;
109318730Ssteve
1094138346Sharti	if (rcnt == -1)
1095104121Sjmallett	    *error = "Error reading shell's output for \"%s\"";
109618864Ssteve
1097138346Sharti	res = (char *)Buf_GetAll(buf, &blen);
1098138232Sharti	Buf_Destroy(buf, FALSE);
109918730Ssteve
110018730Ssteve	if (status)
1101104121Sjmallett	    *error = "\"%s\" returned non-zero status";
110218730Ssteve
110318730Ssteve	/*
110418730Ssteve	 * Null-terminate the result, convert newlines to spaces and
110518730Ssteve	 * install it in the variable.
110618730Ssteve	 */
1107138346Sharti	res[blen] = '\0';
1108138346Sharti	cp = &res[blen] - 1;
110918730Ssteve
111018730Ssteve	if (*cp == '\n') {
111118730Ssteve	    /*
111218730Ssteve	     * A final newline is just stripped
111318730Ssteve	     */
111418730Ssteve	    *cp-- = '\0';
111518730Ssteve	}
111618730Ssteve	while (cp >= res) {
111718730Ssteve	    if (*cp == '\n') {
111818730Ssteve		*cp = ' ';
111918730Ssteve	    }
112018730Ssteve	    cp--;
112118730Ssteve	}
112218730Ssteve	break;
112318730Ssteve    }
1124138232Sharti    return (res);
112518730Sstevebad:
112618730Ssteve    res = emalloc(1);
112718730Ssteve    *res = '\0';
1128138232Sharti    return (res);
112918730Ssteve}
113018730Ssteve
11311590Srgrimes/*
11321590Srgrimes * usage --
11331590Srgrimes *	exit with usage message
11341590Srgrimes */
11351590Srgrimesstatic void
1136104696Sjmallettusage(void)
11371590Srgrimes{
1138138232Sharti	fprintf(stderr, "%s\n%s\n%s\n",
1139113512Sru"usage: make [-BPSXeiknqrstv] [-C directory] [-D variable] [-d flags]",
1140113512Sru"            [-E variable] [-f makefile] [-I directory] [-j max_jobs]",
1141113512Sru"            [-m directory] [-V variable] [variable=value] [target ...]");
11421590Srgrimes	exit(2);
11431590Srgrimes}
1144