main.c revision 145971
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 145971 2005-05-06 18:30:06Z harti $");
501590Srgrimes
51144475Sharti/*
52144475Sharti * main.c
531590Srgrimes *	The main file for this entire program. Exit routines etc
541590Srgrimes *	reside here.
551590Srgrimes *
561590Srgrimes * Utility functions defined in this file:
57144475Sharti *	Main_ParseArgLine
58144475Sharti *			Takes a line of arguments, breaks them and
59144475Sharti *			treats them as if they were given when first
60144475Sharti *			invoked. Used by the parse module to implement
61144475Sharti *			the .MFLAGS target.
621590Srgrimes */
631590Srgrimes
64141104Sharti#ifndef MACHINE
65141104Sharti#include <sys/utsname.h>
66141104Sharti#endif
671590Srgrimes#include <sys/param.h>
681590Srgrimes#include <sys/stat.h>
6939006Skato#include <sys/sysctl.h>
70127880Sdes#include <sys/time.h>
71144020Sharti#include <sys/queue.h>
72127899Sru#include <sys/resource.h>
7318730Ssteve#include <sys/wait.h>
7427644Scharnier#include <err.h>
751590Srgrimes#include <errno.h>
76127880Sdes#include <signal.h>
77127880Sdes#include <stdlib.h>
78141104Sharti#include <string.h>
7963955Simp#include <unistd.h>
80127880Sdes
81141104Sharti#include "arch.h"
82141133Sharti#include "buf.h"
83141104Sharti#include "compat.h"
84141104Sharti#include "config.h"
851590Srgrimes#include "dir.h"
86141104Sharti#include "globals.h"
871590Srgrimes#include "job.h"
88141104Sharti#include "make.h"
89141104Sharti#include "nonints.h"
90141104Sharti#include "parse.h"
911590Srgrimes#include "pathnames.h"
92141104Sharti#include "str.h"
93141104Sharti#include "suff.h"
94141104Sharti#include "targ.h"
95141104Sharti#include "util.h"
96141104Sharti#include "var.h"
971590Srgrimes
98104395Sjmallett#define WANT_ENV_MKLVL	1
99138071Sjmallett#define	MKLVL_MAXVAL	500
100138071Sjmallett#define	MKLVL_ENVVAR	"__MKLVL__"
101104395Sjmallett
1021590Srgrimes#define	MAKEFLAGS	".MAKEFLAGS"
1031590Srgrimes
104145971Shartiextern char **environ;	/* XXX what header declares this variable? */
105145971Sharti
106138916Sharti/* Targets to be made */
107138916ShartiLst create = Lst_Initializer(create);
108138916Sharti
109144475Shartitime_t		now;		/* Time at start of make */
110144475Shartistruct GNode	*DEFAULT;	/* .DEFAULT node */
111144475ShartiBoolean		allPrecious;	/* .PRECIOUS given on line by itself */
112145679Shartiuint32_t	warn_flags;	/* actual warning flags */
113145679Shartiuint32_t	warn_cmd;	/* command line warning flags */
114145679Shartiuint32_t	warn_nocmd;	/* command line no-warning flags */
1151590Srgrimes
116144475Shartistatic Boolean	noBuiltins;	/* -r flag */
117138916Sharti
118138916Sharti/* ordered list of makefiles to read */
119138916Shartistatic Lst makefiles = Lst_Initializer(makefiles);
120138916Sharti
121144475Shartistatic Boolean	expandVars;	/* fully expand printed variables */
122138916Sharti
123138916Sharti/* list of variables to print */
124138916Shartistatic Lst variables = Lst_Initializer(variables);
125138916Sharti
126144475Shartiint		maxJobs;	/* -j argument */
127144475Shartistatic Boolean	forceJobs;      /* -j argument given */
128144475ShartiBoolean		compatMake;	/* -B argument */
129144475ShartiBoolean		debug;		/* -d flag */
130144475ShartiBoolean		noExecute;	/* -n flag */
131144475ShartiBoolean		keepgoing;	/* -k flag */
132144475ShartiBoolean		queryFlag;	/* -q flag */
133144475ShartiBoolean		touchFlag;	/* -t flag */
134144475ShartiBoolean		usePipes;	/* !-P flag */
135144475ShartiBoolean		ignoreErrors;	/* -i flag */
136144475ShartiBoolean		beSilent;	/* -s flag */
137144475ShartiBoolean		beVerbose;	/* -v flag */
138144475ShartiBoolean		oldVars;	/* variable substitution style */
139144475ShartiBoolean		checkEnvFirst;	/* -e flag */
140138916Sharti
141138916Sharti/* (-E) vars to override from env */
142138916ShartiLst envFirstVars = Lst_Initializer(envFirstVars);
143138916Sharti
144144475ShartiBoolean		jobsRunning;	/* TRUE if the jobs might be running */
1451590Srgrimes
146144475Shartichar		*chdir_verify_path(const char *, char *);
147144475Shartistatic int	ReadMakefile(const char *);
148144475Shartistatic void	usage(void);
1491590Srgrimes
150144475Shartistatic char	*curdir;	/* startup directory */
151144475Shartistatic char	*objdir;	/* where we chdir'ed to */
1521590Srgrimes
153144475Sharti/**
154144475Sharti * MFLAGS_append
155144475Sharti *	Append a flag with an optional argument to MAKEFLAGS and MFLAGS
156133085Sharti */
157133085Shartistatic void
158141252ShartiMFLAGS_append(const char *flag, char *arg)
159133085Sharti{
160140870Sharti	char *str;
161138232Sharti
162133085Sharti	Var_Append(MAKEFLAGS, flag, VAR_GLOBAL);
163140870Sharti	if (arg != NULL) {
164140870Sharti		str = MAKEFLAGS_quote(arg);
165140870Sharti		Var_Append(MAKEFLAGS, str, VAR_GLOBAL);
166140870Sharti		free(str);
167140870Sharti	}
168133085Sharti
169133085Sharti	Var_Append("MFLAGS", flag, VAR_GLOBAL);
170140870Sharti	if (arg != NULL) {
171140870Sharti		str = MAKEFLAGS_quote(arg);
172140870Sharti		Var_Append("MFLAGS", str, VAR_GLOBAL);
173140870Sharti		free(str);
174140870Sharti	}
175133085Sharti}
176133085Sharti
177144475Sharti/**
178145679Sharti * Main_ParseWarn
179145679Sharti *
180145679Sharti *	Handle argument to warning option.
181145679Sharti */
182145679Shartiint
183145679ShartiMain_ParseWarn(const char *arg, int iscmd)
184145679Sharti{
185145679Sharti	int i, neg;
186145679Sharti
187145679Sharti	static const struct {
188145679Sharti		const char	*option;
189145679Sharti		uint32_t	flag;
190145679Sharti	} options[] = {
191145679Sharti		{ "dirsyntax",	WARN_DIRSYNTAX },
192145679Sharti		{ NULL,		0 }
193145679Sharti	};
194145679Sharti
195145679Sharti	neg = 0;
196145679Sharti	if (arg[0] == 'n' && arg[1] == 'o') {
197145679Sharti		neg = 1;
198145679Sharti		arg += 2;
199145679Sharti	}
200145679Sharti
201145679Sharti	for (i = 0; options[i].option != NULL; i++)
202145679Sharti		if (strcmp(arg, options[i].option) == 0)
203145679Sharti			break;
204145679Sharti
205145679Sharti	if (options[i].option == NULL)
206145679Sharti		/* unknown option */
207145679Sharti		return (-1);
208145679Sharti
209145679Sharti	if (iscmd) {
210145679Sharti		if (!neg) {
211145679Sharti			warn_cmd |= options[i].flag;
212145679Sharti			warn_nocmd &= ~options[i].flag;
213145679Sharti			warn_flags |= options[i].flag;
214145679Sharti		} else {
215145679Sharti			warn_nocmd |= options[i].flag;
216145679Sharti			warn_cmd &= ~options[i].flag;
217145679Sharti			warn_flags &= ~options[i].flag;
218145679Sharti		}
219145679Sharti	} else {
220145679Sharti		if (!neg) {
221145679Sharti			warn_flags |= (options[i].flag & ~warn_nocmd);
222145679Sharti		} else {
223145679Sharti			warn_flags &= ~(options[i].flag | warn_cmd);
224145679Sharti		}
225145679Sharti	}
226145679Sharti	return (0);
227145679Sharti}
228145679Sharti
229145679Sharti/**
230144475Sharti * MainParseArgs
2311590Srgrimes *	Parse a given argument vector. Called from main() and from
2321590Srgrimes *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
2331590Srgrimes *
2341590Srgrimes *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
2351590Srgrimes *
2361590Srgrimes * Side Effects:
2371590Srgrimes *	Various global and local flags will be set depending on the flags
2381590Srgrimes *	given
2391590Srgrimes */
2401590Srgrimesstatic void
241104696SjmallettMainParseArgs(int argc, char **argv)
2421590Srgrimes{
2435814Sjkh	int c;
2441590Srgrimes
245144896Shartirearg:
2461590Srgrimes	optind = 1;	/* since we're called more than once */
247144896Sharti	optreset = 1;
248145627Sharti#define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:"
249144896Sharti	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
2501590Srgrimes		switch(c) {
251144387Sharti
252144387Sharti		case 'A':
253144387Sharti			arch_fatal = FALSE;
254144387Sharti			MFLAGS_append("-A", NULL);
255144387Sharti			break;
256102393Sjmallett		case 'C':
257107964Sseanc			if (chdir(optarg) == -1)
258107964Sseanc				err(1, "chdir %s", optarg);
259102393Sjmallett			break;
2601590Srgrimes		case 'D':
2611590Srgrimes			Var_Set(optarg, "1", VAR_GLOBAL);
262133085Sharti			MFLAGS_append("-D", optarg);
2631590Srgrimes			break;
2641590Srgrimes		case 'I':
2651590Srgrimes			Parse_AddIncludeDir(optarg);
266133085Sharti			MFLAGS_append("-I", optarg);
2671590Srgrimes			break;
26817193Sbde		case 'V':
269138920Sru			Lst_AtEnd(&variables, estrdup(optarg));
270133085Sharti			MFLAGS_append("-V", optarg);
27117193Sbde			break;
27266365Speter		case 'X':
27366365Speter			expandVars = FALSE;
27466365Speter			break;
2751590Srgrimes		case 'B':
2761590Srgrimes			compatMake = TRUE;
277133085Sharti			MFLAGS_append("-B", NULL);
278137626Sphk			unsetenv("MAKE_JOBS_FIFO");
2791590Srgrimes			break;
2801590Srgrimes		case 'P':
2811590Srgrimes			usePipes = FALSE;
282133085Sharti			MFLAGS_append("-P", NULL);
2831590Srgrimes			break;
2841590Srgrimes		case 'S':
2851590Srgrimes			keepgoing = FALSE;
286133085Sharti			MFLAGS_append("-S", NULL);
2871590Srgrimes			break;
2881590Srgrimes		case 'd': {
2891590Srgrimes			char *modules = optarg;
2901590Srgrimes
2911590Srgrimes			for (; *modules; ++modules)
2921590Srgrimes				switch (*modules) {
2931590Srgrimes				case 'A':
2941590Srgrimes					debug = ~0;
2951590Srgrimes					break;
2961590Srgrimes				case 'a':
2971590Srgrimes					debug |= DEBUG_ARCH;
2981590Srgrimes					break;
2991590Srgrimes				case 'c':
3001590Srgrimes					debug |= DEBUG_COND;
3011590Srgrimes					break;
3021590Srgrimes				case 'd':
3031590Srgrimes					debug |= DEBUG_DIR;
3041590Srgrimes					break;
3051590Srgrimes				case 'f':
3061590Srgrimes					debug |= DEBUG_FOR;
3071590Srgrimes					break;
3081590Srgrimes				case 'g':
3091590Srgrimes					if (modules[1] == '1') {
3101590Srgrimes						debug |= DEBUG_GRAPH1;
3111590Srgrimes						++modules;
3121590Srgrimes					}
3131590Srgrimes					else if (modules[1] == '2') {
3141590Srgrimes						debug |= DEBUG_GRAPH2;
3151590Srgrimes						++modules;
3161590Srgrimes					}
3171590Srgrimes					break;
3181590Srgrimes				case 'j':
3191590Srgrimes					debug |= DEBUG_JOB;
3201590Srgrimes					break;
32160569Swill				case 'l':
32260569Swill					debug |= DEBUG_LOUD;
32360569Swill					break;
3241590Srgrimes				case 'm':
3251590Srgrimes					debug |= DEBUG_MAKE;
3261590Srgrimes					break;
3271590Srgrimes				case 's':
3281590Srgrimes					debug |= DEBUG_SUFF;
3291590Srgrimes					break;
3301590Srgrimes				case 't':
3311590Srgrimes					debug |= DEBUG_TARG;
3321590Srgrimes					break;
3331590Srgrimes				case 'v':
3341590Srgrimes					debug |= DEBUG_VAR;
3351590Srgrimes					break;
3361590Srgrimes				default:
337144475Sharti					warnx("illegal argument to d option "
338144475Sharti					    "-- %c", *modules);
3391590Srgrimes					usage();
3401590Srgrimes				}
341133085Sharti			MFLAGS_append("-d", optarg);
3421590Srgrimes			break;
3431590Srgrimes		}
34449332Shoek		case 'E':
345138920Sru			Lst_AtEnd(&envFirstVars, estrdup(optarg));
346133085Sharti			MFLAGS_append("-E", optarg);
34749332Shoek			break;
3481590Srgrimes		case 'e':
3491590Srgrimes			checkEnvFirst = TRUE;
350133085Sharti			MFLAGS_append("-e", NULL);
3511590Srgrimes			break;
3521590Srgrimes		case 'f':
353138920Sru			Lst_AtEnd(&makefiles, estrdup(optarg));
3541590Srgrimes			break;
3551590Srgrimes		case 'i':
3561590Srgrimes			ignoreErrors = TRUE;
357133085Sharti			MFLAGS_append("-i", NULL);
3581590Srgrimes			break;
35949331Shoek		case 'j': {
36049331Shoek			char *endptr;
36149331Shoek
36218730Ssteve			forceJobs = TRUE;
36349331Shoek			maxJobs = strtol(optarg, &endptr, 10);
36449331Shoek			if (maxJobs <= 0 || *endptr != '\0') {
36549938Shoek				warnx("illegal number, -j argument -- %s",
36649938Shoek				    optarg);
36749938Shoek				usage();
36849331Shoek			}
369133085Sharti			MFLAGS_append("-j", optarg);
3701590Srgrimes			break;
37149331Shoek		}
3721590Srgrimes		case 'k':
3731590Srgrimes			keepgoing = TRUE;
374133085Sharti			MFLAGS_append("-k", NULL);
3751590Srgrimes			break;
37618730Ssteve		case 'm':
377144020Sharti			Path_AddDir(&sysIncPath, optarg);
378133085Sharti			MFLAGS_append("-m", optarg);
37918730Ssteve			break;
3801590Srgrimes		case 'n':
3811590Srgrimes			noExecute = TRUE;
382133085Sharti			MFLAGS_append("-n", NULL);
3831590Srgrimes			break;
3841590Srgrimes		case 'q':
3851590Srgrimes			queryFlag = TRUE;
3861590Srgrimes			/* Kind of nonsensical, wot? */
387133085Sharti			MFLAGS_append("-q", NULL);
3881590Srgrimes			break;
3891590Srgrimes		case 'r':
3901590Srgrimes			noBuiltins = TRUE;
391133085Sharti			MFLAGS_append("-r", NULL);
3921590Srgrimes			break;
3931590Srgrimes		case 's':
3941590Srgrimes			beSilent = TRUE;
395133085Sharti			MFLAGS_append("-s", NULL);
3961590Srgrimes			break;
3971590Srgrimes		case 't':
3981590Srgrimes			touchFlag = TRUE;
399133085Sharti			MFLAGS_append("-t", NULL);
4001590Srgrimes			break;
40141151Sdg		case 'v':
40241151Sdg			beVerbose = TRUE;
403133085Sharti			MFLAGS_append("-v", NULL);
40441151Sdg			break;
405145627Sharti		case 'x':
406145679Sharti			if (Main_ParseWarn(optarg, 1) != -1)
407145627Sharti				MFLAGS_append("-x", optarg);
408145627Sharti			break;
409145627Sharti
4101590Srgrimes		default:
4111590Srgrimes		case '?':
4121590Srgrimes			usage();
4131590Srgrimes		}
4141590Srgrimes	}
415144896Sharti	argv += optind;
416144896Sharti	argc -= optind;
4171590Srgrimes
4181590Srgrimes	oldVars = TRUE;
4191590Srgrimes
4201590Srgrimes	/*
421144896Sharti	 * Parse the rest of the arguments.
422144896Sharti	 *	o Check for variable assignments and perform them if so.
423144896Sharti	 *	o Check for more flags and restart getopt if so.
424144896Sharti	 *      o Anything else is taken to be a target and added
425144896Sharti	 *	  to the end of the "create" list.
4261590Srgrimes	 */
427144896Sharti	for (; *argv != NULL; ++argv, --argc) {
428133562Sharti		if (Parse_IsVar(*argv)) {
429140870Sharti			char *ptr = MAKEFLAGS_quote(*argv);
430133562Sharti
431133562Sharti			Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
432144896Sharti			Parse_DoVar(*argv, VAR_CMD);
433133562Sharti			free(ptr);
434133562Sharti
435144896Sharti		} else if ((*argv)[0] == '-') {
436144896Sharti			if ((*argv)[1] == '\0') {
437144896Sharti				/*
438144896Sharti				 * (*argv) is a single dash, so we
439144896Sharti				 * just ignore it.
440144896Sharti				 */
441144896Sharti			} else {
442144896Sharti				/*
443144896Sharti				 * (*argv) is a -flag, so backup argv
444144896Sharti				 *  and argc, since getopt() expects
445144896Sharti				 * options to start in the 2nd position.
446144896Sharti				 */
447144896Sharti				argc++;
448144896Sharti				argv--;
4491590Srgrimes				goto rearg;
4501590Srgrimes			}
451144896Sharti
452144896Sharti		} else if ((*argv)[0] == '\0') {
453144896Sharti			Punt("illegal (null) argument.");
454144896Sharti
455144896Sharti		} else {
456138916Sharti			Lst_AtEnd(&create, estrdup(*argv));
4571590Srgrimes		}
458144896Sharti	}
4591590Srgrimes}
4601590Srgrimes
461144475Sharti/**
462144475Sharti * Main_ParseArgLine
4631590Srgrimes *  	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
4641590Srgrimes *	is encountered and by main() when reading the .MAKEFLAGS envariable.
4651590Srgrimes *	Takes a line of arguments and breaks it into its
4661590Srgrimes * 	component words and passes those words and the number of them to the
4671590Srgrimes *	MainParseArgs function.
4681590Srgrimes *	The line should have all its leading whitespace removed.
4691590Srgrimes *
4701590Srgrimes * Side Effects:
4711590Srgrimes *	Only those that come from the various arguments.
4721590Srgrimes */
4731590Srgrimesvoid
474140870ShartiMain_ParseArgLine(char *line, int mflags)
4751590Srgrimes{
4761590Srgrimes	char **argv;			/* Manufactured argument vector */
4771590Srgrimes	int argc;			/* Number of arguments in argv */
4781590Srgrimes
4791590Srgrimes	if (line == NULL)
4801590Srgrimes		return;
4811590Srgrimes	for (; *line == ' '; ++line)
4821590Srgrimes		continue;
4831590Srgrimes	if (!*line)
4841590Srgrimes		return;
4851590Srgrimes
486140870Sharti	if (mflags)
487140870Sharti		argv = MAKEFLAGS_break(line, &argc);
488140870Sharti	else
489140870Sharti		argv = brk_string(line, &argc, TRUE);
490140870Sharti
4911590Srgrimes	MainParseArgs(argc, argv);
4921590Srgrimes}
4931590Srgrimes
49418339Sswallacechar *
495141252Shartichdir_verify_path(const char *path, char *obpath)
49618339Sswallace{
49718339Sswallace	struct stat sb;
49818339Sswallace
49918339Sswallace	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
50075973Sru		if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {
50127644Scharnier			warn("warning: %s", path);
502141252Sharti			return (NULL);
50318339Sswallace		}
504138232Sharti		return (obpath);
50518339Sswallace	}
50618339Sswallace
507141252Sharti	return (NULL);
50818339Sswallace}
50918339Sswallace
510133082Shartistatic void
511133082Sharticatch_child(int sig __unused)
512123513Sdes{
513123513Sdes}
51418339Sswallace
515138071Sjmallett/*
516138071Sjmallett * In lieu of a good way to prevent every possible looping in
517138071Sjmallett * make(1), stop there from being more than MKLVL_MAXVAL processes forked
518138071Sjmallett * by make(1), to prevent a forkbomb from happening, in a dumb and
519138071Sjmallett * mechanical way.
520138071Sjmallett */
521138071Sjmallettstatic void
522138071Sjmallettcheck_make_level(void)
523138071Sjmallett{
524138071Sjmallett#ifdef WANT_ENV_MKLVL
525138071Sjmallett	char	*value = getenv(MKLVL_ENVVAR);
526138071Sjmallett	int	level = (value == NULL) ? 0 : atoi(value);
527138071Sjmallett
528138071Sjmallett	if (level < 0) {
529144475Sharti		errc(2, EAGAIN, "Invalid value for recursion level (%d).",
530144475Sharti		    level);
531138071Sjmallett	} else if (level > MKLVL_MAXVAL) {
532144475Sharti		errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
533144475Sharti		    MKLVL_MAXVAL);
534138071Sjmallett	} else {
535138071Sjmallett		char new_value[32];
536138071Sjmallett		sprintf(new_value, "%d", level + 1);
537138071Sjmallett		setenv(MKLVL_ENVVAR, new_value, 1);
538138071Sjmallett	}
539138071Sjmallett#endif /* WANT_ENV_MKLVL */
540138071Sjmallett}
541138071Sjmallett
542144475Sharti/**
543144475Sharti * main
5441590Srgrimes *	The main function, for obvious reasons. Initializes variables
5451590Srgrimes *	and a few modules, then parses the arguments give it in the
5461590Srgrimes *	environment and on the command line. Reads the system makefile
5471590Srgrimes *	followed by either Makefile, makefile or the file given by the
5481590Srgrimes *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
5491590Srgrimes *	flags it has received by then uses either the Make or the Compat
5501590Srgrimes *	module to create the initial list of targets.
5511590Srgrimes *
5521590Srgrimes * Results:
5531590Srgrimes *	If -q was given, exits -1 if anything was out-of-date. Else it exits
5541590Srgrimes *	0.
5551590Srgrimes *
5561590Srgrimes * Side Effects:
5571590Srgrimes *	The program exits when done. Targets are created. etc. etc. etc.
5581590Srgrimes */
5591590Srgrimesint
560104696Sjmallettmain(int argc, char **argv)
5611590Srgrimes{
5621590Srgrimes	Boolean outOfDate = TRUE; 	/* FALSE if all targets up to date */
563141252Sharti	char *p, *p1, *pathp;
564141252Sharti	char *path;
56573262Simp	char mdpath[MAXPATHLEN];
56673262Simp	char obpath[MAXPATHLEN];
56773262Simp	char cdpath[MAXPATHLEN];
568141252Sharti    	const char *machine = getenv("MACHINE");
569141252Sharti	const char *machine_arch = getenv("MACHINE_ARCH");
570141252Sharti	const char *machine_cpu = getenv("MACHINE_CPU");
57118730Ssteve	char *cp = NULL, *start;
572141252Sharti
573144475Sharti	/* avoid faults on read-only strings */
574143412Sharti	static char syspath[] = PATH_DEFSYSPATH;
5751590Srgrimes
576123513Sdes	{
577123513Sdes	/*
578123513Sdes	 * Catch SIGCHLD so that we get kicked out of select() when we
579123513Sdes	 * need to look at a child.  This is only known to matter for the
580123513Sdes	 * -j case (perhaps without -P).
581123513Sdes	 *
582123513Sdes	 * XXX this is intentionally misplaced.
583123513Sdes	 */
584123513Sdes	struct sigaction sa;
585123513Sdes
586123513Sdes	sigemptyset(&sa.sa_mask);
587123513Sdes	sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
588123513Sdes	sa.sa_handler = catch_child;
589123513Sdes	sigaction(SIGCHLD, &sa, NULL);
590123513Sdes	}
591123513Sdes
592138071Sjmallett	check_make_level();
593104395Sjmallett
59464739Sgreen#if DEFSHELL == 2
59564739Sgreen	/*
59664739Sgreen	 * Turn off ENV to make ksh happier.
59764739Sgreen	 */
59864739Sgreen	unsetenv("ENV");
59964739Sgreen#endif
60064739Sgreen
60118730Ssteve#ifdef RLIMIT_NOFILE
6021590Srgrimes	/*
60318730Ssteve	 * get rid of resource limit on file descriptors
60418730Ssteve	 */
60518730Ssteve	{
60618730Ssteve		struct rlimit rl;
60718730Ssteve		if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
60818730Ssteve		    rl.rlim_cur != rl.rlim_max) {
60918730Ssteve			rl.rlim_cur = rl.rlim_max;
610138232Sharti			setrlimit(RLIMIT_NOFILE, &rl);
61118730Ssteve		}
61218730Ssteve	}
61318730Ssteve#endif
6141590Srgrimes
6155814Sjkh	/*
61639006Skato	 * PC-98 kernel sets the `i386' string to the utsname.machine and
61739006Skato	 * it cannot be distinguished from IBM-PC by uname(3).  Therefore,
61839006Skato	 * we check machine.ispc98 and adjust the machine variable before
61939006Skato	 * using usname(3) below.
62053631Smarcel	 * NOTE: machdep.ispc98 was defined on 1998/8/31. At that time,
62153631Smarcel	 * __FreeBSD_version was defined as 300003. So, this check can
62253631Smarcel	 * safely be done with any kernel with version > 300003.
62339006Skato	 */
62439006Skato	if (!machine) {
62539006Skato		int	ispc98;
62639006Skato		size_t	len;
62739006Skato
62839006Skato		len = sizeof(ispc98);
62939006Skato		if (!sysctlbyname("machdep.ispc98", &ispc98, &len, NULL, 0)) {
63039006Skato			if (ispc98)
63139006Skato				machine = "pc98";
63239006Skato		}
63339006Skato	}
63439006Skato
63539006Skato	/*
6365814Sjkh	 * Get the name of this type of MACHINE from utsname
6375814Sjkh	 * so we can share an executable for similar machines.
6385814Sjkh	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
6395814Sjkh	 *
6405814Sjkh	 * Note that while MACHINE is decided at run-time,
6415814Sjkh	 * MACHINE_ARCH is always known at compile time.
6425814Sjkh	 */
64318864Ssteve	if (!machine) {
64418339Sswallace#ifndef MACHINE
645144475Sharti		static struct utsname utsname;
64618730Ssteve
647144475Sharti		if (uname(&utsname) == -1)
648144475Sharti			err(2, "uname");
649144475Sharti		machine = utsname.machine;
65018339Sswallace#else
651144475Sharti		machine = MACHINE;
65218339Sswallace#endif
6535814Sjkh	}
6541590Srgrimes
65544362Simp	if (!machine_arch) {
65644362Simp#ifndef MACHINE_ARCH
65744362Simp		machine_arch = "unknown";
65844362Simp#else
65944362Simp		machine_arch = MACHINE_ARCH;
66044362Simp#endif
66144362Simp	}
66244362Simp
6631590Srgrimes	/*
66472679Skris	 * Set machine_cpu to the minumum supported CPU revision based
66572679Skris	 * on the target architecture, if not already set.
66672679Skris	 */
66772679Skris	if (!machine_cpu) {
66872679Skris		if (!strcmp(machine_arch, "i386"))
66972679Skris			machine_cpu = "i386";
67072679Skris		else if (!strcmp(machine_arch, "alpha"))
67172679Skris			machine_cpu = "ev4";
67272679Skris		else
67372679Skris			machine_cpu = "unknown";
67472679Skris	}
6751590Srgrimes
67666365Speter	expandVars = TRUE;
6771590Srgrimes	beSilent = FALSE;		/* Print commands as executed */
6781590Srgrimes	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
6791590Srgrimes	noExecute = FALSE;		/* Execute all commands */
6801590Srgrimes	keepgoing = FALSE;		/* Stop on error */
6811590Srgrimes	allPrecious = FALSE;		/* Remove targets when interrupted */
6821590Srgrimes	queryFlag = FALSE;		/* This is not just a check-run */
6831590Srgrimes	noBuiltins = FALSE;		/* Read the built-in rules */
6841590Srgrimes	touchFlag = FALSE;		/* Actually update targets */
6851590Srgrimes	usePipes = TRUE;		/* Catch child output in pipes */
6861590Srgrimes	debug = 0;			/* No debug verbosity, please. */
6871590Srgrimes	jobsRunning = FALSE;
6881590Srgrimes
689137571Sphk	maxJobs = DEFMAXJOBS;
69028228Sfsmp	forceJobs = FALSE;              /* No -j flag */
69118730Ssteve	compatMake = FALSE;		/* No compat mode */
6921590Srgrimes
6931590Srgrimes	/*
6941590Srgrimes	 * Initialize the parsing, directory and variable modules to prepare
6951590Srgrimes	 * for the reading of inclusion paths and variable settings on the
6961590Srgrimes	 * command line
6971590Srgrimes	 */
6981590Srgrimes	Dir_Init();		/* Initialize directory structures so -I flags
6991590Srgrimes				 * can be processed correctly */
700145971Sharti	Var_Init(environ);	/* As well as the lists of variables for
7011590Srgrimes				 * parsing arguments */
7025814Sjkh        str_init();
7031590Srgrimes
7041590Srgrimes	/*
7051590Srgrimes	 * Initialize various variables.
7061590Srgrimes	 *	MAKE also gets this name, for compatibility
7071590Srgrimes	 *	.MAKEFLAGS gets set to the empty string just in case.
7081590Srgrimes	 *	MFLAGS also gets initialized empty, for compatibility.
7091590Srgrimes	 */
7101590Srgrimes	Var_Set("MAKE", argv[0], VAR_GLOBAL);
7111590Srgrimes	Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
7121590Srgrimes	Var_Set("MFLAGS", "", VAR_GLOBAL);
7135814Sjkh	Var_Set("MACHINE", machine, VAR_GLOBAL);
71444362Simp	Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
71572679Skris	Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL);
71697121Sru#ifdef MAKE_VERSION
71797121Sru	Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
71897121Sru#endif
7191590Srgrimes
7201590Srgrimes	/*
721144896Sharti	 * First snag things out of the MAKEFLAGS environment
722144896Sharti	 * variable.  Then parse the command line arguments.
7231590Srgrimes	 */
724140870Sharti	Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
7258874Srgrimes
7261590Srgrimes	MainParseArgs(argc, argv);
7271590Srgrimes
7281590Srgrimes	/*
729120053Sru	 * Find where we are...
730120053Sru	 */
731120053Sru	curdir = cdpath;
732120053Sru	if (getcwd(curdir, MAXPATHLEN) == NULL)
733120053Sru		err(2, NULL);
734120053Sru
735141252Sharti	{
736141252Sharti	struct stat sa;
737141252Sharti
738120053Sru	if (stat(curdir, &sa) == -1)
739120053Sru	    err(2, "%s", curdir);
740141252Sharti	}
741120053Sru
742120053Sru	/*
743120053Sru	 * The object directory location is determined using the
744120053Sru	 * following order of preference:
745120053Sru	 *
746120053Sru	 *	1. MAKEOBJDIRPREFIX`cwd`
747120053Sru	 *	2. MAKEOBJDIR
748143412Sharti	 *	3. PATH_OBJDIR.${MACHINE}
749143412Sharti	 *	4. PATH_OBJDIR
750143412Sharti	 *	5. PATH_OBJDIRPREFIX`cwd`
751120053Sru	 *
752120053Sru	 * If one of the first two fails, use the current directory.
753120053Sru	 * If the remaining three all fail, use the current directory.
754120053Sru	 *
755120053Sru	 * Once things are initted,
756120053Sru	 * have to add the original directory to the search path,
757120053Sru	 * and modify the paths for the Makefiles apropriately.  The
758120053Sru	 * current directory is also placed as a variable for make scripts.
759120053Sru	 */
760120053Sru	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
761120053Sru		if (!(path = getenv("MAKEOBJDIR"))) {
762143412Sharti			path = PATH_OBJDIR;
763143412Sharti			pathp = PATH_OBJDIRPREFIX;
764138232Sharti			snprintf(mdpath, MAXPATHLEN, "%s.%s",
765120053Sru					path, machine);
766120053Sru			if (!(objdir = chdir_verify_path(mdpath, obpath)))
767120053Sru				if (!(objdir=chdir_verify_path(path, obpath))) {
768138232Sharti					snprintf(mdpath, MAXPATHLEN,
769120053Sru							"%s%s", pathp, curdir);
770120053Sru					if (!(objdir=chdir_verify_path(mdpath,
771120053Sru								       obpath)))
772120053Sru						objdir = curdir;
773120053Sru				}
774120053Sru		}
775120053Sru		else if (!(objdir = chdir_verify_path(path, obpath)))
776120053Sru			objdir = curdir;
777120053Sru	}
778120053Sru	else {
779138232Sharti		snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
780120053Sru		if (!(objdir = chdir_verify_path(mdpath, obpath)))
781120053Sru			objdir = curdir;
782120053Sru	}
783120053Sru	Dir_InitDot();		/* Initialize the "." directory */
784120053Sru	if (objdir != curdir)
785144020Sharti		Path_AddDir(&dirSearchPath, curdir);
786145971Sharti	Var_Set(".ST_EXPORTVAR", "YES", VAR_GLOBAL);
787120053Sru	Var_Set(".CURDIR", curdir, VAR_GLOBAL);
788120053Sru	Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
789120053Sru
790137606Sphk	if (getenv("MAKE_JOBS_FIFO") != NULL)
791137606Sphk		forceJobs = TRUE;
792120053Sru	/*
79328228Sfsmp	 * Be compatible if user did not specify -j and did not explicitly
79428228Sfsmp	 * turned compatibility on
79528228Sfsmp	 */
79628228Sfsmp	if (!compatMake && !forceJobs)
79728228Sfsmp		compatMake = TRUE;
79828228Sfsmp
79928228Sfsmp	/*
800144387Sharti	 * Initialize target and suffix modules in preparation for
8011590Srgrimes	 * parsing the makefile(s)
8021590Srgrimes	 */
8031590Srgrimes	Targ_Init();
8041590Srgrimes	Suff_Init();
8051590Srgrimes
80669527Swill	DEFAULT = NULL;
807138232Sharti	time(&now);
8081590Srgrimes
8091590Srgrimes	/*
8101590Srgrimes	 * Set up the .TARGETS variable to contain the list of targets to be
8111590Srgrimes	 * created. If none specified, make the variable empty -- the parser
8121590Srgrimes	 * will fill the thing in with the default or .MAIN target.
8131590Srgrimes	 */
814138916Sharti	if (!Lst_IsEmpty(&create)) {
815138512Sharti		LstNode *ln;
8161590Srgrimes
817138916Sharti		for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
818138264Sharti			char *name = Lst_Datum(ln);
8191590Srgrimes
8201590Srgrimes			Var_Append(".TARGETS", name, VAR_GLOBAL);
8211590Srgrimes		}
8221590Srgrimes	} else
8231590Srgrimes		Var_Set(".TARGETS", "", VAR_GLOBAL);
8241590Srgrimes
82518730Ssteve
8261590Srgrimes	/*
82718730Ssteve	 * If no user-supplied system path was given (through the -m option)
82818730Ssteve	 * add the directories from the DEFSYSPATH (more than one may be given
82918730Ssteve	 * as dir1:...:dirn) to the system include path.
8301590Srgrimes	 */
831144020Sharti	if (TAILQ_EMPTY(&sysIncPath)) {
83218730Ssteve		for (start = syspath; *start != '\0'; start = cp) {
83318730Ssteve			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
83418730Ssteve				continue;
83518730Ssteve			if (*cp == '\0') {
836144020Sharti				Path_AddDir(&sysIncPath, start);
83718730Ssteve			} else {
83818730Ssteve				*cp++ = '\0';
839144020Sharti				Path_AddDir(&sysIncPath, start);
84018730Ssteve			}
84118730Ssteve		}
84218730Ssteve	}
8431590Srgrimes
84418730Ssteve	/*
84518730Ssteve	 * Read in the built-in rules first, followed by the specified
84618730Ssteve	 * makefile, if it was (makefile != (char *) NULL), or the default
84718730Ssteve	 * Makefile and makefile, in that order, if it wasn't.
84818730Ssteve	 */
84918730Ssteve	if (!noBuiltins) {
850138916Sharti		/* Path of sys.mk */
851138916Sharti		Lst sysMkPath = Lst_Initializer(sysMkPath);
852138512Sharti		LstNode *ln;
85318730Ssteve
854144020Sharti		Path_Expand(PATH_DEFSYSMK, &sysIncPath, &sysMkPath);
855138916Sharti		if (Lst_IsEmpty(&sysMkPath))
856143412Sharti			Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
857143808Sharti		LST_FOREACH(ln, &sysMkPath) {
858143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
859143808Sharti				break;
860143808Sharti		}
86169527Swill		if (ln != NULL)
86218730Ssteve			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
863138916Sharti		Lst_Destroy(&sysMkPath, free);
86418730Ssteve	}
86518730Ssteve
866138916Sharti	if (!Lst_IsEmpty(&makefiles)) {
867138512Sharti		LstNode *ln;
8681590Srgrimes
869143808Sharti		LST_FOREACH(ln, &makefiles) {
870143808Sharti			if (!ReadMakefile(Lst_Datum(ln)))
871143808Sharti				break;
872143808Sharti		}
87369527Swill		if (ln != NULL)
8741590Srgrimes			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
875143808Sharti	} else if (!ReadMakefile("BSDmakefile"))
876143808Sharti	    if (!ReadMakefile("makefile"))
877143808Sharti		ReadMakefile("Makefile");
8781590Srgrimes
879143808Sharti	ReadMakefile(".depend");
8801590Srgrimes
8811590Srgrimes	/* Install all the flags into the MAKE envariable. */
8825814Sjkh	if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
8831590Srgrimes		setenv("MAKEFLAGS", p, 1);
884105826Sjmallett	free(p1);
8851590Srgrimes
8861590Srgrimes	/*
8871590Srgrimes	 * For compatibility, look at the directories in the VPATH variable
8881590Srgrimes	 * and add them to the search path, if the variable is defined. The
8891590Srgrimes	 * variable's value is in the same format as the PATH envariable, i.e.
8901590Srgrimes	 * <directory>:<directory>:<directory>...
8911590Srgrimes	 */
8921590Srgrimes	if (Var_Exists("VPATH", VAR_CMD)) {
8931590Srgrimes		/*
8941590Srgrimes		 * GCC stores string constants in read-only memory, but
8951590Srgrimes		 * Var_Subst will want to write this thing, so store it
8961590Srgrimes		 * in an array
8971590Srgrimes		 */
8981590Srgrimes		static char VPATH[] = "${VPATH}";
899142457Sharti		Buffer	*buf;
900142457Sharti		char	*vpath;
901142457Sharti		char	*ptr;
902142457Sharti		char	savec;
9031590Srgrimes
904142457Sharti		buf = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
905142457Sharti
906143959Sharti		vpath = Buf_Data(buf);
9071590Srgrimes		do {
9081590Srgrimes			/* skip to end of directory */
909142457Sharti			for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
910141969Sharti				;
911141969Sharti
9121590Srgrimes			/* Save terminator character so know when to stop */
913141969Sharti			savec = *ptr;
914141969Sharti			*ptr = '\0';
915141969Sharti
9161590Srgrimes			/* Add directory to search path */
917144020Sharti			Path_AddDir(&dirSearchPath, vpath);
918141969Sharti
919142457Sharti			vpath = ptr + 1;
920141969Sharti		} while (savec != '\0');
921142457Sharti
922142457Sharti		Buf_Destroy(buf, TRUE);
9231590Srgrimes	}
9241590Srgrimes
9251590Srgrimes	/*
9261590Srgrimes	 * Now that all search paths have been read for suffixes et al, it's
9271590Srgrimes	 * time to add the default search path to their lists...
9281590Srgrimes	 */
9291590Srgrimes	Suff_DoPaths();
9301590Srgrimes
9311590Srgrimes	/* print the initial graph, if the user requested it */
9321590Srgrimes	if (DEBUG(GRAPH1))
9331590Srgrimes		Targ_PrintGraph(1);
9341590Srgrimes
93517193Sbde	/* print the values of any variables requested by the user */
936141974Sharti	if (Lst_IsEmpty(&variables)) {
9371590Srgrimes		/*
938141974Sharti		 * Since the user has not requested that any variables
939142008Sharti		 * be printed, we can build targets.
940141974Sharti		 *
941142008Sharti		 * Have read the entire graph and need to make a list of targets
942141974Sharti		 * to create. If none was given on the command line, we consult
943141974Sharti		 * the parsing module to find the main target(s) to create.
9441590Srgrimes		 */
945138916Sharti		Lst targs = Lst_Initializer(targs);
946138916Sharti
947138916Sharti		if (Lst_IsEmpty(&create))
948138916Sharti			Parse_MainName(&targs);
949101460Sru		else
950138916Sharti			Targ_FindList(&targs, &create, TARG_CREATE);
951101460Sru
952141974Sharti		if (compatMake) {
953101460Sru			/*
954141974Sharti			 * Compat_Init will take care of creating
955141974Sharti			 * all the targets as well as initializing
956141974Sharti			 * the module.
957101460Sru			 */
958141974Sharti			Compat_Run(&targs);
959141974Sharti			outOfDate = 0;
960141974Sharti		} else {
961141974Sharti			/*
962141974Sharti			 * Initialize job module before traversing
963141974Sharti			 * the graph, now that any .BEGIN and .END
964141974Sharti			 * targets have been read.  This is done
965141974Sharti			 * only if the -q flag wasn't given (to
966141974Sharti			 * prevent the .BEGIN from being executed
967141974Sharti			 * should it exist).
968141974Sharti			 */
969101460Sru			if (!queryFlag) {
970137572Sphk				Job_Init(maxJobs);
971101460Sru				jobsRunning = TRUE;
972101460Sru			}
973101460Sru
974101460Sru			/* Traverse the graph, checking on all the targets */
975138916Sharti			outOfDate = Make_Run(&targs);
9761590Srgrimes		}
977138916Sharti		Lst_Destroy(&targs, NOFREE);
978141974Sharti
979141974Sharti	} else {
980141974Sharti		/*
981141974Sharti		 * Print the values of any variables requested by
982141974Sharti		 * the user.
983141974Sharti		 */
984142457Sharti		LstNode		*n;
985142457Sharti		const char	*name;
986142457Sharti		char		*v;
987142457Sharti		char		*value;
988141974Sharti
989142457Sharti		LST_FOREACH(n, &variables) {
990142457Sharti			name = Lst_Datum(n);
991141974Sharti			if (expandVars) {
992141974Sharti				v = emalloc(strlen(name) + 1 + 3);
993141974Sharti				sprintf(v, "${%s}", name);
994141974Sharti
995143292Sharti				value = Buf_Peel(Var_Subst(NULL, v,
996143292Sharti				    VAR_GLOBAL, FALSE));
997142457Sharti				printf("%s\n", value);
998142457Sharti
999142457Sharti				free(v);
1000143292Sharti				free(value);
1001141974Sharti			} else {
1002141974Sharti				value = Var_Value(name, VAR_GLOBAL, &v);
1003142457Sharti				printf("%s\n", value != NULL ? value : "");
1004142457Sharti				if (v != NULL)
1005142457Sharti					free(v);
1006141974Sharti			}
1007141974Sharti		}
100817193Sbde	}
10098874Srgrimes
1010138920Sru	Lst_Destroy(&variables, free);
1011138920Sru	Lst_Destroy(&makefiles, free);
1012138916Sharti	Lst_Destroy(&create, free);
10135814Sjkh
10141590Srgrimes	/* print the graph now it's been processed if the user requested it */
10151590Srgrimes	if (DEBUG(GRAPH2))
10161590Srgrimes		Targ_PrintGraph(2);
10171590Srgrimes
10181590Srgrimes	if (queryFlag && outOfDate)
1019138232Sharti		return (1);
10201590Srgrimes	else
1021138232Sharti		return (0);
10221590Srgrimes}
10231590Srgrimes
1024144475Sharti/**
1025144475Sharti * ReadMakefile
10261590Srgrimes *	Open and parse the given makefile.
10271590Srgrimes *
10281590Srgrimes * Results:
10291590Srgrimes *	TRUE if ok. FALSE if couldn't open file.
10301590Srgrimes *
10311590Srgrimes * Side Effects:
10321590Srgrimes *	lots
10331590Srgrimes */
10341590Srgrimesstatic Boolean
1035143808ShartiReadMakefile(const char *p)
10361590Srgrimes{
1037104696Sjmallett	char *fname;			/* makefile to read */
10381590Srgrimes	FILE *stream;
103973262Simp	char *name, path[MAXPATHLEN];
104097163Sjmallett	char *MAKEFILE;
104194990Sru	int setMAKEFILE;
10421590Srgrimes
1043138561Sharti	/* XXX - remove this once constification is done */
1044138561Sharti	fname = estrdup(p);
1045104696Sjmallett
10461590Srgrimes	if (!strcmp(fname, "-")) {
10471590Srgrimes		Parse_File("(stdin)", stdin);
10481590Srgrimes		Var_Set("MAKEFILE", "", VAR_GLOBAL);
10491590Srgrimes	} else {
105094990Sru		setMAKEFILE = strcmp(fname, ".depend");
105194990Sru
10521590Srgrimes		/* if we've chdir'd, rebuild the path name */
10531590Srgrimes		if (curdir != objdir && *fname != '/') {
1054138232Sharti			snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
1055100733Simp			/*
1056100733Simp			 * XXX The realpath stuff breaks relative includes
1057100733Simp			 * XXX in some cases.   The problem likely is in
1058100733Simp			 * XXX parse.c where it does special things in
1059100733Simp			 * XXX ParseDoInclude if the file is relateive
1060100733Simp			 * XXX or absolute and not a system file.  There
1061100733Simp			 * XXX it assumes that if the current file that's
1062100733Simp			 * XXX being included is absolute, that any files
1063100733Simp			 * XXX that it includes shouldn't do the -I path
1064100733Simp			 * XXX stuff, which is inconsistant with historical
1065100733Simp			 * XXX behavior.  However, I can't pentrate the mists
1066100733Simp			 * XXX further, so I'm putting this workaround in
1067100733Simp			 * XXX here until such time as the underlying bug
1068100733Simp			 * XXX can be fixed.
1069100733Simp			 */
1070100733Simp#if THIS_BREAKS_THINGS
107197077Sjmallett			if (realpath(path, path) != NULL &&
107297077Sjmallett			    (stream = fopen(path, "r")) != NULL) {
107397163Sjmallett				MAKEFILE = fname;
10741590Srgrimes				fname = path;
10751590Srgrimes				goto found;
10761590Srgrimes			}
107797077Sjmallett		} else if (realpath(fname, path) != NULL) {
107897163Sjmallett			MAKEFILE = fname;
107997077Sjmallett			fname = path;
108097077Sjmallett			if ((stream = fopen(fname, "r")) != NULL)
108197077Sjmallett				goto found;
108297077Sjmallett		}
1083100733Simp#else
1084100733Simp			if ((stream = fopen(path, "r")) != NULL) {
1085100733Simp				MAKEFILE = fname;
1086100733Simp				fname = path;
1087100733Simp				goto found;
1088100733Simp			}
1089100733Simp		} else {
1090100733Simp			MAKEFILE = fname;
1091100733Simp			if ((stream = fopen(fname, "r")) != NULL)
1092100733Simp				goto found;
1093100733Simp		}
1094100733Simp#endif
10951590Srgrimes		/* look in -I and system include directories. */
1096144020Sharti		name = Path_FindFile(fname, &parseIncPath);
10971590Srgrimes		if (!name)
1098144020Sharti			name = Path_FindFile(fname, &sysIncPath);
10991590Srgrimes		if (!name || !(stream = fopen(name, "r")))
1100138232Sharti			return (FALSE);
110197163Sjmallett		MAKEFILE = fname = name;
11021590Srgrimes		/*
11031590Srgrimes		 * set the MAKEFILE variable desired by System V fans -- the
11041590Srgrimes		 * placement of the setting here means it gets set to the last
11051590Srgrimes		 * makefile specified, as it is set by SysV make.
11061590Srgrimes		 */
110794990Srufound:
110894990Sru		if (setMAKEFILE)
110997163Sjmallett			Var_Set("MAKEFILE", MAKEFILE, VAR_GLOBAL);
11101590Srgrimes		Parse_File(fname, stream);
1111138232Sharti		fclose(stream);
11121590Srgrimes	}
1113138232Sharti	return (TRUE);
11141590Srgrimes}
11151590Srgrimes
1116144475Sharti/**
1117144475Sharti * Cmd_Exec
111818730Ssteve *	Execute the command in cmd, and return the output of that command
111918730Ssteve *	in a string.
112018730Ssteve *
112118730Ssteve * Results:
112218730Ssteve *	A string containing the output of the command, or the empty string
1123104121Sjmallett *	If error is not NULL, it contains the reason for the command failure
112418730Ssteve *
112518730Ssteve * Side Effects:
112618730Ssteve *	The string must be freed by the caller.
112718730Ssteve */
1128141454ShartiBuffer *
1129141252ShartiCmd_Exec(char *cmd, const char **error)
113018730Ssteve{
1131144475Sharti	int	fds[2];	/* Pipe streams */
1132144475Sharti	int	cpid;	/* Child PID */
1133144475Sharti	int	pid;	/* PID from wait() */
1134144475Sharti	int	status;	/* command exit status */
1135144475Sharti	Buffer	*buf;	/* buffer to store the result */
1136144475Sharti	ssize_t	rcnt;
113718730Ssteve
1138144475Sharti	*error = NULL;
1139144475Sharti	buf = Buf_Init(0);
114018730Ssteve
1141144475Sharti	if (shellPath == NULL)
1142144475Sharti		Shell_Init();
114318730Ssteve	/*
1144144475Sharti	 * Open a pipe for fetching its output
114518730Ssteve	 */
1146144475Sharti	if (pipe(fds) == -1) {
1147144475Sharti		*error = "Couldn't create pipe for \"%s\"";
1148144475Sharti		return (buf);
1149144475Sharti	}
115018730Ssteve
115118730Ssteve	/*
1152144475Sharti	 * Fork
115318730Ssteve	 */
1154144475Sharti	switch (cpid = vfork()) {
1155144475Sharti	  case 0:
1156144475Sharti		/*
1157144475Sharti		 * Close input side of pipe
1158144475Sharti		 */
1159144475Sharti		close(fds[0]);
116018730Ssteve
1161144475Sharti		/*
1162144475Sharti		 * Duplicate the output stream to the shell's output, then
1163144475Sharti		 * shut the extra thing down. Note we don't fetch the error
1164144475Sharti		 * stream...why not? Why?
1165144475Sharti		 */
1166144475Sharti		dup2(fds[1], 1);
1167144475Sharti		close(fds[1]);
116818730Ssteve
1169144475Sharti		{
1170144475Sharti			char	*args[4];
1171141454Sharti
1172144475Sharti			/* Set up arguments for shell */
1173144475Sharti			args[0] = shellName;
1174144475Sharti			args[1] = "-c";
1175144475Sharti			args[2] = cmd;
1176144475Sharti			args[3] = NULL;
1177141454Sharti
1178144475Sharti			execv(shellPath, args);
1179144475Sharti			_exit(1);
1180144475Sharti			/*NOTREACHED*/
1181144475Sharti		}
118218730Ssteve
1183144475Sharti	  case -1:
1184144475Sharti		*error = "Couldn't exec \"%s\"";
1185144475Sharti		return (buf);
118618730Ssteve
1187144475Sharti	  default:
1188144475Sharti		/*
1189144475Sharti		 * No need for the writing half
1190144475Sharti		 */
1191144475Sharti		close(fds[1]);
1192141454Sharti
1193144475Sharti		do {
1194144475Sharti			char	result[BUFSIZ];
1195141454Sharti
1196144475Sharti			rcnt = read(fds[0], result, sizeof(result));
1197144475Sharti			if (rcnt != -1)
1198144475Sharti				Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result);
1199144475Sharti		} while (rcnt > 0 || (rcnt == -1 && errno == EINTR));
120018730Ssteve
1201144475Sharti		if (rcnt == -1)
1202144475Sharti			*error = "Error reading shell's output for \"%s\"";
120318730Ssteve
1204144475Sharti		/*
1205144475Sharti		 * Close the input side of the pipe.
1206144475Sharti		 */
1207144475Sharti		close(fds[0]);
120818730Ssteve
1209144475Sharti		/*
1210144475Sharti		 * Wait for the process to exit.
1211144475Sharti		 */
1212144475Sharti		while (((pid = wait(&status)) != cpid) && (pid >= 0))
1213144475Sharti			continue;
121418730Ssteve
1215144475Sharti		if (status)
1216144475Sharti			*error = "\"%s\" returned non-zero status";
1217144475Sharti
1218144475Sharti		Buf_StripNewlines(buf);
1219144475Sharti
1220144475Sharti		break;
1221144475Sharti	}
1222144475Sharti	return (buf);
122318730Ssteve}
122418730Ssteve
12251590Srgrimes/*
12261590Srgrimes * usage --
12271590Srgrimes *	exit with usage message
12281590Srgrimes */
12291590Srgrimesstatic void
1230104696Sjmallettusage(void)
12311590Srgrimes{
1232145627Sharti	fprintf(stderr, "%s\n%s\n%s\n%s\n",
1233145627Sharti"usage: make [-ABPSXeiknqrstv] [-C directory] [-D variable] [-d flags]",
1234113512Sru"            [-E variable] [-f makefile] [-I directory] [-j max_jobs]",
1235145627Sharti"            [-m directory] [-V variable] [variable=value] [-x warn_flag]",
1236145627Sharti"            [target ...]");
12371590Srgrimes	exit(2);
12381590Srgrimes}
1239