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