main.c revision 28191
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39#ifndef lint
40static const char copyright[] =
41"@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
42	The Regents of the University of California.  All rights reserved.\n";
43#endif /* not lint */
44
45#ifndef lint
46#if 0
47static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 3/19/94";
48#endif
49static const char rcsid[] =
50	"$Id: main.c,v 1.18 1997/07/24 06:58:06 charnier Exp $";
51#endif /* not lint */
52
53/*-
54 * main.c --
55 *	The main file for this entire program. Exit routines etc
56 *	reside here.
57 *
58 * Utility functions defined in this file:
59 *	Main_ParseArgLine	Takes a line of arguments, breaks them and
60 *				treats them as if they were given when first
61 *				invoked. Used by the parse module to implement
62 *				the .MFLAGS target.
63 *
64 *	Error			Print a tagged error message. The global
65 *				MAKE variable must have been defined. This
66 *				takes a format string and two optional
67 *				arguments for it.
68 *
69 *	Fatal			Print an error message and exit. Also takes
70 *				a format string and two arguments.
71 *
72 *	Punt			Aborts all jobs and exits with a message. Also
73 *				takes a format string and two arguments.
74 *
75 *	Finish			Finish things up by printing the number of
76 *				errors which occured, as passed to it, and
77 *				exiting.
78 */
79
80#include <sys/types.h>
81#include <sys/time.h>
82#include <sys/param.h>
83#include <sys/resource.h>
84#include <sys/signal.h>
85#include <sys/stat.h>
86#ifndef MACHINE
87#include <sys/utsname.h>
88#endif
89#include <sys/wait.h>
90#include <err.h>
91#include <errno.h>
92#include <fcntl.h>
93#include <stdio.h>
94#if __STDC__
95#include <stdarg.h>
96#else
97#include <varargs.h>
98#endif
99#include "make.h"
100#include "hash.h"
101#include "dir.h"
102#include "job.h"
103#include "pathnames.h"
104
105#ifndef	DEFMAXLOCAL
106#define	DEFMAXLOCAL DEFMAXJOBS
107#endif	/* DEFMAXLOCAL */
108
109#define	MAKEFLAGS	".MAKEFLAGS"
110
111Lst			create;		/* Targets to be made */
112time_t			now;		/* Time at start of make */
113GNode			*DEFAULT;	/* .DEFAULT node */
114Boolean			allPrecious;	/* .PRECIOUS given on line by itself */
115
116static Boolean		noBuiltins;	/* -r flag */
117static Lst		makefiles;	/* ordered list of makefiles to read */
118static Boolean		printVars;	/* print value of one or more vars */
119static Lst		variables;	/* list of variables to print */
120int			maxJobs;	/* -j argument */
121static int		maxLocal;	/* -L argument */
122Boolean			compatMake;	/* -B argument */
123Boolean			debug;		/* -d flag */
124Boolean			noExecute;	/* -n flag */
125Boolean			keepgoing;	/* -k flag */
126Boolean			queryFlag;	/* -q flag */
127Boolean			touchFlag;	/* -t flag */
128Boolean			usePipes;	/* !-P flag */
129Boolean			ignoreErrors;	/* -i flag */
130Boolean			beSilent;	/* -s flag */
131Boolean			oldVars;	/* variable substitution style */
132Boolean			checkEnvFirst;	/* -e flag */
133static Boolean		jobsRunning;	/* TRUE if the jobs might be running */
134
135static void		MainParseArgs __P((int, char **));
136char *			chdir_verify_path __P((char *, char *));
137static int		ReadMakefile __P((ClientData, ClientData));
138static void		usage __P((void));
139
140static char *curdir;			/* startup directory */
141static char *objdir;			/* where we chdir'ed to */
142
143/*-
144 * MainParseArgs --
145 *	Parse a given argument vector. Called from main() and from
146 *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
147 *
148 *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
149 *
150 * Results:
151 *	None
152 *
153 * Side Effects:
154 *	Various global and local flags will be set depending on the flags
155 *	given
156 */
157static void
158MainParseArgs(argc, argv)
159	int argc;
160	char **argv;
161{
162	extern int optind;
163	extern char *optarg;
164	int c;
165	int forceJobs = 0;
166
167	optind = 1;	/* since we're called more than once */
168#ifdef REMOTE
169# define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst"
170#else
171# define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
172#endif
173rearg:	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
174		switch(c) {
175		case 'D':
176			Var_Set(optarg, "1", VAR_GLOBAL);
177			Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
178			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
179			break;
180		case 'I':
181			Parse_AddIncludeDir(optarg);
182			Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
183			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
184			break;
185		case 'V':
186			printVars = TRUE;
187			(void)Lst_AtEnd(variables, (ClientData)optarg);
188			Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
189			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
190			break;
191		case 'B':
192			compatMake = TRUE;
193			break;
194#ifdef REMOTE
195		case 'L':
196			maxLocal = atoi(optarg);
197			Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
198			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
199			break;
200#endif
201		case 'P':
202			usePipes = FALSE;
203			Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
204			break;
205		case 'S':
206			keepgoing = FALSE;
207			Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
208			break;
209		case 'd': {
210			char *modules = optarg;
211
212			for (; *modules; ++modules)
213				switch (*modules) {
214				case 'A':
215					debug = ~0;
216					break;
217				case 'a':
218					debug |= DEBUG_ARCH;
219					break;
220				case 'c':
221					debug |= DEBUG_COND;
222					break;
223				case 'd':
224					debug |= DEBUG_DIR;
225					break;
226				case 'f':
227					debug |= DEBUG_FOR;
228					break;
229				case 'g':
230					if (modules[1] == '1') {
231						debug |= DEBUG_GRAPH1;
232						++modules;
233					}
234					else if (modules[1] == '2') {
235						debug |= DEBUG_GRAPH2;
236						++modules;
237					}
238					break;
239				case 'j':
240					debug |= DEBUG_JOB;
241					break;
242				case 'm':
243					debug |= DEBUG_MAKE;
244					break;
245				case 's':
246					debug |= DEBUG_SUFF;
247					break;
248				case 't':
249					debug |= DEBUG_TARG;
250					break;
251				case 'v':
252					debug |= DEBUG_VAR;
253					break;
254				default:
255					warnx("illegal argument to d option -- %c", *modules);
256					usage();
257				}
258			Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
259			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
260			break;
261		}
262		case 'e':
263			checkEnvFirst = TRUE;
264			Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
265			break;
266		case 'f':
267			(void)Lst_AtEnd(makefiles, (ClientData)optarg);
268			break;
269		case 'i':
270			ignoreErrors = TRUE;
271			Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
272			break;
273		case 'j':
274			forceJobs = TRUE;
275			maxJobs = atoi(optarg);
276#ifndef REMOTE
277			maxLocal = maxJobs;
278#endif
279			Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
280			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
281			break;
282		case 'k':
283			keepgoing = TRUE;
284			Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
285			break;
286		case 'm':
287			Dir_AddDir(sysIncPath, optarg);
288			Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
289			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
290			break;
291		case 'n':
292			noExecute = TRUE;
293			Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
294			break;
295		case 'q':
296			queryFlag = TRUE;
297			/* Kind of nonsensical, wot? */
298			Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
299			break;
300		case 'r':
301			noBuiltins = TRUE;
302			Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
303			break;
304		case 's':
305			beSilent = TRUE;
306			Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
307			break;
308		case 't':
309			touchFlag = TRUE;
310			Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
311			break;
312		default:
313		case '?':
314			usage();
315		}
316	}
317
318	oldVars = TRUE;
319
320	/*
321	 * See if the rest of the arguments are variable assignments and
322	 * perform them if so. Else take them to be targets and stuff them
323	 * on the end of the "create" list.
324	 */
325	for (argv += optind, argc -= optind; *argv; ++argv, --argc)
326		if (Parse_IsVar(*argv))
327			Parse_DoVar(*argv, VAR_CMD);
328		else {
329			if (!**argv)
330				Punt("illegal (null) argument.");
331			if (**argv == '-') {
332				if ((*argv)[1])
333					optind = 0;     /* -flag... */
334				else
335					optind = 1;     /* - */
336				goto rearg;
337			}
338			(void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
339		}
340
341	/*
342	 * Be compatible if user did not specify -j and did not explicitly
343	 * turned compatibility on
344	 */
345	if (!compatMake && !forceJobs)
346		compatMake = TRUE;
347}
348
349/*-
350 * Main_ParseArgLine --
351 *  	Used by the parse module when a .MFLAGS or .MAKEFLAGS target
352 *	is encountered and by main() when reading the .MAKEFLAGS envariable.
353 *	Takes a line of arguments and breaks it into its
354 * 	component words and passes those words and the number of them to the
355 *	MainParseArgs function.
356 *	The line should have all its leading whitespace removed.
357 *
358 * Results:
359 *	None
360 *
361 * Side Effects:
362 *	Only those that come from the various arguments.
363 */
364void
365Main_ParseArgLine(line)
366	char *line;			/* Line to fracture */
367{
368	char **argv;			/* Manufactured argument vector */
369	int argc;			/* Number of arguments in argv */
370
371	if (line == NULL)
372		return;
373	for (; *line == ' '; ++line)
374		continue;
375	if (!*line)
376		return;
377
378	argv = brk_string(line, &argc, TRUE);
379	MainParseArgs(argc, argv);
380}
381
382char *
383chdir_verify_path(path, obpath)
384	char *path;
385	char *obpath;
386{
387	struct stat sb;
388
389	if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
390		if (chdir(path)) {
391			warn("warning: %s", path);
392			return 0;
393		}
394		else {
395			if (path[0] != '/') {
396				(void) snprintf(obpath, MAXPATHLEN, "%s/%s",
397						curdir, path);
398				return obpath;
399			}
400			else
401				return path;
402		}
403	}
404
405	return 0;
406}
407
408
409/*-
410 * main --
411 *	The main function, for obvious reasons. Initializes variables
412 *	and a few modules, then parses the arguments give it in the
413 *	environment and on the command line. Reads the system makefile
414 *	followed by either Makefile, makefile or the file given by the
415 *	-f argument. Sets the .MAKEFLAGS PMake variable based on all the
416 *	flags it has received by then uses either the Make or the Compat
417 *	module to create the initial list of targets.
418 *
419 * Results:
420 *	If -q was given, exits -1 if anything was out-of-date. Else it exits
421 *	0.
422 *
423 * Side Effects:
424 *	The program exits when done. Targets are created. etc. etc. etc.
425 */
426int
427main(argc, argv)
428	int argc;
429	char **argv;
430{
431	Lst targs;	/* target nodes to create -- passed to Make_Init */
432	Boolean outOfDate = TRUE; 	/* FALSE if all targets up to date */
433	struct stat sb, sa;
434	char *p, *p1, *path, *pathp, *pwd;
435	char mdpath[MAXPATHLEN + 1];
436	char obpath[MAXPATHLEN + 1];
437	char cdpath[MAXPATHLEN + 1];
438    	char *machine = getenv("MACHINE");
439	Lst sysMkPath;			/* Path of sys.mk */
440	char *cp = NULL, *start;
441					/* avoid faults on read-only strings */
442	static char syspath[] = _PATH_DEFSYSPATH;
443
444#ifdef RLIMIT_NOFILE
445	/*
446	 * get rid of resource limit on file descriptors
447	 */
448	{
449		struct rlimit rl;
450		if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
451		    rl.rlim_cur != rl.rlim_max) {
452			rl.rlim_cur = rl.rlim_max;
453			(void) setrlimit(RLIMIT_NOFILE, &rl);
454		}
455	}
456#endif
457	/*
458	 * Find where we are and take care of PWD for the automounter...
459	 * All this code is so that we know where we are when we start up
460	 * on a different machine with pmake.
461	 */
462	curdir = cdpath;
463	if (getcwd(curdir, MAXPATHLEN) == NULL)
464		err(2, NULL);
465
466	if (stat(curdir, &sa) == -1)
467	    err(2, "%s", curdir);
468
469	if ((pwd = getenv("PWD")) != NULL) {
470	    if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
471		sa.st_dev == sb.st_dev)
472		(void) strcpy(curdir, pwd);
473	}
474
475	/*
476	 * Get the name of this type of MACHINE from utsname
477	 * so we can share an executable for similar machines.
478	 * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
479	 *
480	 * Note that while MACHINE is decided at run-time,
481	 * MACHINE_ARCH is always known at compile time.
482	 */
483	if (!machine) {
484#ifndef MACHINE
485	    struct utsname utsname;
486
487	    if (uname(&utsname) == -1) {
488		    perror("make: uname");
489		    exit(2);
490	    }
491	    machine = utsname.machine;
492#else
493	    machine = MACHINE;
494#endif
495	}
496
497	/*
498	 * The object directory location is determined using the
499	 * following order of preference:
500	 *
501	 *	1. MAKEOBJDIRPREFIX`cwd`
502	 *	2. MAKEOBJDIR
503	 *	3. _PATH_OBJDIR.${MACHINE}
504	 *	4. _PATH_OBJDIR
505	 *	5. _PATH_OBJDIRPREFIX${MACHINE}
506	 *
507	 * If all fails, use the current directory to build.
508	 *
509	 * Once things are initted,
510	 * have to add the original directory to the search path,
511	 * and modify the paths for the Makefiles apropriately.  The
512	 * current directory is also placed as a variable for make scripts.
513	 */
514	if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
515		if (!(path = getenv("MAKEOBJDIR"))) {
516			path = _PATH_OBJDIR;
517			pathp = _PATH_OBJDIRPREFIX;
518			(void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
519					path, machine);
520			if (!(objdir = chdir_verify_path(mdpath, obpath)))
521				if (!(objdir=chdir_verify_path(path, obpath))) {
522					(void) snprintf(mdpath, MAXPATHLEN,
523							"%s%s", pathp, curdir);
524					if (!(objdir=chdir_verify_path(mdpath,
525								       obpath)))
526						objdir = curdir;
527				}
528		}
529		else if (!(objdir = chdir_verify_path(path, obpath)))
530			objdir = curdir;
531	}
532	else {
533		(void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
534		if (!(objdir = chdir_verify_path(mdpath, obpath)))
535			objdir = curdir;
536	}
537
538	setenv("PWD", objdir, 1);
539
540	create = Lst_Init(FALSE);
541	makefiles = Lst_Init(FALSE);
542	printVars = FALSE;
543	variables = Lst_Init(FALSE);
544	beSilent = FALSE;		/* Print commands as executed */
545	ignoreErrors = FALSE;		/* Pay attention to non-zero returns */
546	noExecute = FALSE;		/* Execute all commands */
547	keepgoing = FALSE;		/* Stop on error */
548	allPrecious = FALSE;		/* Remove targets when interrupted */
549	queryFlag = FALSE;		/* This is not just a check-run */
550	noBuiltins = FALSE;		/* Read the built-in rules */
551	touchFlag = FALSE;		/* Actually update targets */
552	usePipes = TRUE;		/* Catch child output in pipes */
553	debug = 0;			/* No debug verbosity, please. */
554	jobsRunning = FALSE;
555
556	maxLocal = DEFMAXLOCAL;		/* Set default local max concurrency */
557#ifdef REMOTE
558	maxJobs = DEFMAXJOBS;		/* Set default max concurrency */
559#else
560	maxJobs = maxLocal;
561#endif
562	compatMake = FALSE;		/* No compat mode */
563
564
565	/*
566	 * Initialize the parsing, directory and variable modules to prepare
567	 * for the reading of inclusion paths and variable settings on the
568	 * command line
569	 */
570	Dir_Init();		/* Initialize directory structures so -I flags
571				 * can be processed correctly */
572	Parse_Init();		/* Need to initialize the paths of #include
573				 * directories */
574	Var_Init();		/* As well as the lists of variables for
575				 * parsing arguments */
576        str_init();
577	if (objdir != curdir)
578		Dir_AddDir(dirSearchPath, curdir);
579	Var_Set(".CURDIR", curdir, VAR_GLOBAL);
580	Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
581
582	/*
583	 * Initialize various variables.
584	 *	MAKE also gets this name, for compatibility
585	 *	.MAKEFLAGS gets set to the empty string just in case.
586	 *	MFLAGS also gets initialized empty, for compatibility.
587	 */
588	Var_Set("MAKE", argv[0], VAR_GLOBAL);
589	Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
590	Var_Set("MFLAGS", "", VAR_GLOBAL);
591	Var_Set("MACHINE", machine, VAR_GLOBAL);
592#ifdef MACHINE_ARCH
593	Var_Set("MACHINE_ARCH", MACHINE_ARCH, VAR_GLOBAL);
594#endif
595
596	/*
597	 * First snag any flags out of the MAKE environment variable.
598	 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
599	 * in a different format).
600	 */
601#ifdef POSIX
602	Main_ParseArgLine(getenv("MAKEFLAGS"));
603#else
604	Main_ParseArgLine(getenv("MAKE"));
605#endif
606
607	MainParseArgs(argc, argv);
608
609	/*
610	 * Initialize archive, target and suffix modules in preparation for
611	 * parsing the makefile(s)
612	 */
613	Arch_Init();
614	Targ_Init();
615	Suff_Init();
616
617	DEFAULT = NILGNODE;
618	(void)time(&now);
619
620	/*
621	 * Set up the .TARGETS variable to contain the list of targets to be
622	 * created. If none specified, make the variable empty -- the parser
623	 * will fill the thing in with the default or .MAIN target.
624	 */
625	if (!Lst_IsEmpty(create)) {
626		LstNode ln;
627
628		for (ln = Lst_First(create); ln != NILLNODE;
629		    ln = Lst_Succ(ln)) {
630			char *name = (char *)Lst_Datum(ln);
631
632			Var_Append(".TARGETS", name, VAR_GLOBAL);
633		}
634	} else
635		Var_Set(".TARGETS", "", VAR_GLOBAL);
636
637
638	/*
639	 * If no user-supplied system path was given (through the -m option)
640	 * add the directories from the DEFSYSPATH (more than one may be given
641	 * as dir1:...:dirn) to the system include path.
642	 */
643	if (Lst_IsEmpty(sysIncPath)) {
644		for (start = syspath; *start != '\0'; start = cp) {
645			for (cp = start; *cp != '\0' && *cp != ':'; cp++)
646				continue;
647			if (*cp == '\0') {
648				Dir_AddDir(sysIncPath, start);
649			} else {
650				*cp++ = '\0';
651				Dir_AddDir(sysIncPath, start);
652			}
653		}
654	}
655
656	/*
657	 * Read in the built-in rules first, followed by the specified
658	 * makefile, if it was (makefile != (char *) NULL), or the default
659	 * Makefile and makefile, in that order, if it wasn't.
660	 */
661	if (!noBuiltins) {
662		LstNode ln;
663
664		sysMkPath = Lst_Init (FALSE);
665		Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
666		if (Lst_IsEmpty(sysMkPath))
667			Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
668		ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
669		if (ln != NILLNODE)
670			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
671	}
672
673	if (!Lst_IsEmpty(makefiles)) {
674		LstNode ln;
675
676		ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
677		if (ln != NILLNODE)
678			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
679	} else if (!ReadMakefile("makefile", NULL))
680		(void)ReadMakefile("Makefile", NULL);
681
682	(void)ReadMakefile(".depend", NULL);
683
684	Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
685	if (p1)
686	    free(p1);
687
688	/* Install all the flags into the MAKE envariable. */
689	if (((p = Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1)) != NULL) && *p)
690#ifdef POSIX
691		setenv("MAKEFLAGS", p, 1);
692#else
693		setenv("MAKE", p, 1);
694#endif
695	if (p1)
696	    free(p1);
697
698	/*
699	 * For compatibility, look at the directories in the VPATH variable
700	 * and add them to the search path, if the variable is defined. The
701	 * variable's value is in the same format as the PATH envariable, i.e.
702	 * <directory>:<directory>:<directory>...
703	 */
704	if (Var_Exists("VPATH", VAR_CMD)) {
705		char *vpath, *path, *cp, savec;
706		/*
707		 * GCC stores string constants in read-only memory, but
708		 * Var_Subst will want to write this thing, so store it
709		 * in an array
710		 */
711		static char VPATH[] = "${VPATH}";
712
713		vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
714		path = vpath;
715		do {
716			/* skip to end of directory */
717			for (cp = path; *cp != ':' && *cp != '\0'; cp++)
718				continue;
719			/* Save terminator character so know when to stop */
720			savec = *cp;
721			*cp = '\0';
722			/* Add directory to search path */
723			Dir_AddDir(dirSearchPath, path);
724			*cp = savec;
725			path = cp + 1;
726		} while (savec == ':');
727		(void)free((Address)vpath);
728	}
729
730	/*
731	 * Now that all search paths have been read for suffixes et al, it's
732	 * time to add the default search path to their lists...
733	 */
734	Suff_DoPaths();
735
736	/* print the initial graph, if the user requested it */
737	if (DEBUG(GRAPH1))
738		Targ_PrintGraph(1);
739
740	/* print the values of any variables requested by the user */
741	if (printVars) {
742		LstNode ln;
743
744		for (ln = Lst_First(variables); ln != NILLNODE;
745		    ln = Lst_Succ(ln)) {
746			char *value = Var_Value((char *)Lst_Datum(ln),
747					  VAR_GLOBAL, &p1);
748
749			printf("%s\n", value ? value : "");
750			if (p1)
751				free(p1);
752		}
753	}
754
755	/*
756	 * Have now read the entire graph and need to make a list of targets
757	 * to create. If none was given on the command line, we consult the
758	 * parsing module to find the main target(s) to create.
759	 */
760	if (Lst_IsEmpty(create))
761		targs = Parse_MainName();
762	else
763		targs = Targ_FindList(create, TARG_CREATE);
764
765	if (!compatMake && !printVars) {
766		/*
767		 * Initialize job module before traversing the graph, now that
768		 * any .BEGIN and .END targets have been read.  This is done
769		 * only if the -q flag wasn't given (to prevent the .BEGIN from
770		 * being executed should it exist).
771		 */
772		if (!queryFlag) {
773			if (maxLocal == -1)
774				maxLocal = maxJobs;
775			Job_Init(maxJobs, maxLocal);
776			jobsRunning = TRUE;
777		}
778
779		/* Traverse the graph, checking on all the targets */
780		outOfDate = Make_Run(targs);
781	} else if (!printVars) {
782		/*
783		 * Compat_Init will take care of creating all the targets as
784		 * well as initializing the module.
785		 */
786		Compat_Run(targs);
787	}
788
789	Lst_Destroy(targs, NOFREE);
790	Lst_Destroy(variables, NOFREE);
791	Lst_Destroy(makefiles, NOFREE);
792	Lst_Destroy(create, (void (*) __P((ClientData))) free);
793
794	/* print the graph now it's been processed if the user requested it */
795	if (DEBUG(GRAPH2))
796		Targ_PrintGraph(2);
797
798	Suff_End();
799        Targ_End();
800	Arch_End();
801	str_end();
802	Var_End();
803	Parse_End();
804	Dir_End();
805
806	if (queryFlag && outOfDate)
807		return(1);
808	else
809		return(0);
810}
811
812/*-
813 * ReadMakefile  --
814 *	Open and parse the given makefile.
815 *
816 * Results:
817 *	TRUE if ok. FALSE if couldn't open file.
818 *
819 * Side Effects:
820 *	lots
821 */
822static Boolean
823ReadMakefile(p, q)
824	ClientData p, q;
825{
826	char *fname = p;		/* makefile to read */
827	extern Lst parseIncPath;
828	FILE *stream;
829	char *name, path[MAXPATHLEN + 1];
830
831	if (!strcmp(fname, "-")) {
832		Parse_File("(stdin)", stdin);
833		Var_Set("MAKEFILE", "", VAR_GLOBAL);
834	} else {
835		if ((stream = fopen(fname, "r")) != NULL)
836			goto found;
837		/* if we've chdir'd, rebuild the path name */
838		if (curdir != objdir && *fname != '/') {
839			(void)sprintf(path, "%s/%s", curdir, fname);
840			if ((stream = fopen(path, "r")) != NULL) {
841				fname = path;
842				goto found;
843			}
844		}
845		/* look in -I and system include directories. */
846		name = Dir_FindFile(fname, parseIncPath);
847		if (!name)
848			name = Dir_FindFile(fname, sysIncPath);
849		if (!name || !(stream = fopen(name, "r")))
850			return(FALSE);
851		fname = name;
852		/*
853		 * set the MAKEFILE variable desired by System V fans -- the
854		 * placement of the setting here means it gets set to the last
855		 * makefile specified, as it is set by SysV make.
856		 */
857found:		Var_Set("MAKEFILE", fname, VAR_GLOBAL);
858		Parse_File(fname, stream);
859		(void)fclose(stream);
860	}
861	return(TRUE);
862}
863
864/*-
865 * Cmd_Exec --
866 *	Execute the command in cmd, and return the output of that command
867 *	in a string.
868 *
869 * Results:
870 *	A string containing the output of the command, or the empty string
871 *	If err is not NULL, it contains the reason for the command failure
872 *
873 * Side Effects:
874 *	The string must be freed by the caller.
875 */
876char *
877Cmd_Exec(cmd, err)
878    char *cmd;
879    char **err;
880{
881    char	*args[4];   	/* Args for invoking the shell */
882    int 	fds[2];	    	/* Pipe streams */
883    int 	cpid;	    	/* Child PID */
884    int 	pid;	    	/* PID from wait() */
885    char	*res;		/* result */
886    int		status;		/* command exit status */
887    Buffer	buf;		/* buffer to store the result */
888    char	*cp;
889    int		cc;
890
891
892    *err = NULL;
893
894    /*
895     * Set up arguments for shell
896     */
897    args[0] = "sh";
898    args[1] = "-c";
899    args[2] = cmd;
900    args[3] = NULL;
901
902    /*
903     * Open a pipe for fetching its output
904     */
905    if (pipe(fds) == -1) {
906	*err = "Couldn't create pipe for \"%s\"";
907	goto bad;
908    }
909
910    /*
911     * Fork
912     */
913    switch (cpid = vfork()) {
914    case 0:
915	/*
916	 * Close input side of pipe
917	 */
918	(void) close(fds[0]);
919
920	/*
921	 * Duplicate the output stream to the shell's output, then
922	 * shut the extra thing down. Note we don't fetch the error
923	 * stream...why not? Why?
924	 */
925	(void) dup2(fds[1], 1);
926	(void) close(fds[1]);
927
928	(void) execv("/bin/sh", args);
929	_exit(1);
930	/*NOTREACHED*/
931
932    case -1:
933	*err = "Couldn't exec \"%s\"";
934	goto bad;
935
936    default:
937	/*
938	 * No need for the writing half
939	 */
940	(void) close(fds[1]);
941
942	buf = Buf_Init (MAKE_BSIZE);
943
944	do {
945	    char   result[BUFSIZ];
946	    cc = read(fds[0], result, sizeof(result));
947	    if (cc > 0)
948		Buf_AddBytes(buf, cc, (Byte *) result);
949	}
950	while (cc > 0 || (cc == -1 && errno == EINTR));
951
952	/*
953	 * Close the input side of the pipe.
954	 */
955	(void) close(fds[0]);
956
957	/*
958	 * Wait for the process to exit.
959	 */
960	while(((pid = wait(&status)) != cpid) && (pid >= 0))
961	    continue;
962
963	if (cc == -1)
964	    *err = "Error reading shell's output for \"%s\"";
965
966	res = (char *)Buf_GetAll (buf, &cc);
967	Buf_Destroy (buf, FALSE);
968
969	if (status)
970	    *err = "\"%s\" returned non-zero status";
971
972	/*
973	 * Null-terminate the result, convert newlines to spaces and
974	 * install it in the variable.
975	 */
976	res[cc] = '\0';
977	cp = &res[cc] - 1;
978
979	if (*cp == '\n') {
980	    /*
981	     * A final newline is just stripped
982	     */
983	    *cp-- = '\0';
984	}
985	while (cp >= res) {
986	    if (*cp == '\n') {
987		*cp = ' ';
988	    }
989	    cp--;
990	}
991	break;
992    }
993    return res;
994bad:
995    res = emalloc(1);
996    *res = '\0';
997    return res;
998}
999
1000/*-
1001 * Error --
1002 *	Print an error message given its format.
1003 *
1004 * Results:
1005 *	None.
1006 *
1007 * Side Effects:
1008 *	The message is printed.
1009 */
1010/* VARARGS */
1011void
1012#if __STDC__
1013Error(char *fmt, ...)
1014#else
1015Error(va_alist)
1016	va_dcl
1017#endif
1018{
1019	va_list ap;
1020#if __STDC__
1021	va_start(ap, fmt);
1022#else
1023	char *fmt;
1024
1025	va_start(ap);
1026	fmt = va_arg(ap, char *);
1027#endif
1028	(void)vfprintf(stderr, fmt, ap);
1029	va_end(ap);
1030	(void)fprintf(stderr, "\n");
1031	(void)fflush(stderr);
1032}
1033
1034/*-
1035 * Fatal --
1036 *	Produce a Fatal error message. If jobs are running, waits for them
1037 *	to finish.
1038 *
1039 * Results:
1040 *	None
1041 *
1042 * Side Effects:
1043 *	The program exits
1044 */
1045/* VARARGS */
1046void
1047#if __STDC__
1048Fatal(char *fmt, ...)
1049#else
1050Fatal(va_alist)
1051	va_dcl
1052#endif
1053{
1054	va_list ap;
1055#if __STDC__
1056	va_start(ap, fmt);
1057#else
1058	char *fmt;
1059
1060	va_start(ap);
1061	fmt = va_arg(ap, char *);
1062#endif
1063	if (jobsRunning)
1064		Job_Wait();
1065
1066	(void)vfprintf(stderr, fmt, ap);
1067	va_end(ap);
1068	(void)fprintf(stderr, "\n");
1069	(void)fflush(stderr);
1070
1071	if (DEBUG(GRAPH2))
1072		Targ_PrintGraph(2);
1073	exit(2);		/* Not 1 so -q can distinguish error */
1074}
1075
1076/*
1077 * Punt --
1078 *	Major exception once jobs are being created. Kills all jobs, prints
1079 *	a message and exits.
1080 *
1081 * Results:
1082 *	None
1083 *
1084 * Side Effects:
1085 *	All children are killed indiscriminately and the program Lib_Exits
1086 */
1087/* VARARGS */
1088void
1089#if __STDC__
1090Punt(char *fmt, ...)
1091#else
1092Punt(va_alist)
1093	va_dcl
1094#endif
1095{
1096	va_list ap;
1097#if __STDC__
1098	va_start(ap, fmt);
1099#else
1100	char *fmt;
1101
1102	va_start(ap);
1103	fmt = va_arg(ap, char *);
1104#endif
1105
1106	(void)fprintf(stderr, "make: ");
1107	(void)vfprintf(stderr, fmt, ap);
1108	va_end(ap);
1109	(void)fprintf(stderr, "\n");
1110	(void)fflush(stderr);
1111
1112	DieHorribly();
1113}
1114
1115/*-
1116 * DieHorribly --
1117 *	Exit without giving a message.
1118 *
1119 * Results:
1120 *	None
1121 *
1122 * Side Effects:
1123 *	A big one...
1124 */
1125void
1126DieHorribly()
1127{
1128	if (jobsRunning)
1129		Job_AbortAll();
1130	if (DEBUG(GRAPH2))
1131		Targ_PrintGraph(2);
1132	exit(2);		/* Not 1, so -q can distinguish error */
1133}
1134
1135/*
1136 * Finish --
1137 *	Called when aborting due to errors in child shell to signal
1138 *	abnormal exit.
1139 *
1140 * Results:
1141 *	None
1142 *
1143 * Side Effects:
1144 *	The program exits
1145 */
1146void
1147Finish(errors)
1148	int errors;	/* number of errors encountered in Make_Make */
1149{
1150	Fatal("%d error%s", errors, errors == 1 ? "" : "s");
1151}
1152
1153/*
1154 * emalloc --
1155 *	malloc, but die on error.
1156 */
1157void *
1158emalloc(len)
1159	size_t len;
1160{
1161	void *p;
1162
1163	if ((p = malloc(len)) == NULL)
1164		enomem();
1165	return(p);
1166}
1167
1168/*
1169 * estrdup --
1170 *	strdup, but die on error.
1171 */
1172char *
1173estrdup(str)
1174	const char *str;
1175{
1176	char *p;
1177
1178	if ((p = strdup(str)) == NULL)
1179		enomem();
1180	return(p);
1181}
1182
1183/*
1184 * erealloc --
1185 *	realloc, but die on error.
1186 */
1187void *
1188erealloc(ptr, size)
1189	void *ptr;
1190	size_t size;
1191{
1192	if ((ptr = realloc(ptr, size)) == NULL)
1193		enomem();
1194	return(ptr);
1195}
1196
1197/*
1198 * enomem --
1199 *	die when out of memory.
1200 */
1201void
1202enomem()
1203{
1204	err(2, NULL);
1205}
1206
1207/*
1208 * enunlink --
1209 *	Remove a file carefully, avoiding directories.
1210 */
1211int
1212eunlink(file)
1213	const char *file;
1214{
1215	struct stat st;
1216
1217	if (lstat(file, &st) == -1)
1218		return -1;
1219
1220	if (S_ISDIR(st.st_mode)) {
1221		errno = EISDIR;
1222		return -1;
1223	}
1224	return unlink(file);
1225}
1226
1227/*
1228 * usage --
1229 *	exit with usage message
1230 */
1231static void
1232usage()
1233{
1234	(void)fprintf(stderr, "%s\n%s\n%s\n",
1235"usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]",
1236"            [-I directory] [-j max_jobs] [-m directory] [-V variable]",
1237"            [variable=value] [target ...]");
1238	exit(2);
1239}
1240
1241
1242int
1243PrintAddr(a, b)
1244    ClientData a;
1245    ClientData b;
1246{
1247    printf("%lx ", (unsigned long) a);
1248    return b ? 0 : 0;
1249}
1250