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