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