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