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