1 /* $NetBSD: main.c,v 1.79 2001/11/12 21:58:18 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.79 2001/11/12 21:58:18 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.79 2001/11/12 21:58:18 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 = FALSE; 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 Dir_InitDot(); 486 rc = TRUE; 487 } 488 } 489 490 if (p) 491 free(p); 492 return rc; 493 } 494 495 496 /*- 497 * main -- 498 * The main function, for obvious reasons. Initializes variables 499 * and a few modules, then parses the arguments give it in the 500 * environment and on the command line. Reads the system makefile 501 * followed by either Makefile, makefile or the file given by the 502 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the 503 * flags it has received by then uses either the Make or the Compat 504 * module to create the initial list of targets. 505 * 506 * Results: 507 * If -q was given, exits -1 if anything was out-of-date. Else it exits 508 * 0. 509 * 510 * Side Effects: 511 * The program exits when done. Targets are created. etc. etc. etc. 512 */ 513 int 514 main(argc, argv) 515 int argc; 516 char **argv; 517 { 518 Lst targs; /* target nodes to create -- passed to Make_Init */ 519 Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ 520 struct stat sb, sa; 521 char *p1, *path, *pwd; 522 char mdpath[MAXPATHLEN]; 523 char *machine = getenv("MACHINE"); 524 char *machine_arch = getenv("MACHINE_ARCH"); 525 char *syspath = getenv("MAKESYSPATH"); 526 Lst sysMkPath; /* Path of sys.mk */ 527 char *cp = NULL, *start; 528 /* avoid faults on read-only strings */ 529 static char defsyspath[] = _PATH_DEFSYSPATH; 530 531 if ((progname = strrchr(argv[0], '/')) != NULL) 532 progname++; 533 else 534 progname = argv[0]; 535 #ifdef RLIMIT_NOFILE 536 /* 537 * get rid of resource limit on file descriptors 538 */ 539 { 540 struct rlimit rl; 541 if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && 542 rl.rlim_cur != rl.rlim_max) { 543 rl.rlim_cur = rl.rlim_max; 544 (void) setrlimit(RLIMIT_NOFILE, &rl); 545 } 546 } 547 #endif 548 /* 549 * Find where we are and take care of PWD for the automounter... 550 * All this code is so that we know where we are when we start up 551 * on a different machine with pmake. 552 */ 553 if (getcwd(curdir, MAXPATHLEN) == NULL) { 554 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); 555 exit(2); 556 } 557 558 if (stat(curdir, &sa) == -1) { 559 (void)fprintf(stderr, "%s: %s: %s.\n", 560 progname, curdir, strerror(errno)); 561 exit(2); 562 } 563 564 /* 565 * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX 566 * since the value of curdir can very depending on how we got 567 * here. Ie sitting at a shell prompt (shell that provides $PWD) 568 * or via subdir.mk in which case its likely a shell which does 569 * not provide it. 570 * So, to stop it breaking this case only, we ignore PWD if 571 * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform. 572 */ 573 if ((pwd = getenv("PWD")) != NULL && getenv("MAKEOBJDIRPREFIX") == NULL) { 574 const char *makeobjdir = getenv("MAKEOBJDIR"); 575 576 if (makeobjdir == NULL || !strchr(makeobjdir, '$')) { 577 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && 578 sa.st_dev == sb.st_dev) 579 (void) strncpy(curdir, pwd, MAXPATHLEN); 580 } 581 } 582 583 /* 584 * Get the name of this type of MACHINE from utsname 585 * so we can share an executable for similar machines. 586 * (i.e. m68k: amiga hp300, mac68k, sun3, ...) 587 * 588 * Note that both MACHINE and MACHINE_ARCH are decided at 589 * run-time. 590 */ 591 if (!machine) { 592 #ifndef MAKE_BOOTSTRAP 593 struct utsname utsname; 594 595 if (uname(&utsname) == -1) { 596 (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, 597 strerror(errno)); 598 exit(2); 599 } 600 machine = utsname.machine; 601 #else 602 machine = MACHINE; 603 #endif 604 } 605 606 if (!machine_arch) { 607 #ifndef MACHINE_ARCH 608 #ifdef __ARCHITECTURE__ 609 machine_arch = __ARCHITECTURE__; 610 #else 611 machine_arch = "unknown"; /* XXX: no uname -p yet */ 612 #endif 613 #else 614 machine_arch = MACHINE_ARCH; 615 #endif 616 } 617 618 /* 619 * Just in case MAKEOBJDIR wants us to do something tricky. 620 */ 621 Var_Init(); /* Initialize the lists of variables for 622 * parsing arguments */ 623 Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0); 624 Var_Set("MACHINE", machine, VAR_GLOBAL, 0); 625 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); 626 #ifdef MAKE_VERSION 627 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0); 628 #endif 629 Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */ 630 631 /* 632 * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that, 633 * MAKEOBJDIR is set in the environment, try only that value 634 * and fall back to .CURDIR if it does not exist. 635 * 636 * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and 637 * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none 638 * of these paths exist, just use .CURDIR. 639 */ 640 Dir_Init(curdir); 641 (void) Main_SetObjdir(curdir); 642 643 if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) { 644 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir); 645 (void) Main_SetObjdir(mdpath); 646 } else if ((path = getenv("MAKEOBJDIR")) != NULL) { 647 (void) Main_SetObjdir(path); 648 } else { 649 (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine); 650 if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) { 651 (void) snprintf(mdpath, MAXPATHLEN, "%s%s", 652 _PATH_OBJDIRPREFIX, curdir); 653 (void) Main_SetObjdir(mdpath); 654 } 655 } 656 657 create = Lst_Init(FALSE); 658 makefiles = Lst_Init(FALSE); 659 printVars = FALSE; 660 variables = Lst_Init(FALSE); 661 beSilent = FALSE; /* Print commands as executed */ 662 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 663 noExecute = FALSE; /* Execute all commands */ 664 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */ 665 keepgoing = FALSE; /* Stop on error */ 666 allPrecious = FALSE; /* Remove targets when interrupted */ 667 queryFlag = FALSE; /* This is not just a check-run */ 668 noBuiltins = FALSE; /* Read the built-in rules */ 669 touchFlag = FALSE; /* Actually update targets */ 670 usePipes = TRUE; /* Catch child output in pipes */ 671 debug = 0; /* No debug verbosity, please. */ 672 jobsRunning = FALSE; 673 674 maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */ 675 #ifdef REMOTE 676 maxJobs = DEFMAXJOBS; /* Set default max concurrency */ 677 #else 678 maxJobs = maxLocal; 679 #endif 680 compatMake = FALSE; /* No compat mode */ 681 682 683 /* 684 * Initialize the parsing, directory and variable modules to prepare 685 * for the reading of inclusion paths and variable settings on the 686 * command line 687 */ 688 689 /* 690 * Initialize various variables. 691 * MAKE also gets this name, for compatibility 692 * .MAKEFLAGS gets set to the empty string just in case. 693 * MFLAGS also gets initialized empty, for compatibility. 694 */ 695 Parse_Init(); 696 Var_Set("MAKE", argv[0], VAR_GLOBAL, 0); 697 Var_Set(".MAKE", argv[0], VAR_GLOBAL, 0); 698 Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0); 699 Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0); 700 Var_Set("MFLAGS", "", VAR_GLOBAL, 0); 701 Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0); 702 703 /* 704 * First snag any flags out of the MAKE environment variable. 705 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's 706 * in a different format). 707 */ 708 #ifdef POSIX 709 Main_ParseArgLine(getenv("MAKEFLAGS")); 710 #else 711 Main_ParseArgLine(getenv("MAKE")); 712 #endif 713 714 MainParseArgs(argc, argv); 715 716 /* 717 * Be compatible if user did not specify -j and did not explicitly 718 * turned compatibility on 719 */ 720 if (!compatMake && !forceJobs) { 721 compatMake = TRUE; 722 } 723 724 /* 725 * Initialize archive, target and suffix modules in preparation for 726 * parsing the makefile(s) 727 */ 728 Arch_Init(); 729 Targ_Init(); 730 Suff_Init(); 731 Trace_Init(tracefile); 732 733 DEFAULT = NILGNODE; 734 (void)time(&now); 735 736 Trace_Log(MAKESTART, NULL); 737 738 /* 739 * Set up the .TARGETS variable to contain the list of targets to be 740 * created. If none specified, make the variable empty -- the parser 741 * will fill the thing in with the default or .MAIN target. 742 */ 743 if (!Lst_IsEmpty(create)) { 744 LstNode ln; 745 746 for (ln = Lst_First(create); ln != NILLNODE; 747 ln = Lst_Succ(ln)) { 748 char *name = (char *)Lst_Datum(ln); 749 750 Var_Append(".TARGETS", name, VAR_GLOBAL); 751 } 752 } else 753 Var_Set(".TARGETS", "", VAR_GLOBAL, 0); 754 755 756 /* 757 * If no user-supplied system path was given (through the -m option) 758 * add the directories from the DEFSYSPATH (more than one may be given 759 * as dir1:...:dirn) to the system include path. 760 */ 761 if (syspath == NULL || *syspath == '\0') 762 syspath = defsyspath; 763 else 764 syspath = strdup(syspath); 765 766 for (start = syspath; *start != '\0'; start = cp) { 767 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 768 continue; 769 if (*cp == '\0') { 770 (void) Dir_AddDir(defIncPath, start); 771 } else { 772 *cp++ = '\0'; 773 (void) Dir_AddDir(defIncPath, start); 774 } 775 } 776 if (syspath != defsyspath) 777 free(syspath); 778 779 /* 780 * Read in the built-in rules first, followed by the specified 781 * makefile, if it was (makefile != (char *) NULL), or the default 782 * Makefile and makefile, in that order, if it wasn't. 783 */ 784 if (!noBuiltins) { 785 LstNode ln; 786 787 sysMkPath = Lst_Init (FALSE); 788 Dir_Expand(_PATH_DEFSYSMK, 789 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath, 790 sysMkPath); 791 if (Lst_IsEmpty(sysMkPath)) 792 Fatal("%s: no system rules (%s).", progname, 793 _PATH_DEFSYSMK); 794 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile); 795 if (ln != NILLNODE) 796 Fatal("%s: cannot open %s.", progname, 797 (char *)Lst_Datum(ln)); 798 } 799 800 if (!Lst_IsEmpty(makefiles)) { 801 LstNode ln; 802 803 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile); 804 if (ln != NILLNODE) 805 Fatal("%s: cannot open %s.", progname, 806 (char *)Lst_Datum(ln)); 807 } else if (!ReadMakefile("makefile", NULL)) 808 (void)ReadMakefile("Makefile", NULL); 809 810 (void)ReadMakefile(".depend", NULL); 811 812 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); 813 if (p1) 814 free(p1); 815 816 if (!jobServer && !compatMake) 817 Job_ServerStart(maxJobs); 818 if (DEBUG(JOB)) 819 printf("job_pipe %d %d, maxjobs %d maxlocal %d compat %d\n", job_pipe[0], job_pipe[1], maxJobs, 820 maxLocal, compatMake); 821 822 Main_ExportMAKEFLAGS(TRUE); /* initial export */ 823 824 Check_Cwd_av(0, NULL, 0); /* initialize it */ 825 826 827 /* 828 * For compatibility, look at the directories in the VPATH variable 829 * and add them to the search path, if the variable is defined. The 830 * variable's value is in the same format as the PATH envariable, i.e. 831 * <directory>:<directory>:<directory>... 832 */ 833 if (Var_Exists("VPATH", VAR_CMD)) { 834 char *vpath, *path, *cp, savec; 835 /* 836 * GCC stores string constants in read-only memory, but 837 * Var_Subst will want to write this thing, so store it 838 * in an array 839 */ 840 static char VPATH[] = "${VPATH}"; 841 842 vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); 843 path = vpath; 844 do { 845 /* skip to end of directory */ 846 for (cp = path; *cp != ':' && *cp != '\0'; cp++) 847 continue; 848 /* Save terminator character so know when to stop */ 849 savec = *cp; 850 *cp = '\0'; 851 /* Add directory to search path */ 852 (void) Dir_AddDir(dirSearchPath, path); 853 *cp = savec; 854 path = cp + 1; 855 } while (savec == ':'); 856 (void)free((Address)vpath); 857 } 858 859 /* 860 * Now that all search paths have been read for suffixes et al, it's 861 * time to add the default search path to their lists... 862 */ 863 Suff_DoPaths(); 864 865 /* 866 * Propagate attributes through :: dependency lists. 867 */ 868 Targ_Propagate(); 869 870 /* print the initial graph, if the user requested it */ 871 if (DEBUG(GRAPH1)) 872 Targ_PrintGraph(1); 873 874 /* print the values of any variables requested by the user */ 875 if (printVars) { 876 LstNode ln; 877 878 for (ln = Lst_First(variables); ln != NILLNODE; 879 ln = Lst_Succ(ln)) { 880 char *value = Var_Value((char *)Lst_Datum(ln), 881 VAR_GLOBAL, &p1); 882 883 printf("%s\n", value ? value : ""); 884 if (p1) 885 free(p1); 886 } 887 } 888 889 /* 890 * Have now read the entire graph and need to make a list of targets 891 * to create. If none was given on the command line, we consult the 892 * parsing module to find the main target(s) to create. 893 */ 894 if (Lst_IsEmpty(create)) 895 targs = Parse_MainName(); 896 else 897 targs = Targ_FindList(create, TARG_CREATE); 898 899 if (!compatMake && !printVars) { 900 /* 901 * Initialize job module before traversing the graph, now that 902 * any .BEGIN and .END targets have been read. This is done 903 * only if the -q flag wasn't given (to prevent the .BEGIN from 904 * being executed should it exist). 905 */ 906 if (!queryFlag) { 907 if (maxLocal == -1) 908 maxLocal = maxJobs; 909 Job_Init(maxJobs, maxLocal); 910 jobsRunning = TRUE; 911 } 912 913 /* Traverse the graph, checking on all the targets */ 914 outOfDate = Make_Run(targs); 915 } else if (!printVars) { 916 /* 917 * Compat_Init will take care of creating all the targets as 918 * well as initializing the module. 919 */ 920 Compat_Run(targs); 921 } 922 923 #ifdef CLEANUP 924 Lst_Destroy(targs, NOFREE); 925 Lst_Destroy(variables, NOFREE); 926 Lst_Destroy(makefiles, NOFREE); 927 Lst_Destroy(create, (void (*) __P((ClientData))) free); 928 #endif 929 930 /* print the graph now it's been processed if the user requested it */ 931 if (DEBUG(GRAPH2)) 932 Targ_PrintGraph(2); 933 934 Trace_Log(MAKEEND, 0); 935 936 Suff_End(); 937 Targ_End(); 938 Arch_End(); 939 Var_End(); 940 Parse_End(); 941 Dir_End(); 942 Job_End(); 943 Trace_End(); 944 945 if (queryFlag && outOfDate) 946 return(1); 947 else 948 return(0); 949 } 950 951 /*- 952 * ReadMakefile -- 953 * Open and parse the given makefile. 954 * 955 * Results: 956 * TRUE if ok. FALSE if couldn't open file. 957 * 958 * Side Effects: 959 * lots 960 */ 961 static Boolean 962 ReadMakefile(p, q) 963 ClientData p, q; 964 { 965 char *fname = p; /* makefile to read */ 966 FILE *stream; 967 size_t len = MAXPATHLEN; 968 char *name, *path = emalloc(len); 969 int setMAKEFILE; 970 971 if (!strcmp(fname, "-")) { 972 Parse_File("(stdin)", stdin); 973 Var_Set("MAKEFILE", "", VAR_GLOBAL, 0); 974 } else { 975 setMAKEFILE = strcmp(fname, ".depend"); 976 977 /* if we've chdir'd, rebuild the path name */ 978 if (strcmp(curdir, objdir) && *fname != '/') { 979 size_t plen = strlen(curdir) + strlen(fname) + 2; 980 if (len < plen) 981 path = erealloc(path, len = 2 * plen); 982 983 (void)snprintf(path, len, "%s/%s", curdir, fname); 984 if ((stream = fopen(path, "r")) != NULL) { 985 fname = path; 986 goto found; 987 } 988 } else if ((stream = fopen(fname, "r")) != NULL) 989 goto found; 990 /* look in -I and system include directories. */ 991 name = Dir_FindFile(fname, parseIncPath); 992 if (!name) 993 name = Dir_FindFile(fname, 994 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); 995 if (!name || !(stream = fopen(name, "r"))) { 996 free(path); 997 return(FALSE); 998 } 999 fname = name; 1000 /* 1001 * set the MAKEFILE variable desired by System V fans -- the 1002 * placement of the setting here means it gets set to the last 1003 * makefile specified, as it is set by SysV make. 1004 */ 1005 found: 1006 if (setMAKEFILE) 1007 Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0); 1008 Parse_File(fname, stream); 1009 (void)fclose(stream); 1010 } 1011 free(path); 1012 return(TRUE); 1013 } 1014 1015 1016 /* 1017 * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR 1018 * in situations that would not arrise with ./obj (links or not). 1019 * This tends to break things like: 1020 * 1021 * build: 1022 * ${MAKE} includes 1023 * 1024 * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as 1025 * opposed to an argument) in a command line and if so returns 1026 * ${.CURDIR} so caller can chdir() so that the assumptions made by 1027 * the Makefile hold true. 1028 * 1029 * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped. 1030 * 1031 * The chdir() only happens in the child process, and does nothing if 1032 * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it 1033 * should not break anything. Also if NOCHECKMAKECHDIR is set we 1034 * do nothing - to ensure historic semantics can be retained. 1035 */ 1036 static int Check_Cwd_Off = 0; 1037 1038 static char * 1039 Check_Cwd_av(ac, av, copy) 1040 int ac; 1041 char **av; 1042 int copy; 1043 { 1044 static char *make[4]; 1045 static char *curdir = NULL; 1046 char *cp, **mp; 1047 int is_cmd, next_cmd; 1048 int i; 1049 int n; 1050 1051 if (Check_Cwd_Off) 1052 return NULL; 1053 1054 if (make[0] == NULL) { 1055 if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) { 1056 Check_Cwd_Off = 1; 1057 return NULL; 1058 } 1059 1060 make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp); 1061 if ((make[0] = strrchr(make[1], '/')) == NULL) { 1062 make[0] = make[1]; 1063 make[1] = NULL; 1064 } else 1065 ++make[0]; 1066 make[2] = NULL; 1067 curdir = Var_Value(".CURDIR", VAR_GLOBAL, &cp); 1068 } 1069 if (ac == 0 || av == NULL) 1070 return NULL; /* initialization only */ 1071 1072 if (getenv("MAKEOBJDIR") == NULL && 1073 getenv("MAKEOBJDIRPREFIX") == NULL) 1074 return NULL; 1075 1076 1077 next_cmd = 1; 1078 for (i = 0; i < ac; ++i) { 1079 is_cmd = next_cmd; 1080 1081 n = strlen(av[i]); 1082 cp = &(av[i])[n - 1]; 1083 if (strspn(av[i], "|&;") == n) { 1084 next_cmd = 1; 1085 continue; 1086 } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') { 1087 next_cmd = 1; 1088 if (copy) { 1089 do { 1090 *cp-- = '\0'; 1091 } while (*cp == ';' || *cp == '&' || *cp == '|' || 1092 *cp == ')' || *cp == '}') ; 1093 } else { 1094 /* 1095 * XXX this should not happen. 1096 */ 1097 fprintf(stderr, "WARNING: raw arg ends in shell meta '%s'\n", 1098 av[i]); 1099 } 1100 } else 1101 next_cmd = 0; 1102 1103 cp = av[i]; 1104 if (*cp == ';' || *cp == '&' || *cp == '|') 1105 is_cmd = 1; 1106 1107 #ifdef check_cwd_debug 1108 fprintf(stderr, "av[%d] == %s '%s'", 1109 i, (is_cmd) ? "cmd" : "arg", av[i]); 1110 #endif 1111 if (is_cmd != 0) { 1112 if (*cp == '(' || *cp == '{' || 1113 *cp == ';' || *cp == '&' || *cp == '|') { 1114 do { 1115 ++cp; 1116 } while (*cp == '(' || *cp == '{' || 1117 *cp == ';' || *cp == '&' || *cp == '|'); 1118 if (*cp == '\0') { 1119 next_cmd = 1; 1120 continue; 1121 } 1122 } 1123 if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) { 1124 #ifdef check_cwd_debug 1125 fprintf(stderr, " == cd, done.\n"); 1126 #endif 1127 return NULL; 1128 } 1129 for (mp = make; *mp != NULL; ++mp) { 1130 n = strlen(*mp); 1131 if (strcmp(cp, *mp) == 0) { 1132 #ifdef check_cwd_debug 1133 fprintf(stderr, " %s == '%s', chdir(%s)\n", 1134 cp, *mp, curdir); 1135 #endif 1136 return curdir; 1137 } 1138 } 1139 } 1140 #ifdef check_cwd_debug 1141 fprintf(stderr, "\n"); 1142 #endif 1143 } 1144 return NULL; 1145 } 1146 1147 char * 1148 Check_Cwd_Cmd(cmd) 1149 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(argv) 1178 char **argv; 1179 { 1180 char *cp; 1181 int ac; 1182 1183 if (Check_Cwd_Off) 1184 return; 1185 1186 for (ac = 0; argv[ac] != NULL; ++ac) 1187 /* NOTHING */; 1188 if (ac == 3 && *argv[1] == '-') { 1189 cp = Check_Cwd_Cmd(argv[2]); 1190 } else { 1191 cp = Check_Cwd_av(ac, argv, 0); 1192 } 1193 if (cp) { 1194 chdir(cp); 1195 } 1196 } 1197 1198 /*- 1199 * Cmd_Exec -- 1200 * Execute the command in cmd, and return the output of that command 1201 * in a string. 1202 * 1203 * Results: 1204 * A string containing the output of the command, or the empty string 1205 * If err is not NULL, it contains the reason for the command failure 1206 * 1207 * Side Effects: 1208 * The string must be freed by the caller. 1209 */ 1210 char * 1211 Cmd_Exec(cmd, err) 1212 char *cmd; 1213 char **err; 1214 { 1215 char *args[4]; /* Args for invoking the shell */ 1216 int fds[2]; /* Pipe streams */ 1217 int cpid; /* Child PID */ 1218 int pid; /* PID from wait() */ 1219 char *res; /* result */ 1220 int status; /* command exit status */ 1221 Buffer buf; /* buffer to store the result */ 1222 char *cp; 1223 int cc; 1224 1225 1226 *err = NULL; 1227 1228 /* 1229 * Set up arguments for shell 1230 */ 1231 args[0] = "sh"; 1232 args[1] = "-c"; 1233 args[2] = cmd; 1234 args[3] = NULL; 1235 1236 /* 1237 * Open a pipe for fetching its output 1238 */ 1239 if (pipe(fds) == -1) { 1240 *err = "Couldn't create pipe for \"%s\""; 1241 goto bad; 1242 } 1243 1244 /* 1245 * Fork 1246 */ 1247 switch (cpid = vfork()) { 1248 case 0: 1249 /* 1250 * Close input side of pipe 1251 */ 1252 (void) close(fds[0]); 1253 1254 /* 1255 * Duplicate the output stream to the shell's output, then 1256 * shut the extra thing down. Note we don't fetch the error 1257 * stream...why not? Why? 1258 */ 1259 (void) dup2(fds[1], 1); 1260 (void) close(fds[1]); 1261 1262 (void) execv("/bin/sh", args); 1263 _exit(1); 1264 /*NOTREACHED*/ 1265 1266 case -1: 1267 *err = "Couldn't exec \"%s\""; 1268 goto bad; 1269 1270 default: 1271 /* 1272 * No need for the writing half 1273 */ 1274 (void) close(fds[1]); 1275 1276 buf = Buf_Init (MAKE_BSIZE); 1277 1278 do { 1279 char result[BUFSIZ]; 1280 cc = read(fds[0], result, sizeof(result)); 1281 if (cc > 0) 1282 Buf_AddBytes(buf, cc, (Byte *) result); 1283 } 1284 while (cc > 0 || (cc == -1 && errno == EINTR)); 1285 1286 /* 1287 * Close the input side of the pipe. 1288 */ 1289 (void) close(fds[0]); 1290 1291 /* 1292 * Wait for the process to exit. 1293 */ 1294 while(((pid = wait(&status)) != cpid) && (pid >= 0)) 1295 continue; 1296 1297 res = (char *)Buf_GetAll (buf, &cc); 1298 Buf_Destroy (buf, FALSE); 1299 1300 if (cc == 0) 1301 *err = "Couldn't read shell's output for \"%s\""; 1302 1303 if (status) 1304 *err = "\"%s\" returned non-zero status"; 1305 1306 /* 1307 * Null-terminate the result, convert newlines to spaces and 1308 * install it in the variable. 1309 */ 1310 res[cc] = '\0'; 1311 cp = &res[cc]; 1312 1313 if (cc > 0 && *--cp == '\n') { 1314 /* 1315 * A final newline is just stripped 1316 */ 1317 *cp-- = '\0'; 1318 } 1319 while (cp >= res) { 1320 if (*cp == '\n') { 1321 *cp = ' '; 1322 } 1323 cp--; 1324 } 1325 break; 1326 } 1327 return res; 1328 bad: 1329 res = emalloc(1); 1330 *res = '\0'; 1331 return res; 1332 } 1333 1334 /*- 1335 * Error -- 1336 * Print an error message given its format. 1337 * 1338 * Results: 1339 * None. 1340 * 1341 * Side Effects: 1342 * The message is printed. 1343 */ 1344 /* VARARGS */ 1345 void 1346 #ifdef __STDC__ 1347 Error(char *fmt, ...) 1348 #else 1349 Error(va_alist) 1350 va_dcl 1351 #endif 1352 { 1353 va_list ap; 1354 #ifdef __STDC__ 1355 va_start(ap, fmt); 1356 #else 1357 char *fmt; 1358 1359 va_start(ap); 1360 fmt = va_arg(ap, char *); 1361 #endif 1362 fprintf(stderr, "%s: ", progname); 1363 (void)vfprintf(stderr, fmt, ap); 1364 va_end(ap); 1365 (void)fprintf(stderr, "\n"); 1366 (void)fflush(stderr); 1367 } 1368 1369 /*- 1370 * Fatal -- 1371 * Produce a Fatal error message. If jobs are running, waits for them 1372 * to finish. 1373 * 1374 * Results: 1375 * None 1376 * 1377 * Side Effects: 1378 * The program exits 1379 */ 1380 /* VARARGS */ 1381 void 1382 #ifdef __STDC__ 1383 Fatal(char *fmt, ...) 1384 #else 1385 Fatal(va_alist) 1386 va_dcl 1387 #endif 1388 { 1389 va_list ap; 1390 #ifdef __STDC__ 1391 va_start(ap, fmt); 1392 #else 1393 char *fmt; 1394 1395 va_start(ap); 1396 fmt = va_arg(ap, char *); 1397 #endif 1398 if (jobsRunning) 1399 Job_Wait(); 1400 Job_TokenFlush(); 1401 1402 (void)vfprintf(stderr, fmt, ap); 1403 va_end(ap); 1404 (void)fprintf(stderr, "\n"); 1405 (void)fflush(stderr); 1406 1407 PrintOnError(NULL); 1408 1409 if (DEBUG(GRAPH2)) 1410 Targ_PrintGraph(2); 1411 Trace_Log(MAKEERROR, 0); 1412 exit(2); /* Not 1 so -q can distinguish error */ 1413 } 1414 1415 /* 1416 * Punt -- 1417 * Major exception once jobs are being created. Kills all jobs, prints 1418 * a message and exits. 1419 * 1420 * Results: 1421 * None 1422 * 1423 * Side Effects: 1424 * All children are killed indiscriminately and the program Lib_Exits 1425 */ 1426 /* VARARGS */ 1427 void 1428 #ifdef __STDC__ 1429 Punt(char *fmt, ...) 1430 #else 1431 Punt(va_alist) 1432 va_dcl 1433 #endif 1434 { 1435 va_list ap; 1436 #ifdef __STDC__ 1437 va_start(ap, fmt); 1438 #else 1439 char *fmt; 1440 1441 va_start(ap); 1442 fmt = va_arg(ap, char *); 1443 #endif 1444 1445 (void)fprintf(stderr, "%s: ", progname); 1446 (void)vfprintf(stderr, fmt, ap); 1447 va_end(ap); 1448 (void)fprintf(stderr, "\n"); 1449 (void)fflush(stderr); 1450 1451 PrintOnError(NULL); 1452 1453 DieHorribly(); 1454 } 1455 1456 /*- 1457 * DieHorribly -- 1458 * Exit without giving a message. 1459 * 1460 * Results: 1461 * None 1462 * 1463 * Side Effects: 1464 * A big one... 1465 */ 1466 void 1467 DieHorribly() 1468 { 1469 if (jobsRunning) 1470 Job_AbortAll(); 1471 if (DEBUG(GRAPH2)) 1472 Targ_PrintGraph(2); 1473 Trace_Log(MAKEERROR, 0); 1474 exit(2); /* Not 1, so -q can distinguish error */ 1475 } 1476 1477 /* 1478 * Finish -- 1479 * Called when aborting due to errors in child shell to signal 1480 * abnormal exit. 1481 * 1482 * Results: 1483 * None 1484 * 1485 * Side Effects: 1486 * The program exits 1487 */ 1488 void 1489 Finish(errors) 1490 int errors; /* number of errors encountered in Make_Make */ 1491 { 1492 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 1493 } 1494 1495 /* 1496 * emalloc -- 1497 * malloc, but die on error. 1498 */ 1499 void * 1500 emalloc(len) 1501 size_t len; 1502 { 1503 void *p; 1504 1505 if ((p = malloc(len)) == NULL) 1506 enomem(); 1507 return(p); 1508 } 1509 1510 /* 1511 * estrdup -- 1512 * strdup, but die on error. 1513 */ 1514 char * 1515 estrdup(str) 1516 const char *str; 1517 { 1518 char *p; 1519 1520 if ((p = strdup(str)) == NULL) 1521 enomem(); 1522 return(p); 1523 } 1524 1525 /* 1526 * erealloc -- 1527 * realloc, but die on error. 1528 */ 1529 void * 1530 erealloc(ptr, size) 1531 void *ptr; 1532 size_t size; 1533 { 1534 if ((ptr = realloc(ptr, size)) == NULL) 1535 enomem(); 1536 return(ptr); 1537 } 1538 1539 /* 1540 * enomem -- 1541 * die when out of memory. 1542 */ 1543 void 1544 enomem() 1545 { 1546 (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); 1547 exit(2); 1548 } 1549 1550 /* 1551 * enunlink -- 1552 * Remove a file carefully, avoiding directories. 1553 */ 1554 int 1555 eunlink(file) 1556 const char *file; 1557 { 1558 struct stat st; 1559 1560 if (lstat(file, &st) == -1) 1561 return -1; 1562 1563 if (S_ISDIR(st.st_mode)) { 1564 errno = EISDIR; 1565 return -1; 1566 } 1567 return unlink(file); 1568 } 1569 1570 /* 1571 * execError -- 1572 * Print why exec failed, avoiding stdio. 1573 */ 1574 void 1575 execError(av) 1576 const char *av; 1577 { 1578 #ifdef USE_IOVEC 1579 int i = 0; 1580 struct iovec iov[6]; 1581 #define IOADD(s) \ 1582 (void)(iov[i].iov_base = (s), \ 1583 iov[i].iov_len = strlen(iov[i].iov_base), \ 1584 i++) 1585 #else 1586 #define IOADD (void)write(2, s, strlen(s)) 1587 #endif 1588 1589 IOADD(progname); 1590 IOADD(": Exec of `"); 1591 IOADD((char *)av); 1592 IOADD("' failed ("); 1593 IOADD(strerror(errno)); 1594 IOADD(")\n"); 1595 1596 #ifdef USE_IOVEC 1597 (void)writev(2, iov, 6); 1598 #endif 1599 } 1600 1601 /* 1602 * usage -- 1603 * exit with usage message 1604 */ 1605 static void 1606 usage() 1607 { 1608 (void)fprintf(stderr, 1609 "Usage: %s [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\ 1610 [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\ 1611 [variable=value] [target ...]\n", progname); 1612 exit(2); 1613 } 1614 1615 1616 int 1617 PrintAddr(a, b) 1618 ClientData a; 1619 ClientData b; 1620 { 1621 printf("%lx ", (unsigned long) a); 1622 return b ? 0 : 0; 1623 } 1624 1625 1626 1627 void 1628 PrintOnError(s) 1629 char *s; 1630 { 1631 char tmp[64]; 1632 1633 if (s) 1634 printf("%s", s); 1635 1636 printf("\n%s: stopped in %s\n", progname, curdir); 1637 strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}", 1638 sizeof(tmp) - 1); 1639 s = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); 1640 if (s && *s) 1641 printf("%s", s); 1642 } 1643 1644 void 1645 Main_ExportMAKEFLAGS(first) 1646 Boolean first; 1647 { 1648 static int once = 1; 1649 char tmp[64]; 1650 char *s; 1651 1652 if (once != first) 1653 return; 1654 once = 0; 1655 1656 strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}", 1657 sizeof(tmp)); 1658 s = Var_Subst(NULL, tmp, VAR_CMD, 0); 1659 if (s && *s) { 1660 #ifdef POSIX 1661 setenv("MAKEFLAGS", s, 1); 1662 #else 1663 setenv("MAKE", s, 1); 1664 #endif 1665 } 1666 } 1667