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