main.c revision 141974
1141104Sharti/*-
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 141974 2005-02-16 17:20:09Z 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
63141104Sharti#ifndef MACHINE
64141104Sharti#include <sys/utsname.h>
65141104Sharti#endif
661590Srgrimes#include <sys/param.h>
671590Srgrimes#include <sys/stat.h>
6839006Skato#include <sys/sysctl.h>
69127880Sdes#include <sys/time.h>
70127899Sru#include <sys/resource.h>
7118730Ssteve#include <sys/wait.h>
7227644Scharnier#include <err.h>
731590Srgrimes#include <errno.h>
74127880Sdes#include <signal.h>
75127880Sdes#include <stdlib.h>
76141104Sharti#include <string.h>
7763955Simp#include <unistd.h>
78127880Sdes
79141104Sharti#include "arch.h"
80141133Sharti#include "buf.h"
81141104Sharti#include "compat.h"
82141104Sharti#include "config.h"
831590Srgrimes#include "dir.h"
84141104Sharti#include "globals.h"
851590Srgrimes#include "job.h"
86141104Sharti#include "make.h"
87141104Sharti#include "nonints.h"
88141104Sharti#include "parse.h"
891590Srgrimes#include "pathnames.h"
90141104Sharti#include "str.h"
91141104Sharti#include "suff.h"
92141104Sharti#include "targ.h"
93141104Sharti#include "util.h"
94141104Sharti#include "var.h"
951590Srgrimes
96104395Sjmallett#define WANT_ENV_MKLVL	1
97138071Sjmallett#define	MKLVL_MAXVAL	500
98138071Sjmallett#define	MKLVL_ENVVAR	"__MKLVL__"
99104395Sjmallett
1001590Srgrimes#define	MAKEFLAGS	".MAKEFLAGS"
1011590Srgrimes
102138916Sharti/* Targets to be made */
103138916ShartiLst create = Lst_Initializer(create);
104138916Sharti
1051590Srgrimestime_t			now;		/* Time at start of make */
106141104Shartistruct GNode		*DEFAULT;	/* .DEFAULT node */
1071590SrgrimesBoolean			allPrecious;	/* .PRECIOUS given on line by itself */
1081590Srgrimes
1091590Srgrimesstatic Boolean		noBuiltins;	/* -r flag */
110138916Sharti
111138916Sharti/* ordered list of makefiles to read */
112138916Shartistatic Lst makefiles = Lst_Initializer(makefiles);
113138916Sharti
11466365Speterstatic Boolean		expandVars;	/* fully expand printed variables */
115138916Sharti
116138916Sharti/* list of variables to print */
117138916Shartistatic Lst variables = Lst_Initializer(variables);
118138916Sharti
11918730Ssteveint			maxJobs;	/* -j argument */
12028228Sfsmpstatic Boolean          forceJobs;      /* -j argument given */
1211590SrgrimesBoolean			compatMake;	/* -B argument */
1221590SrgrimesBoolean			debug;		/* -d flag */
1231590SrgrimesBoolean			noExecute;	/* -n flag */
1241590SrgrimesBoolean			keepgoing;	/* -k flag */
1251590SrgrimesBoolean			queryFlag;	/* -q flag */
1261590SrgrimesBoolean			touchFlag;	/* -t flag */
1271590SrgrimesBoolean			usePipes;	/* !-P flag */
1281590SrgrimesBoolean			ignoreErrors;	/* -i flag */
1291590SrgrimesBoolean			beSilent;	/* -s flag */
13041151SdgBoolean			beVerbose;	/* -v flag */
1311590SrgrimesBoolean			oldVars;	/* variable substitution style */
1321590SrgrimesBoolean			checkEnvFirst;	/* -e flag */
133138916Sharti
134138916Sharti/* (-E) vars to override from env */
135138916ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
136138916Sharti
137104818SjmallettBoolean			jobsRunning;	/* TRUE if the jobs might be running */
1381590Srgrimes
13992921Simpstatic void		MainParseArgs(int, char **);
140141252Shartichar			*chdir_verify_path(const char *, char *);
141138561Shartistatic int		ReadMakefile(const void *, const void *);
14292921Simpstatic void		usage(void);
1431590Srgrimes
1441590Srgrimesstatic char *curdir;			/* startup directory */
1451590Srgrimesstatic char *objdir;			/* where we chdir'ed to */
1461590Srgrimes
147133085Sharti/*
148133085Sharti * Append a flag with an optional argument to MAKEFLAGS and MFLAGS
149133085Sharti */
150133085Shartistatic void
151141252ShartiMFLAGS_append(const char *flag, char *arg)
152133085Sharti{
153140870Sharti	char *str;
154138232Sharti
155133085Sharti	Var_Append(MAKEFLAGS, flag, VAR_GLOBAL);
156140870Sharti	if (arg != NULL) {
157140870Sharti		str = MAKEFLAGS_quote(arg);
158140870Sharti		Var_Append(MAKEFLAGS, str, VAR_GLOBAL);
159140870Sharti		free(str);
160140870Sharti	}
161133085Sharti
162133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
163140870Sharti	if (arg != NULL) {
164140870Sharti		str = MAKEFLAGS_quote(arg);
165140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
166140870Sharti		free(str);
167140870Sharti	}
168133085Sharti}
169133085Sharti
1701590Srgrimes/*-
1711590Srgrimes * MainParseArgs --
1721590Srgrimes *	Parse a given argument vector. Called from main() and from
1731590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
1741590Srgrimes *
1751590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
1761590Srgrimes *
1771590Srgrimes * Results:
1781590Srgrimes *	None
1791590Srgrimes *
1801590Srgrimes * Side Effects:
1811590Srgrimes *	Various global and local flags will be set depending on the flags
1821590Srgrimes *	given
1831590Srgrimes */
1841590Srgrimesstatic void
185104696SjmallettMainParseArgs(int argc, char **argv)
1861590Srgrimes{
1875814Sjkh	int c;
1881590Srgrimes
1891590Srgrimes	optind = 1;	/* since we're called more than once */
190137202Sharti#define OPTFLAGS "BC:D:E:I:PSV:Xd:ef:ij:km:nqrstv"
19124360Simprearg:	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
1921590Srgrimes		switch(c) {
193102393Sjmallett		case 'C':
194107964Sseanc			if (chdir(optarg) == -1)
195107964Sseanc				err(1, "chdir %s", optarg);
196102393Sjmallett			break;
1971590Srgrimes		case 'D':
1981590Srgrimes			Var_Set(optarg, "1", VAR_GLOBAL);
199133085Sharti			MFLAGS_append("-D", optarg);
2001590Srgrimes			break;
2011590Srgrimes		case 'I':
2021590Srgrimes			Parse_AddIncludeDir(optarg);
203133085Sharti			MFLAGS_append("-I", optarg);
2041590Srgrimes			break;
20517193Sbde		case 'V':
206138920Sru			Lst_AtEnd(&variables, estrdup(optarg));
207133085Sharti			MFLAGS_append("-V", optarg);
20817193Sbde			break;
20966365Speter		case 'X':
21066365Speter			expandVars = FALSE;
21166365Speter			break;
2121590Srgrimes		case 'B':
2131590Srgrimes			compatMake = TRUE;
214133085Sharti			MFLAGS_append("-B", NULL);
215137626Sphk			unsetenv("MAKE_JOBS_FIFO");
2161590Srgrimes			break;
2171590Srgrimes		case 'P':
2181590Srgrimes			usePipes = FALSE;
219133085Sharti			MFLAGS_append("-P", NULL);
2201590Srgrimes			break;
2211590Srgrimes		case 'S':
2221590Srgrimes			keepgoing = FALSE;
223133085Sharti			MFLAGS_append("-S", NULL);
2241590Srgrimes			break;
2251590Srgrimes		case 'd': {
2261590Srgrimes			char *modules = optarg;
2271590Srgrimes
2281590Srgrimes			for (; *modules; ++modules)
2291590Srgrimes				switch (*modules) {
2301590Srgrimes				case 'A':
2311590Srgrimes					debug = ~0;
2321590Srgrimes					break;
2331590Srgrimes				case 'a':
2341590Srgrimes					debug |= DEBUG_ARCH;
2351590Srgrimes					break;
2361590Srgrimes				case 'c':
2371590Srgrimes					debug |= DEBUG_COND;
2381590Srgrimes					break;
2391590Srgrimes				case 'd':
2401590Srgrimes					debug |= DEBUG_DIR;
2411590Srgrimes					break;
2421590Srgrimes				case 'f':
2431590Srgrimes					debug |= DEBUG_FOR;
2441590Srgrimes					break;
2451590Srgrimes				case 'g':
2461590Srgrimes					if (modules[1] == '1') {
2471590Srgrimes						debug |= DEBUG_GRAPH1;
2481590Srgrimes						++modules;
2491590Srgrimes					}
2501590Srgrimes					else if (modules[1] == '2') {
2511590Srgrimes						debug |= DEBUG_GRAPH2;
2521590Srgrimes						++modules;
2531590Srgrimes					}
2541590Srgrimes					break;
2551590Srgrimes				case 'j':
2561590Srgrimes					debug |= DEBUG_JOB;
2571590Srgrimes					break;
25860569Swill				case 'l':
25960569Swill					debug |= DEBUG_LOUD;
26060569Swill					break;
2611590Srgrimes				case 'm':
2621590Srgrimes					debug |= DEBUG_MAKE;
2631590Srgrimes					break;
2641590Srgrimes				case 's':
2651590Srgrimes					debug |= DEBUG_SUFF;
2661590Srgrimes					break;
2671590Srgrimes				case 't':
2681590Srgrimes					debug |= DEBUG_TARG;
2691590Srgrimes					break;
2701590Srgrimes				case 'v':
2711590Srgrimes					debug |= DEBUG_VAR;
2721590Srgrimes					break;
2731590Srgrimes				default:
27427644Scharnier					warnx("illegal argument to d option -- %c", *modules);
2751590Srgrimes					usage();
2761590Srgrimes				}
277133085Sharti			MFLAGS_append("-d", optarg);
2781590Srgrimes			break;
2791590Srgrimes		}
28049332Shoek		case 'E':
281138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
282133085Sharti			MFLAGS_append("-E", optarg);
28349332Shoek			break;
2841590Srgrimes		case 'e':
2851590Srgrimes			checkEnvFirst = TRUE;
286133085Sharti			MFLAGS_append("-e", NULL);
2871590Srgrimes			break;
2881590Srgrimes		case 'f':
289138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
2901590Srgrimes			break;
2911590Srgrimes		case 'i':
2921590Srgrimes			ignoreErrors = TRUE;
293133085Sharti			MFLAGS_append("-i", NULL);
2941590Srgrimes			break;
29549331Shoek		case 'j': {
29649331Shoek			char *endptr;
29749331Shoek
29818730Ssteve			forceJobs = TRUE;
29949331Shoek			maxJobs = strtol(optarg, &endptr, 10);
30049331Shoek			if (maxJobs <= 0 || *endptr != '\0') {
30149938Shoek				warnx("illegal number, -j argument -- %s",
30249938Shoek				    optarg);
30349938Shoek				usage();
30449331Shoek			}
305133085Sharti			MFLAGS_append("-j", optarg);
3061590Srgrimes			break;
30749331Shoek		}
3081590Srgrimes		case 'k':
3091590Srgrimes			keepgoing = TRUE;
310133085Sharti			MFLAGS_append("-k", NULL);
3111590Srgrimes			break;
31218730Ssteve		case 'm':
313138916Sharti			Dir_AddDir(&sysIncPath, optarg);
314133085Sharti			MFLAGS_append("-m", optarg);
31518730Ssteve			break;
3161590Srgrimes		case 'n':
3171590Srgrimes			noExecute = TRUE;
318133085Sharti			MFLAGS_append("-n", NULL);
3191590Srgrimes			break;
3201590Srgrimes		case 'q':
3211590Srgrimes			queryFlag = TRUE;
3221590Srgrimes			/* Kind of nonsensical, wot? */
323133085Sharti			MFLAGS_append("-q", NULL);
3241590Srgrimes			break;
3251590Srgrimes		case 'r':
3261590Srgrimes			noBuiltins = TRUE;
327133085Sharti			MFLAGS_append("-r", NULL);
3281590Srgrimes			break;
3291590Srgrimes		case 's':
3301590Srgrimes			beSilent = TRUE;
331133085Sharti			MFLAGS_append("-s", NULL);
3321590Srgrimes			break;
3331590Srgrimes		case 't':
3341590Srgrimes			touchFlag = TRUE;
335133085Sharti			MFLAGS_append("-t", NULL);
3361590Srgrimes			break;
33741151Sdg		case 'v':
33841151Sdg			beVerbose = TRUE;
339133085Sharti			MFLAGS_append("-v", NULL);
34041151Sdg			break;
3411590Srgrimes		default:
3421590Srgrimes		case '?':
3431590Srgrimes			usage();
3441590Srgrimes		}
3451590Srgrimes	}
3461590Srgrimes
3471590Srgrimes	oldVars = TRUE;
3481590Srgrimes
3491590Srgrimes	/*
3501590Srgrimes	 * See if the rest of the arguments are variable assignments and
3511590Srgrimes	 * perform them if so. Else take them to be targets and stuff them
3521590Srgrimes	 * on the end of the "create" list.
3531590Srgrimes	 */
3541590Srgrimes	for (argv += optind, argc -= optind; *argv; ++argv, --argc)
355133562Sharti		if (Parse_IsVar(*argv)) {
356140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
357133562Sharti
358133562Sharti			Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
359133562Sharti			free(ptr);
360133562Sharti
3611590Srgrimes			Parse_DoVar(*argv, VAR_CMD);
362133562Sharti		} else {
3631590Srgrimes			if (!**argv)
3641590Srgrimes				Punt("illegal (null) argument.");
3651590Srgrimes			if (**argv == '-') {
3661590Srgrimes				if ((*argv)[1])
3671590Srgrimes					optind = 0;     /* -flag... */
3681590Srgrimes				else
3691590Srgrimes					optind = 1;     /* - */
3701590Srgrimes				goto rearg;
3711590Srgrimes			}
372138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
3731590Srgrimes		}
3741590Srgrimes}
3751590Srgrimes
3761590Srgrimes/*-
3771590Srgrimes * Main_ParseArgLine --
3781590Srgrimes *  	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
3791590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
3801590Srgrimes *	Takes a line of arguments and breaks it into its
3811590Srgrimes * 	component words and passes those words and the number of them to the
3821590Srgrimes *	MainParseArgs function.
3831590Srgrimes *	The line should have all its leading whitespace removed.
3841590Srgrimes *
3851590Srgrimes * Results:
3861590Srgrimes *	None
3871590Srgrimes *
3881590Srgrimes * Side Effects:
3891590Srgrimes *	Only those that come from the various arguments.
3901590Srgrimes */
3911590Srgrimesvoid
392140870ShartiMain_ParseArgLine(char *line, int mflags)
3931590Srgrimes{
3941590Srgrimes	char **argv;			/* Manufactured argument vector */
3951590Srgrimes	int argc;			/* Number of arguments in argv */
3961590Srgrimes
3971590Srgrimes	if (line == NULL)
3981590Srgrimes		return;
3991590Srgrimes	for (; *line == ' '; ++line)
4001590Srgrimes		continue;
4011590Srgrimes	if (!*line)
4021590Srgrimes		return;
4031590Srgrimes
404140870Sharti	if (mflags)
405140870Sharti		argv = MAKEFLAGS_break(line, &argc);
406140870Sharti	else
407140870Sharti		argv = brk_string(line, &argc, TRUE);
408140870Sharti
4091590Srgrimes	MainParseArgs(argc, argv);
4101590Srgrimes}
4111590Srgrimes
41218339Sswallacechar *
413141252Shartichdir_verify_path(const char *path, char *obpath)
41418339Sswallace{
41518339Sswallace	struct stat sb;
41618339Sswallace
41718339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
41875973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
41927644Scharnier			warn("warning: %s", path);
420141252Sharti			return (NULL);
42118339Sswallace		}
422138232Sharti		return (obpath);
42318339Sswallace	}
42418339Sswallace
425141252Sharti	return (NULL);
42618339Sswallace}
42718339Sswallace
428133082Shartistatic void
429133082Sharticatch_child(int sig __unused)
430123513Sdes{
431123513Sdes}
43218339Sswallace
433138071Sjmallett/*
434138071Sjmallett * In lieu of a good way to prevent every possible looping in
435138071Sjmallett * make(1), stop there from being more than MKLVL_MAXVAL processes forked
436138071Sjmallett * by make(1), to prevent a forkbomb from happening, in a dumb and
437138071Sjmallett * mechanical way.
438138071Sjmallett */
439138071Sjmallettstatic void
440138071Sjmallettcheck_make_level(void)
441138071Sjmallett{
442138071Sjmallett#ifdef WANT_ENV_MKLVL
443138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
444138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
445138071Sjmallett
446138071Sjmallett	if (level < 0) {
447138071Sjmallett		errc(2, EAGAIN, "Invalid value for recursion level (%d).", level);
448138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
449138071Sjmallett		errc(2, EAGAIN, "Max recursion level (%d) exceeded.", MKLVL_MAXVAL);
450138071Sjmallett	} else {
451138071Sjmallett		char new_value[32];
452138071Sjmallett		sprintf(new_value, "%d", level + 1);
453138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
454138071Sjmallett	}
455138071Sjmallett#endif /* WANT_ENV_MKLVL */
456138071Sjmallett}
457138071Sjmallett
4581590Srgrimes/*-
4591590Srgrimes * main --
4601590Srgrimes *	The main function, for obvious reasons. Initializes variables
4611590Srgrimes *	and a few modules, then parses the arguments give it in the
4621590Srgrimes *	environment and on the command line. Reads the system makefile
4631590Srgrimes *	followed by either Makefile, makefile or the file given by the
4641590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
4651590Srgrimes *	flags it has received by then uses either the Make or the Compat
4661590Srgrimes *	module to create the initial list of targets.
4671590Srgrimes *
4681590Srgrimes * Results:
4691590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
4701590Srgrimes *	0.
4711590Srgrimes *
4721590Srgrimes * Side Effects:
4731590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
4741590Srgrimes */
4751590Srgrimesint
476104696Sjmallettmain(int argc, char **argv)
4771590Srgrimes{
4781590Srgrimes	Boolean outOfDate = TRUE; 	/* FALSE if all targets up to date */
479141252Sharti	char *p, *p1, *pathp;
480141252Sharti	char *path;
48173262Simp	char mdpath[MAXPATHLEN];
48273262Simp	char obpath[MAXPATHLEN];
48373262Simp	char cdpath[MAXPATHLEN];
484141252Sharti    	const char *machine = getenv("MACHINE");
485141252Sharti	const char *machine_arch = getenv("MACHINE_ARCH");
486141252Sharti	const char *machine_cpu = getenv("MACHINE_CPU");
48718730Ssteve	char *cp = NULL, *start;
488141252Sharti
48918730Ssteve					/* avoid faults on read-only strings */
49018730Ssteve	static char syspath[] = _PATH_DEFSYSPATH;
4911590Srgrimes
492123513Sdes	{
493123513Sdes	/*
494123513Sdes	 * Catch SIGCHLD so that we get kicked out of select() when we
495123513Sdes	 * need to look at a child.  This is only known to matter for the
496123513Sdes	 * -j case (perhaps without -P).
497123513Sdes	 *
498123513Sdes	 * XXX this is intentionally misplaced.
499123513Sdes	 */
500123513Sdes	struct sigaction sa;
501123513Sdes
502123513Sdes	sigemptyset(&sa.sa_mask);
503123513Sdes	sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
504123513Sdes	sa.sa_handler = catch_child;
505123513Sdes	sigaction(SIGCHLD, &sa, NULL);
506123513Sdes	}
507123513Sdes
508138071Sjmallett	check_make_level();
509104395Sjmallett
51064739Sgreen#if DEFSHELL == 2
51164739Sgreen	/*
51264739Sgreen	 * Turn off ENV to make ksh happier.
51364739Sgreen	 */
51464739Sgreen	unsetenv("ENV");
51564739Sgreen#endif
51664739Sgreen
51718730Ssteve#ifdef RLIMIT_NOFILE
5181590Srgrimes	/*
51918730Ssteve	 * get rid of resource limit on file descriptors
52018730Ssteve	 */
52118730Ssteve	{
52218730Ssteve		struct rlimit rl;
52318730Ssteve		if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
52418730Ssteve		    rl.rlim_cur != rl.rlim_max) {
52518730Ssteve			rl.rlim_cur = rl.rlim_max;
526138232Sharti			setrlimit(RLIMIT_NOFILE, &rl);
52718730Ssteve		}
52818730Ssteve	}
52918730Ssteve#endif
5301590Srgrimes
5315814Sjkh	/*
53239006Skato	 * PC-98 kernel sets the `i386' string to the utsname.machine and
53339006Skato	 * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
53439006Skato	 * we check machine.ispc98 and adjust the machine variable before
53539006Skato	 * using usname(3) below.
53653631Smarcel	 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
53753631Smarcel	 * __FreeBSD_version was defined as 300003. So, this check can
53853631Smarcel	 * safely be done with any kernel with version > 300003.
53939006Skato	 */
54039006Skato	if (!machine) {
54139006Skato		int	ispc98;
54239006Skato		size_t	len;
54339006Skato
54439006Skato		len = sizeof(ispc98);
54539006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
54639006Skato			if (ispc98)
54739006Skato				machine = "pc98";
54839006Skato		}
54939006Skato	}
55039006Skato
55139006Skato	/*
5525814Sjkh	 * Get the name of this type of MACHINE from utsname
5535814Sjkh	 * so we can share an executable for similar machines.
5545814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
5555814Sjkh	 *
5565814Sjkh	 * Note that while MACHINE is decided at run-time,
5575814Sjkh	 * MACHINE_ARCH is always known at compile time.
5585814Sjkh	 */
55918864Ssteve	if (!machine) {
56018339Sswallace#ifndef MACHINE
56118730Ssteve	    struct utsname utsname;
56218730Ssteve
56394506Scharnier	    if (uname(&utsname) == -1)
56494506Scharnier		    err(2, "uname");
5655814Sjkh	    machine = utsname.machine;
56618339Sswallace#else
56718339Sswallace	    machine = MACHINE;
56818339Sswallace#endif
5695814Sjkh	}
5701590Srgrimes
57144362Simp	if (!machine_arch) {
57244362Simp#ifndef MACHINE_ARCH
57344362Simp		machine_arch = "unknown";
57444362Simp#else
57544362Simp		machine_arch = MACHINE_ARCH;
57644362Simp#endif
57744362Simp	}
57844362Simp
5791590Srgrimes	/*
58072679Skris	 * Set machine_cpu to the minumum supported CPU revision based
58172679Skris	 * on the target architecture, if not already set.
58272679Skris	 */
58372679Skris	if (!machine_cpu) {
58472679Skris		if (!strcmp(machine_arch, "i386"))
58572679Skris			machine_cpu = "i386";
58672679Skris		else if (!strcmp(machine_arch, "alpha"))
58772679Skris			machine_cpu = "ev4";
58872679Skris		else
58972679Skris			machine_cpu = "unknown";
59072679Skris	}
5911590Srgrimes
59266365Speter	expandVars = TRUE;
5931590Srgrimes	beSilent = FALSE;		/* Print commands as executed */
5941590Srgrimes	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
5951590Srgrimes	noExecute = FALSE;		/* Execute all commands */
5961590Srgrimes	keepgoing = FALSE;		/* Stop on error */
5971590Srgrimes	allPrecious = FALSE;		/* Remove targets when interrupted */
5981590Srgrimes	queryFlag = FALSE;		/* This is not just a check-run */
5991590Srgrimes	noBuiltins = FALSE;		/* Read the built-in rules */
6001590Srgrimes	touchFlag = FALSE;		/* Actually update targets */
6011590Srgrimes	usePipes = TRUE;		/* Catch child output in pipes */
6021590Srgrimes	debug = 0;			/* No debug verbosity, please. */
6031590Srgrimes	jobsRunning = FALSE;
6041590Srgrimes
605137571Sphk	maxJobs = DEFMAXJOBS;
60628228Sfsmp	forceJobs = FALSE;              /* No -j flag */
60718730Ssteve	compatMake = FALSE;		/* No compat mode */
6081590Srgrimes
6091590Srgrimes	/*
6101590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
6111590Srgrimes	 * for the reading of inclusion paths and variable settings on the
6121590Srgrimes	 * command line
6131590Srgrimes	 */
6141590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
6151590Srgrimes				 * can be processed correctly */
6161590Srgrimes	Parse_Init();		/* Need to initialize the paths of #include
6171590Srgrimes				 * directories */
6181590Srgrimes	Var_Init();		/* As well as the lists of variables for
6191590Srgrimes				 * parsing arguments */
6205814Sjkh        str_init();
6211590Srgrimes
6221590Srgrimes	/*
6231590Srgrimes	 * Initialize various variables.
6241590Srgrimes	 *	MAKE also gets this name, for compatibility
6251590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
6261590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
6271590Srgrimes	 */
6281590Srgrimes	Var_Set("MAKE", argv[0], VAR_GLOBAL);
6291590Srgrimes	Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
6301590Srgrimes	Var_Set("MFLAGS", "", VAR_GLOBAL);
6315814Sjkh	Var_Set("MACHINE", machine, VAR_GLOBAL);
63244362Simp	Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
63372679Skris	Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
63497121Sru#ifdef MAKE_VERSION
63597121Sru	Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
63697121Sru#endif
6371590Srgrimes
6381590Srgrimes	/*
6391590Srgrimes	 * First snag any flags out of the MAKE environment variable.
6401590Srgrimes	 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
6411590Srgrimes	 * in a different format).
6421590Srgrimes	 */
643140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
6448874Srgrimes
6451590Srgrimes	MainParseArgs(argc, argv);
6461590Srgrimes
6471590Srgrimes	/*
648120053Sru	 * Find where we are...
649120053Sru	 * All this code is so that we know where we are when we start up
650120053Sru	 * on a different machine with pmake.
651120053Sru	 */
652120053Sru	curdir = cdpath;
653120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
654120053Sru		err(2, NULL);
655120053Sru
656141252Sharti	{
657141252Sharti	struct stat sa;
658141252Sharti
659120053Sru	if (stat(curdir, &sa) == -1)
660120053Sru	    err(2, "%s", curdir);
661141252Sharti	}
662120053Sru
663120053Sru	/*
664120053Sru	 * The object directory location is determined using the
665120053Sru	 * following order of preference:
666120053Sru	 *
667120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
668120053Sru	 *	2. MAKEOBJDIR
669120053Sru	 *	3. _PATH_OBJDIR.${MACHINE}
670120053Sru	 *	4. _PATH_OBJDIR
671120053Sru	 *	5. _PATH_OBJDIRPREFIX`cwd`
672120053Sru	 *
673120053Sru	 * If one of the first two fails, use the current directory.
674120053Sru	 * If the remaining three all fail, use the current directory.
675120053Sru	 *
676120053Sru	 * Once things are initted,
677120053Sru	 * have to add the original directory to the search path,
678120053Sru	 * and modify the paths for the Makefiles apropriately.  The
679120053Sru	 * current directory is also placed as a variable for make scripts.
680120053Sru	 */
681120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
682120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
683120053Sru			path = _PATH_OBJDIR;
684120053Sru			pathp = _PATH_OBJDIRPREFIX;
685138232Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s",
686120053Sru					path, machine);
687120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
688120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
689138232Sharti					snprintf(mdpath, MAXPATHLEN,
690120053Sru							"%s%s", pathp, curdir);
691120053Sru					if (!(objdir=chdir_verify_path(mdpath,
692120053Sru								       obpath)))
693120053Sru						objdir = curdir;
694120053Sru				}
695120053Sru		}
696120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
697120053Sru			objdir = curdir;
698120053Sru	}
699120053Sru	else {
700138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
701120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
702120053Sru			objdir = curdir;
703120053Sru	}
704120053Sru	Dir_InitDot();		/* Initialize the "." directory */
705120053Sru	if (objdir != curdir)
706138916Sharti		Dir_AddDir(&dirSearchPath, curdir);
707120053Sru	Var_Set(".CURDIR", curdir, VAR_GLOBAL);
708120053Sru	Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
709120053Sru
710137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
711137606Sphk		forceJobs = TRUE;
712120053Sru	/*
71328228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
71428228Sfsmp	 * turned compatibility on
71528228Sfsmp	 */
71628228Sfsmp	if (!compatMake && !forceJobs)
71728228Sfsmp		compatMake = TRUE;
71828228Sfsmp
71928228Sfsmp	/*
7201590Srgrimes	 * Initialize archive, target and suffix modules in preparation for
7211590Srgrimes	 * parsing the makefile(s)
7221590Srgrimes	 */
7231590Srgrimes	Arch_Init();
7241590Srgrimes	Targ_Init();
7251590Srgrimes	Suff_Init();
7261590Srgrimes
72769527Swill	DEFAULT = NULL;
728138232Sharti	time(&now);
7291590Srgrimes
7301590Srgrimes	/*
7311590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
7321590Srgrimes	 * created. If none specified, make the variable empty -- the parser
7331590Srgrimes	 * will fill the thing in with the default or .MAIN target.
7341590Srgrimes	 */
735138916Sharti	if (!Lst_IsEmpty(&create)) {
736138512Sharti		LstNode *ln;
7371590Srgrimes
738138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
739138264Sharti			char *name = Lst_Datum(ln);
7401590Srgrimes
7411590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
7421590Srgrimes		}
7431590Srgrimes	} else
7441590Srgrimes		Var_Set(".TARGETS", "", VAR_GLOBAL);
7451590Srgrimes
74618730Ssteve
7471590Srgrimes	/*
74818730Ssteve	 * If no user-supplied system path was given (through the -m option)
74918730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
75018730Ssteve	 * as dir1:...:dirn) to the system include path.
7511590Srgrimes	 */
752138916Sharti	if (Lst_IsEmpty(&sysIncPath)) {
75318730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
75418730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
75518730Ssteve				continue;
75618730Ssteve			if (*cp == '\0') {
757138916Sharti				Dir_AddDir(&sysIncPath, start);
75818730Ssteve			} else {
75918730Ssteve				*cp++ = '\0';
760138916Sharti				Dir_AddDir(&sysIncPath, start);
76118730Ssteve			}
76218730Ssteve		}
76318730Ssteve	}
7641590Srgrimes
76518730Ssteve	/*
76618730Ssteve	 * Read in the built-in rules first, followed by the specified
76718730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
76818730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
76918730Ssteve	 */
77018730Ssteve	if (!noBuiltins) {
771138916Sharti		/* Path of sys.mk */
772138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
773138512Sharti		LstNode *ln;
77418730Ssteve
775138916Sharti		Dir_Expand(_PATH_DEFSYSMK, &sysIncPath, &sysMkPath);
776138916Sharti		if (Lst_IsEmpty(&sysMkPath))
77718730Ssteve			Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
778138916Sharti		ln = Lst_Find(&sysMkPath, NULL, ReadMakefile);
77969527Swill		if (ln != NULL)
78018730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
781138916Sharti		Lst_Destroy(&sysMkPath, free);
78218730Ssteve	}
78318730Ssteve
784138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
785138512Sharti		LstNode *ln;
7861590Srgrimes
787138916Sharti		ln = Lst_Find(&makefiles, NULL, ReadMakefile);
78869527Swill		if (ln != NULL)
7891590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
79094594Sobrien	} else if (!ReadMakefile("BSDmakefile", NULL))
79194594Sobrien	    if (!ReadMakefile("makefile", NULL))
792138232Sharti		ReadMakefile("Makefile", NULL);
7931590Srgrimes
794138232Sharti	ReadMakefile(".depend", NULL);
7951590Srgrimes
7961590Srgrimes	/* Install all the flags into the MAKE envariable. */
7975814Sjkh	if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
7981590Srgrimes		setenv("MAKEFLAGS", p, 1);
799105826Sjmallett	free(p1);
8001590Srgrimes
8011590Srgrimes	/*
8021590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
8031590Srgrimes	 * and add them to the search path, if the variable is defined. The
8041590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
8051590Srgrimes	 * <directory>:<directory>:<directory>...
8061590Srgrimes	 */
8071590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
8081590Srgrimes		/*
8091590Srgrimes		 * GCC stores string constants in read-only memory, but
8101590Srgrimes		 * Var_Subst will want to write this thing, so store it
8111590Srgrimes		 * in an array
8121590Srgrimes		 */
8131590Srgrimes		static char VPATH[] = "${VPATH}";
814141969Sharti		char *vpath;
815141969Sharti		char *start;
816141969Sharti		char *ptr;
817141969Sharti		char savec;
8181590Srgrimes
8191590Srgrimes		vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
820141969Sharti		start = vpath;
8211590Srgrimes		do {
8221590Srgrimes			/* skip to end of directory */
823141969Sharti			for (ptr = start; *ptr != ':' && *ptr != '\0'; ptr++)
824141969Sharti				;
825141969Sharti
8261590Srgrimes			/* Save terminator character so know when to stop */
827141969Sharti			savec = *ptr;
828141969Sharti			*ptr = '\0';
829141969Sharti
8301590Srgrimes			/* Add directory to search path */
831141969Sharti			Dir_AddDir(&dirSearchPath, start);
832141969Sharti
833141969Sharti			start = ptr + 1;
834141969Sharti		} while (savec != '\0');
835138232Sharti		free(vpath);
8361590Srgrimes	}
8371590Srgrimes
8381590Srgrimes	/*
8391590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
8401590Srgrimes	 * time to add the default search path to their lists...
8411590Srgrimes	 */
8421590Srgrimes	Suff_DoPaths();
8431590Srgrimes
8441590Srgrimes	/* print the initial graph, if the user requested it */
8451590Srgrimes	if (DEBUG(GRAPH1))
8461590Srgrimes		Targ_PrintGraph(1);
8471590Srgrimes
84817193Sbde	/* print the values of any variables requested by the user */
849141974Sharti	if (Lst_IsEmpty(&variables)) {
8501590Srgrimes		/*
851141974Sharti		 * Since the user has not requested that any variables
852141974Sharti		 * be printed, we can built targets.
853141974Sharti		 *
854141974Sharti		 * Have red the entire graph and need to make a list of targets
855141974Sharti		 * to create. If none was given on the command line, we consult
856141974Sharti		 * the parsing module to find the main target(s) to create.
8571590Srgrimes		 */
858138916Sharti		Lst targs = Lst_Initializer(targs);
859138916Sharti
860138916Sharti		if (Lst_IsEmpty(&create))
861138916Sharti			Parse_MainName(&targs);
862101460Sru		else
863138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
864101460Sru
865141974Sharti		if (compatMake) {
866101460Sru			/*
867141974Sharti			 * Compat_Init will take care of creating
868141974Sharti			 * all the targets as well as initializing
869141974Sharti			 * the module.
870101460Sru			 */
871141974Sharti			Compat_Run(&targs);
872141974Sharti			outOfDate = 0;
873141974Sharti		} else {
874141974Sharti			/*
875141974Sharti			 * Initialize job module before traversing
876141974Sharti			 * the graph, now that any .BEGIN and .END
877141974Sharti			 * targets have been read.  This is done
878141974Sharti			 * only if the -q flag wasn't given (to
879141974Sharti			 * prevent the .BEGIN from being executed
880141974Sharti			 * should it exist).
881141974Sharti			 */
882101460Sru			if (!queryFlag) {
883137572Sphk				Job_Init(maxJobs);
884101460Sru				jobsRunning = TRUE;
885101460Sru			}
886101460Sru
887101460Sru			/* Traverse the graph, checking on all the targets */
888138916Sharti			outOfDate = Make_Run(&targs);
8891590Srgrimes		}
890138916Sharti		Lst_Destroy(&targs, NOFREE);
891141974Sharti
892141974Sharti	} else {
893141974Sharti		/*
894141974Sharti		 * Print the values of any variables requested by
895141974Sharti		 * the user.
896141974Sharti		 */
897141974Sharti		LstNode *ln;
898141974Sharti		const char *name;
899141974Sharti		char *v;
900141974Sharti		char *value;
901141974Sharti
902141974Sharti		for (ln = Lst_First(&variables); ln != NULL;
903141974Sharti		    ln = Lst_Succ(ln)) {
904141974Sharti			name = Lst_Datum(ln);
905141974Sharti			if (expandVars) {
906141974Sharti				v = emalloc(strlen(name) + 1 + 3);
907141974Sharti				sprintf(v, "${%s}", name);
908141974Sharti
909141974Sharti				value = Var_Subst(NULL, v, VAR_GLOBAL, FALSE);
910141974Sharti			} else {
911141974Sharti				value = Var_Value(name, VAR_GLOBAL, &v);
912141974Sharti			}
913141974Sharti			printf("%s\n", value != NULL ? value : "");
914141974Sharti			if (v != NULL)
915141974Sharti				free(v);
916141974Sharti		}
91717193Sbde	}
9188874Srgrimes
919138920Sru	Lst_Destroy(&variables, free);
920138920Sru	Lst_Destroy(&makefiles, free);
921138916Sharti	Lst_Destroy(&create, free);
9225814Sjkh
9231590Srgrimes	/* print the graph now it's been processed if the user requested it */
9241590Srgrimes	if (DEBUG(GRAPH2))
9251590Srgrimes		Targ_PrintGraph(2);
9261590Srgrimes
9271590Srgrimes	if (queryFlag && outOfDate)
928138232Sharti		return (1);
9291590Srgrimes	else
930138232Sharti		return (0);
9311590Srgrimes}
9321590Srgrimes
9331590Srgrimes/*-
9341590Srgrimes * ReadMakefile  --
9351590Srgrimes *	Open and parse the given makefile.
9361590Srgrimes *
9371590Srgrimes * Results:
9381590Srgrimes *	TRUE if ok. FALSE if couldn't open file.
9391590Srgrimes *
9401590Srgrimes * Side Effects:
9411590Srgrimes *	lots
9421590Srgrimes */
9431590Srgrimesstatic Boolean
944138561ShartiReadMakefile(const void *p, const void *q __unused)
9451590Srgrimes{
946104696Sjmallett	char *fname;			/* makefile to read */
9471590Srgrimes	FILE *stream;
94873262Simp	char *name, path[MAXPATHLEN];
94997163Sjmallett	char *MAKEFILE;
95094990Sru	int setMAKEFILE;
9511590Srgrimes
952138561Sharti	/* XXX - remove this once constification is done */
953138561Sharti	fname = estrdup(p);
954104696Sjmallett
9551590Srgrimes	if (!strcmp(fname, "-")) {
9561590Srgrimes		Parse_File("(stdin)", stdin);
9571590Srgrimes		Var_Set("MAKEFILE", "", VAR_GLOBAL);
9581590Srgrimes	} else {
95994990Sru		setMAKEFILE = strcmp(fname, ".depend");
96094990Sru
9611590Srgrimes		/* if we've chdir'd, rebuild the path name */
9621590Srgrimes		if (curdir != objdir && *fname != '/') {
963138232Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
964100733Simp			/*
965100733Simp			 * XXX The realpath stuff breaks relative includes
966100733Simp			 * XXX in some cases.   The problem likely is in
967100733Simp			 * XXX parse.c where it does special things in
968100733Simp			 * XXX ParseDoInclude if the file is relateive
969100733Simp			 * XXX or absolute and not a system file.  There
970100733Simp			 * XXX it assumes that if the current file that's
971100733Simp			 * XXX being included is absolute, that any files
972100733Simp			 * XXX that it includes shouldn't do the -I path
973100733Simp			 * XXX stuff, which is inconsistant with historical
974100733Simp			 * XXX behavior.  However, I can't pentrate the mists
975100733Simp			 * XXX further, so I'm putting this workaround in
976100733Simp			 * XXX here until such time as the underlying bug
977100733Simp			 * XXX can be fixed.
978100733Simp			 */
979100733Simp#if THIS_BREAKS_THINGS
98097077Sjmallett			if (realpath(path, path) != NULL &&
98197077Sjmallett			    (stream = fopen(path, "r")) != NULL) {
98297163Sjmallett				MAKEFILE = fname;
9831590Srgrimes				fname = path;
9841590Srgrimes				goto found;
9851590Srgrimes			}
98697077Sjmallett		} else if (realpath(fname, path) != NULL) {
98797163Sjmallett			MAKEFILE = fname;
98897077Sjmallett			fname = path;
98997077Sjmallett			if ((stream = fopen(fname, "r")) != NULL)
99097077Sjmallett				goto found;
99197077Sjmallett		}
992100733Simp#else
993100733Simp			if ((stream = fopen(path, "r")) != NULL) {
994100733Simp				MAKEFILE = fname;
995100733Simp				fname = path;
996100733Simp				goto found;
997100733Simp			}
998100733Simp		} else {
999100733Simp			MAKEFILE = fname;
1000100733Simp			if ((stream = fopen(fname, "r")) != NULL)
1001100733Simp				goto found;
1002100733Simp		}
1003100733Simp#endif
10041590Srgrimes		/* look in -I and system include directories. */
1005138916Sharti		name = Dir_FindFile(fname, &parseIncPath);
10061590Srgrimes		if (!name)
1007138916Sharti			name = Dir_FindFile(fname, &sysIncPath);
10081590Srgrimes		if (!name || !(stream = fopen(name, "r")))
1009138232Sharti			return (FALSE);
101097163Sjmallett		MAKEFILE = fname = name;
10111590Srgrimes		/*
10121590Srgrimes		 * set the MAKEFILE variable desired by System V fans -- the
10131590Srgrimes		 * placement of the setting here means it gets set to the last
10141590Srgrimes		 * makefile specified, as it is set by SysV make.
10151590Srgrimes		 */
101694990Srufound:
101794990Sru		if (setMAKEFILE)
101897163Sjmallett			Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
10191590Srgrimes		Parse_File(fname, stream);
1020138232Sharti		fclose(stream);
10211590Srgrimes	}
1022138232Sharti	return (TRUE);
10231590Srgrimes}
10241590Srgrimes
10251590Srgrimes/*-
102618730Ssteve * Cmd_Exec --
102718730Ssteve *	Execute the command in cmd, and return the output of that command
102818730Ssteve *	in a string.
102918730Ssteve *
103018730Ssteve * Results:
103118730Ssteve *	A string containing the output of the command, or the empty string
1032104121Sjmallett *	If error is not NULL, it contains the reason for the command failure
103318730Ssteve *
103418730Ssteve * Side Effects:
103518730Ssteve *	The string must be freed by the caller.
103618730Ssteve */
1037141454ShartiBuffer *
1038141252ShartiCmd_Exec(char *cmd, const char **error)
103918730Ssteve{
104018730Ssteve    int 	fds[2];	    	/* Pipe streams */
104118730Ssteve    int 	cpid;	    	/* Child PID */
104218730Ssteve    int 	pid;	    	/* PID from wait() */
104318730Ssteve    int		status;		/* command exit status */
1044141133Sharti    Buffer	*buf;		/* buffer to store the result */
1045141454Sharti    ssize_t	rcnt;
104618730Ssteve
1047104121Sjmallett    *error = NULL;
1048141454Sharti    buf = Buf_Init(0);
104918730Ssteve
1050136840Sru    if (shellPath == NULL)
1051136840Sru	Shell_Init();
105218730Ssteve    /*
105318730Ssteve     * Open a pipe for fetching its output
105418730Ssteve     */
105518730Ssteve    if (pipe(fds) == -1) {
1056104121Sjmallett	*error = "Couldn't create pipe for \"%s\"";
1057141454Sharti	return (buf);
105818730Ssteve    }
105918730Ssteve
106018730Ssteve    /*
106118730Ssteve     * Fork
106218730Ssteve     */
106318730Ssteve    switch (cpid = vfork()) {
106418730Ssteve    case 0:
106518730Ssteve	/*
106618730Ssteve	 * Close input side of pipe
106718730Ssteve	 */
1068138232Sharti	close(fds[0]);
106918730Ssteve
107018730Ssteve	/*
107118730Ssteve	 * Duplicate the output stream to the shell's output, then
107218730Ssteve	 * shut the extra thing down. Note we don't fetch the error
107318730Ssteve	 * stream...why not? Why?
107418730Ssteve	 */
1075138232Sharti	dup2(fds[1], 1);
1076138232Sharti	close(fds[1]);
107718730Ssteve
1078141454Sharti	{
1079141454Sharti	    char	*args[4];
108018730Ssteve
1081141454Sharti	    /* Set up arguments for shell */
1082141454Sharti	    args[0] = shellName;
1083141454Sharti	    args[1] = "-c";
1084141454Sharti	    args[2] = cmd;
1085141454Sharti	    args[3] = NULL;
1086141454Sharti
1087141454Sharti	    execv(shellPath, args);
1088141454Sharti	    _exit(1);
1089141454Sharti	    /*NOTREACHED*/
1090141454Sharti	}
1091141454Sharti
109218730Ssteve    case -1:
1093104121Sjmallett	*error = "Couldn't exec \"%s\"";
1094141454Sharti	return (buf);
109518730Ssteve
109618730Ssteve    default:
109718730Ssteve	/*
109818730Ssteve	 * No need for the writing half
109918730Ssteve	 */
1100138232Sharti	close(fds[1]);
110118730Ssteve
110218730Ssteve	do {
110318730Ssteve	    char   result[BUFSIZ];
1104138346Sharti	    rcnt = read(fds[0], result, sizeof(result));
1105138346Sharti	    if (rcnt != -1)
1106138346Sharti		Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result);
1107138346Sharti	} while (rcnt > 0 || (rcnt == -1 && errno == EINTR));
1108141454Sharti
1109141454Sharti	if (rcnt == -1)
1110141454Sharti	    *error = "Error reading shell's output for \"%s\"";
1111141454Sharti
111218730Ssteve	/*
111318730Ssteve	 * Close the input side of the pipe.
111418730Ssteve	 */
1115138232Sharti	close(fds[0]);
111618730Ssteve
111718730Ssteve	/*
111818730Ssteve	 * Wait for the process to exit.
111918730Ssteve	 */
1120138232Sharti	while (((pid = wait(&status)) != cpid) && (pid >= 0))
112118730Ssteve	    continue;
112218730Ssteve
112318730Ssteve	if (status)
1124104121Sjmallett	    *error = "\"%s\" returned non-zero status";
112518730Ssteve
1126141454Sharti	Buf_StripNewlines(buf);
112718730Ssteve
112818730Ssteve	break;
112918730Ssteve    }
1130141454Sharti    return (buf);
113118730Ssteve}
113218730Ssteve
11331590Srgrimes/*
11341590Srgrimes * usage --
11351590Srgrimes *	exit with usage message
11361590Srgrimes */
11371590Srgrimesstatic void
1138104696Sjmallettusage(void)
11391590Srgrimes{
1140138232Sharti	fprintf(stderr, "%s\n%s\n%s\n",
1141113512Sru"usage: make [-BPSXeiknqrstv] [-C directory] [-D variable] [-d flags]",
1142113512Sru"            [-E variable] [-f makefile] [-I directory] [-j max_jobs]",
1143113512Sru"            [-m directory] [-V variable] [variable=value] [target ...]");
11441590Srgrimes	exit(2);
11451590Srgrimes}
1146