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