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