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