[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / make

Annotation of src/usr.bin/make/main.c, Revision 1.421

1.421   ! rillig      1: /*     $NetBSD: main.c,v 1.420 2020/10/31 21:09:22 sjg Exp $   */
1.19      christos    2:
1.1       cgd         3: /*
1.31      christos    4:  * Copyright (c) 1988, 1989, 1990, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.91      agc         6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Adam de Boor.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the University nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
1.1       cgd        36:  * Copyright (c) 1989 by Berkeley Softworks
                     37:  * All rights reserved.
                     38:  *
                     39:  * This code is derived from software contributed to Berkeley by
                     40:  * Adam de Boor.
                     41:  *
                     42:  * Redistribution and use in source and binary forms, with or without
                     43:  * modification, are permitted provided that the following conditions
                     44:  * are met:
                     45:  * 1. Redistributions of source code must retain the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer.
                     47:  * 2. Redistributions in binary form must reproduce the above copyright
                     48:  *    notice, this list of conditions and the following disclaimer in the
                     49:  *    documentation and/or other materials provided with the distribution.
                     50:  * 3. All advertising materials mentioning features or use of this software
                     51:  *    must display the following acknowledgement:
                     52:  *     This product includes software developed by the University of
                     53:  *     California, Berkeley and its contributors.
                     54:  * 4. Neither the name of the University nor the names of its contributors
                     55:  *    may be used to endorse or promote products derived from this software
                     56:  *    without specific prior written permission.
                     57:  *
                     58:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     59:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     60:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     61:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     62:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     63:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     64:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     65:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     66:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     67:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     68:  * SUCH DAMAGE.
                     69:  */
                     70:
                     71: /*-
                     72:  * main.c --
                     73:  *     The main file for this entire program. Exit routines etc
                     74:  *     reside here.
                     75:  *
                     76:  * Utility functions defined in this file:
                     77:  *     Main_ParseArgLine       Takes a line of arguments, breaks them and
                     78:  *                             treats them as if they were given when first
                     79:  *                             invoked. Used by the parse module to implement
                     80:  *                             the .MFLAGS target.
                     81:  *
                     82:  *     Error                   Print a tagged error message. The global
                     83:  *                             MAKE variable must have been defined. This
1.227     gson       84:  *                             takes a format string and optional arguments
                     85:  *                             for it.
1.1       cgd        86:  *
                     87:  *     Fatal                   Print an error message and exit. Also takes
1.227     gson       88:  *                             a format string and arguments for it.
1.1       cgd        89:  *
                     90:  *     Punt                    Aborts all jobs and exits with a message. Also
1.227     gson       91:  *                             takes a format string and arguments for it.
1.1       cgd        92:  *
                     93:  *     Finish                  Finish things up by printing the number of
1.72      wiz        94:  *                             errors which occurred, as passed to it, and
1.1       cgd        95:  *                             exiting.
                     96:  */
                     97:
1.13      cgd        98: #include <sys/types.h>
                     99: #include <sys/time.h>
1.1       cgd       100: #include <sys/param.h>
1.13      cgd       101: #include <sys/resource.h>
1.1       cgd       102: #include <sys/stat.h>
1.225     matt      103: #ifdef MAKE_NATIVE
                    104: #include <sys/sysctl.h>
                    105: #endif
1.17      gwr       106: #include <sys/utsname.h>
1.29      christos  107: #include <sys/wait.h>
1.85      wiz       108:
1.1       cgd       109: #include <errno.h>
1.215     christos  110: #include <signal.h>
1.85      wiz       111: #include <stdarg.h>
1.42      kleink    112: #include <time.h>
1.85      wiz       113:
1.1       cgd       114: #include "make.h"
1.13      cgd       115: #include "dir.h"
                    116: #include "job.h"
1.1       cgd       117: #include "pathnames.h"
1.58      sommerfe  118: #include "trace.h"
1.1       cgd       119:
1.337     rillig    120: /*     "@(#)main.c     8.3 (Berkeley) 3/19/94" */
1.421   ! rillig    121: MAKE_RCSID("$NetBSD: main.c,v 1.420 2020/10/31 21:09:22 sjg Exp $");
1.337     rillig    122: #if defined(MAKE_NATIVE) && !defined(lint)
1.369     rillig    123: __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
                    124:            "The Regents of the University of California.  "
                    125:            "All rights reserved.");
1.337     rillig    126: #endif
                    127:
1.1       cgd       128: #ifndef        DEFMAXLOCAL
                    129: #define        DEFMAXLOCAL DEFMAXJOBS
1.336     rillig    130: #endif
1.1       cgd       131:
1.391     rillig    132: CmdOpts opts;
1.1       cgd       133: time_t                 now;            /* Time at start of make */
                    134: GNode                  *DEFAULT;       /* .DEFAULT node */
                    135: Boolean                        allPrecious;    /* .PRECIOUS given on line by itself */
1.251     dholland  136: Boolean                        deleteOnError;  /* .DELETE_ON_ERROR: set */
1.1       cgd       137:
1.132     dsl       138: static int             maxJobTokens;   /* -j argument */
1.233     sjg       139: Boolean                        enterFlagObj;   /* -w and objdir != srcdir */
1.391     rillig    140:
1.1       cgd       141: Boolean                        oldVars;        /* variable substitution style */
1.132     dsl       142: static int jp_0 = -1, jp_1 = -1;       /* ends of parent job pipe */
1.145     dsl       143: Boolean                        doing_depend;   /* Set while reading .depend */
1.1       cgd       144: static Boolean         jobsRunning;    /* TRUE if the jobs might be running */
1.58      sommerfe  145: static const char *    tracefile;
1.325     rillig    146: static int             ReadMakefile(const char *);
1.200     joerg     147: static void            usage(void) MAKE_ATTR_DEAD;
1.262     riastrad  148: static void            purge_cached_realpaths(void);
1.1       cgd       149:
1.174     sjg       150: static Boolean         ignorePWD;      /* if we use -C, PWD is meaningless */
1.74      tv        151: static char objdir[MAXPATHLEN + 1];    /* where we chdir'ed to */
1.196     joerg     152: char curdir[MAXPATHLEN + 1];           /* Startup directory */
1.63      christos  153: char *progname;                                /* the program name */
1.176     sjg       154: char *makeDependfile;
1.183     sjg       155: pid_t myPid;
1.220     christos  156: int makelevel;
1.1       cgd       157:
1.58      sommerfe  158: Boolean forceJobs = FALSE;
1.421   ! rillig    159: static int errors = 0;
1.58      sommerfe  160:
1.338     rillig    161: extern SearchPath *parseIncPath;
1.63      christos  162:
1.220     christos  163: /*
                    164:  * For compatibility with the POSIX version of MAKEFLAGS that includes
                    165:  * all the options with out -, convert flags to -f -l -a -g -s.
                    166:  */
                    167: static char *
                    168: explode(const char *flags)
                    169: {
                    170:     size_t len;
                    171:     char *nf, *st;
                    172:     const char *f;
                    173:
                    174:     if (flags == NULL)
                    175:        return NULL;
                    176:
                    177:     for (f = flags; *f; f++)
1.332     rillig    178:        if (!ch_isalpha(*f))
1.220     christos  179:            break;
                    180:
                    181:     if (*f)
1.221     christos  182:        return bmake_strdup(flags);
1.220     christos  183:
                    184:     len = strlen(flags);
1.221     christos  185:     st = nf = bmake_malloc(len * 3 + 1);
1.220     christos  186:     while (*flags) {
                    187:        *nf++ = '-';
                    188:        *nf++ = *flags++;
                    189:        *nf++ = ' ';
                    190:     }
                    191:     *nf = '\0';
                    192:     return st;
                    193: }
1.279     rillig    194:
1.133     dsl       195: static void
1.344     rillig    196: parse_debug_option_F(const char *modules)
                    197: {
                    198:     const char *mode;
                    199:     size_t len;
                    200:     char *fname;
                    201:
1.391     rillig    202:     if (opts.debug_file != stdout && opts.debug_file != stderr)
                    203:        fclose(opts.debug_file);
1.344     rillig    204:
                    205:     if (*modules == '+') {
                    206:        modules++;
                    207:        mode = "a";
                    208:     } else
                    209:        mode = "w";
                    210:
                    211:     if (strcmp(modules, "stdout") == 0) {
1.391     rillig    212:        opts.debug_file = stdout;
1.344     rillig    213:        return;
                    214:     }
                    215:     if (strcmp(modules, "stderr") == 0) {
1.391     rillig    216:        opts.debug_file = stderr;
1.344     rillig    217:        return;
                    218:     }
                    219:
                    220:     len = strlen(modules);
                    221:     fname = bmake_malloc(len + 20);
                    222:     memcpy(fname, modules, len + 1);
                    223:
                    224:     /* Let the filename be modified by the pid */
                    225:     if (strcmp(fname + len - 3, ".%d") == 0)
                    226:        snprintf(fname + len - 2, 20, "%d", getpid());
                    227:
1.391     rillig    228:     opts.debug_file = fopen(fname, mode);
                    229:     if (!opts.debug_file) {
1.344     rillig    230:        fprintf(stderr, "Cannot open debug file %s\n",
                    231:                fname);
                    232:        usage();
                    233:     }
                    234:     free(fname);
                    235: }
                    236:
                    237: static void
1.133     dsl       238: parse_debug_options(const char *argvalue)
                    239: {
                    240:        const char *modules;
                    241:
                    242:        for (modules = argvalue; *modules; ++modules) {
                    243:                switch (*modules) {
1.369     rillig    244:                case '0':       /* undocumented, only intended for tests */
1.391     rillig    245:                        opts.debug &= DEBUG_LINT;
1.369     rillig    246:                        break;
1.133     dsl       247:                case 'A':
1.391     rillig    248:                        opts.debug = ~(0|DEBUG_LINT);
1.133     dsl       249:                        break;
                    250:                case 'a':
1.391     rillig    251:                        opts.debug |= DEBUG_ARCH;
1.133     dsl       252:                        break;
1.155     christos  253:                case 'C':
1.391     rillig    254:                        opts.debug |= DEBUG_CWD;
1.155     christos  255:                        break;
1.133     dsl       256:                case 'c':
1.391     rillig    257:                        opts.debug |= DEBUG_COND;
1.133     dsl       258:                        break;
                    259:                case 'd':
1.391     rillig    260:                        opts.debug |= DEBUG_DIR;
1.133     dsl       261:                        break;
                    262:                case 'e':
1.391     rillig    263:                        opts.debug |= DEBUG_ERROR;
1.133     dsl       264:                        break;
                    265:                case 'f':
1.391     rillig    266:                        opts.debug |= DEBUG_FOR;
1.133     dsl       267:                        break;
                    268:                case 'g':
                    269:                        if (modules[1] == '1') {
1.391     rillig    270:                                opts.debug |= DEBUG_GRAPH1;
1.133     dsl       271:                                ++modules;
                    272:                        }
                    273:                        else if (modules[1] == '2') {
1.391     rillig    274:                                opts.debug |= DEBUG_GRAPH2;
1.133     dsl       275:                                ++modules;
                    276:                        }
                    277:                        else if (modules[1] == '3') {
1.391     rillig    278:                                opts.debug |= DEBUG_GRAPH3;
1.133     dsl       279:                                ++modules;
                    280:                        }
                    281:                        break;
1.280     sjg       282:                case 'h':
1.391     rillig    283:                        opts.debug |= DEBUG_HASH;
1.280     sjg       284:                        break;
1.133     dsl       285:                case 'j':
1.391     rillig    286:                        opts.debug |= DEBUG_JOB;
1.133     dsl       287:                        break;
1.285     sjg       288:                case 'L':
1.391     rillig    289:                        opts.debug |= DEBUG_LINT;
1.285     sjg       290:                        break;
1.146     sjg       291:                case 'l':
1.391     rillig    292:                        opts.debug |= DEBUG_LOUD;
1.146     sjg       293:                        break;
1.190     sjg       294:                case 'M':
1.391     rillig    295:                        opts.debug |= DEBUG_META;
1.190     sjg       296:                        break;
1.133     dsl       297:                case 'm':
1.391     rillig    298:                        opts.debug |= DEBUG_MAKE;
1.133     dsl       299:                        break;
                    300:                case 'n':
1.391     rillig    301:                        opts.debug |= DEBUG_SCRIPT;
1.133     dsl       302:                        break;
                    303:                case 'p':
1.391     rillig    304:                        opts.debug |= DEBUG_PARSE;
1.133     dsl       305:                        break;
                    306:                case 's':
1.391     rillig    307:                        opts.debug |= DEBUG_SUFF;
1.133     dsl       308:                        break;
                    309:                case 't':
1.391     rillig    310:                        opts.debug |= DEBUG_TARG;
1.133     dsl       311:                        break;
1.201     sjg       312:                case 'V':
1.394     rillig    313:                        opts.debugVflag = TRUE;
1.201     sjg       314:                        break;
1.133     dsl       315:                case 'v':
1.391     rillig    316:                        opts.debug |= DEBUG_VAR;
1.133     dsl       317:                        break;
                    318:                case 'x':
1.391     rillig    319:                        opts.debug |= DEBUG_SHELL;
1.133     dsl       320:                        break;
                    321:                case 'F':
1.344     rillig    322:                        parse_debug_option_F(modules + 1);
1.153     apb       323:                        goto debug_setbuf;
1.133     dsl       324:                default:
                    325:                        (void)fprintf(stderr,
                    326:                            "%s: illegal argument to d option -- %c\n",
                    327:                            progname, *modules);
                    328:                        usage();
                    329:                }
                    330:        }
1.153     apb       331: debug_setbuf:
                    332:        /*
                    333:         * Make the debug_file unbuffered, and make
                    334:         * stdout line buffered (unless debugfile == stdout).
                    335:         */
1.391     rillig    336:        setvbuf(opts.debug_file, NULL, _IONBF, 0);
                    337:        if (opts.debug_file != stdout) {
1.153     apb       338:                setvbuf(stdout, NULL, _IOLBF, 0);
                    339:        }
1.133     dsl       340: }
                    341:
1.264     sjg       342: /*
                    343:  * does path contain any relative components
                    344:  */
1.286     rillig    345: static Boolean
1.264     sjg       346: is_relpath(const char *path)
                    347: {
                    348:        const char *cp;
                    349:
                    350:        if (path[0] != '/')
                    351:                return TRUE;
                    352:        cp = path;
1.286     rillig    353:        while ((cp = strstr(cp, "/.")) != NULL) {
1.264     sjg       354:                cp += 2;
                    355:                if (cp[0] == '/' || cp[0] == '\0')
                    356:                        return TRUE;
                    357:                else if (cp[0] == '.') {
                    358:                        if (cp[1] == '/' || cp[1] == '\0')
                    359:                                return TRUE;
                    360:                }
1.286     rillig    361:        }
1.264     sjg       362:        return FALSE;
                    363: }
                    364:
1.355     rillig    365: static void
                    366: MainParseArgChdir(const char *argvalue)
                    367: {
                    368:        struct stat sa, sb;
                    369:
                    370:        if (chdir(argvalue) == -1) {
                    371:                (void)fprintf(stderr, "%s: chdir %s: %s\n",
                    372:                    progname, argvalue, strerror(errno));
                    373:                exit(1);
                    374:        }
                    375:        if (getcwd(curdir, MAXPATHLEN) == NULL) {
                    376:                (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
                    377:                exit(2);
                    378:        }
                    379:        if (!is_relpath(argvalue) &&
                    380:            stat(argvalue, &sa) != -1 &&
                    381:            stat(curdir, &sb) != -1 &&
                    382:            sa.st_ino == sb.st_ino &&
                    383:            sa.st_dev == sb.st_dev)
                    384:                strncpy(curdir, argvalue, MAXPATHLEN);
                    385:        ignorePWD = TRUE;
                    386: }
                    387:
1.356     rillig    388: static void
                    389: MainParseArgJobsInternal(const char *argvalue)
                    390: {
                    391:        if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
                    392:                (void)fprintf(stderr,
                    393:                              "%s: internal error -- J option malformed (%s)\n",
                    394:                              progname, argvalue);
                    395:                usage();
                    396:        }
                    397:        if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
                    398:            (fcntl(jp_1, F_GETFD, 0) < 0)) {
                    399: #if 0
                    400:                (void)fprintf(stderr,
                    401:                    "%s: ###### warning -- J descriptors were closed!\n",
                    402:                    progname);
                    403:                exit(2);
                    404: #endif
                    405:                jp_0 = -1;
                    406:                jp_1 = -1;
1.391     rillig    407:                opts.compatMake = TRUE;
1.356     rillig    408:        } else {
                    409:                Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
                    410:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    411:        }
                    412: }
                    413:
                    414: static void
                    415: MainParseArgJobs(const char *argvalue)
                    416: {
                    417:        char *p;
                    418:
                    419:        forceJobs = TRUE;
1.391     rillig    420:        opts.maxJobs = (int)strtol(argvalue, &p, 0);
                    421:        if (*p != '\0' || opts.maxJobs < 1) {
1.356     rillig    422:                (void)fprintf(stderr,
                    423:                    "%s: illegal argument to -j -- must be positive integer!\n",
                    424:                    progname);
                    425:                exit(1);        /* XXX: why not 2? */
                    426:        }
                    427:        Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
                    428:        Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    429:        Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL);
1.391     rillig    430:        maxJobTokens = opts.maxJobs;
1.356     rillig    431: }
                    432:
1.357     rillig    433: static void
                    434: MainParseArgSysInc(const char *argvalue)
                    435: {
                    436:        /* look for magic parent directory search string */
                    437:        if (strncmp(".../", argvalue, 4) == 0) {
1.371     rillig    438:                char *found_path = Dir_FindHereOrAbove(curdir, argvalue + 4);
                    439:                if (found_path == NULL)
1.357     rillig    440:                        return;
                    441:                (void)Dir_AddDir(sysIncPath, found_path);
1.371     rillig    442:                free(found_path);
1.357     rillig    443:        } else {
                    444:                (void)Dir_AddDir(sysIncPath, argvalue);
                    445:        }
                    446:        Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
                    447:        Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    448: }
                    449:
1.354     rillig    450: static Boolean
1.360     rillig    451: MainParseArg(char c, const char *argvalue)
1.354     rillig    452: {
                    453:        switch (c) {
                    454:        case '\0':
                    455:                break;
                    456:        case 'B':
1.391     rillig    457:                opts.compatMake = TRUE;
1.354     rillig    458:                Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
                    459:                Var_Set(MAKE_MODE, "compat", VAR_GLOBAL);
                    460:                break;
                    461:        case 'C':
1.355     rillig    462:                MainParseArgChdir(argvalue);
1.354     rillig    463:                break;
                    464:        case 'D':
1.359     rillig    465:                if (argvalue[0] == '\0') return FALSE;
1.354     rillig    466:                Var_Set(argvalue, "1", VAR_GLOBAL);
                    467:                Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
                    468:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    469:                break;
                    470:        case 'I':
                    471:                Parse_AddIncludeDir(argvalue);
                    472:                Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
                    473:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    474:                break;
                    475:        case 'J':
1.356     rillig    476:                MainParseArgJobsInternal(argvalue);
1.354     rillig    477:                break;
                    478:        case 'N':
1.391     rillig    479:                opts.noExecute = TRUE;
                    480:                opts.noRecursiveExecute = TRUE;
1.354     rillig    481:                Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
                    482:                break;
                    483:        case 'S':
1.391     rillig    484:                opts.keepgoing = FALSE;
1.354     rillig    485:                Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
                    486:                break;
                    487:        case 'T':
                    488:                tracefile = bmake_strdup(argvalue);
                    489:                Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
                    490:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    491:                break;
                    492:        case 'V':
                    493:        case 'v':
1.391     rillig    494:                opts.printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS;
                    495:                Lst_Append(opts.variables, bmake_strdup(argvalue));
                    496:                /* XXX: Why always -V? */
1.354     rillig    497:                Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
                    498:                Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    499:                break;
                    500:        case 'W':
1.391     rillig    501:                opts.parseWarnFatal = TRUE;
1.354     rillig    502:                break;
                    503:        case 'X':
1.391     rillig    504:                opts.varNoExportEnv = TRUE;
1.354     rillig    505:                Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
                    506:                break;
                    507:        case 'd':
                    508:                /* If '-d-opts' don't pass to children */
                    509:                if (argvalue[0] == '-')
                    510:                        argvalue++;
                    511:                else {
                    512:                        Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
                    513:                        Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
                    514:                }
                    515:                parse_debug_options(argvalue);
                    516:                break;
                    517:        case 'e':
1.391     rillig    518:                opts.checkEnvFirst = TRUE;
1.354     rillig    519:                Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
                    520:                break;
                    521:        case 'f':
1.391     rillig    522:                Lst_Append(opts.makefiles, bmake_strdup(argvalue));
1.354     rillig    523:                break;
                    524:        case 'i':
1.391     rillig    525:                opts.ignoreErrors = TRUE;
1.354     rillig    526:                Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
                    527:                break;
                    528:        case 'j':
1.356     rillig    529:                MainParseArgJobs(argvalue);
1.354     rillig    530:                break;
                    531:        case 'k':
1.391     rillig    532:                opts.keepgoing = TRUE;
1.354     rillig    533:                Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
                    534:                break;
                    535:        case 'm':
1.357     rillig    536:                MainParseArgSysInc(argvalue);
1.354     rillig    537:                break;
                    538:        case 'n':
1.391     rillig    539:                opts.noExecute = TRUE;
1.354     rillig    540:                Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
                    541:                break;
                    542:        case 'q':
1.391     rillig    543:                opts.queryFlag = TRUE;
1.354     rillig    544:                /* Kind of nonsensical, wot? */
                    545:                Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
                    546:                break;
                    547:        case 'r':
1.391     rillig    548:                opts.noBuiltins = TRUE;
1.354     rillig    549:                Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
                    550:                break;
                    551:        case 's':
1.391     rillig    552:                opts.beSilent = TRUE;
1.354     rillig    553:                Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
                    554:                break;
                    555:        case 't':
1.391     rillig    556:                opts.touchFlag = TRUE;
1.354     rillig    557:                Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
                    558:                break;
                    559:        case 'w':
1.391     rillig    560:                opts.enterFlag = TRUE;
1.354     rillig    561:                Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
                    562:                break;
                    563:        default:
                    564:        case '?':
                    565:                usage();
                    566:        }
                    567:        return TRUE;
                    568: }
                    569:
1.345     rillig    570: /* Parse the given arguments.  Called from main() and from
                    571:  * Main_ParseArgLine() when the .MAKEFLAGS target is used.
1.1       cgd       572:  *
1.345     rillig    573:  * The arguments must be treated as read-only and will be freed after the
                    574:  * call.
1.1       cgd       575:  *
1.345     rillig    576:  * XXX: Deal with command line overriding .MAKEFLAGS in makefile */
1.1       cgd       577: static void
1.149     christos  578: MainParseArgs(int argc, char **argv)
1.1       cgd       579: {
1.360     rillig    580:        char c;
1.98      ross      581:        int arginc;
1.133     dsl       582:        char *argvalue;
1.98      ross      583:        char *optscan;
1.101     ross      584:        Boolean inOption, dashDash = FALSE;
1.1       cgd       585:
1.359     rillig    586:        const char *optspecs = "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstv:w";
1.98      ross      587: /* Can't actually use getopt(3) because rescanning is not portable */
                    588:
1.279     rillig    589: rearg:
1.98      ross      590:        inOption = FALSE;
1.108     lukem     591:        optscan = NULL;
1.358     rillig    592:        while (argc > 1) {
1.359     rillig    593:                const char *optspec;
1.358     rillig    594:                if (!inOption)
1.98      ross      595:                        optscan = argv[1];
                    596:                c = *optscan++;
                    597:                arginc = 0;
1.358     rillig    598:                if (inOption) {
                    599:                        if (c == '\0') {
1.98      ross      600:                                ++argv;
                    601:                                --argc;
                    602:                                inOption = FALSE;
                    603:                                continue;
                    604:                        }
                    605:                } else {
1.101     ross      606:                        if (c != '-' || dashDash)
1.98      ross      607:                                break;
                    608:                        inOption = TRUE;
                    609:                        c = *optscan++;
                    610:                }
                    611:                /* '-' found at some earlier point */
1.359     rillig    612:                optspec = strchr(optspecs, c);
                    613:                if (c != '\0' && optspec != NULL && optspec[1] == ':') {
1.98      ross      614:                        /* -<something> found, and <something> should have an arg */
                    615:                        inOption = FALSE;
                    616:                        arginc = 1;
                    617:                        argvalue = optscan;
1.358     rillig    618:                        if (*argvalue == '\0') {
1.122     christos  619:                                if (argc < 3)
                    620:                                        goto noarg;
1.98      ross      621:                                argvalue = argv[2];
                    622:                                arginc = 2;
                    623:                        }
1.108     lukem     624:                } else {
1.279     rillig    625:                        argvalue = NULL;
1.98      ross      626:                }
1.354     rillig    627:                switch (c) {
1.98      ross      628:                case '\0':
1.358     rillig    629:                        arginc = 1;
                    630:                        inOption = FALSE;
                    631:                        break;
1.101     ross      632:                case '-':
1.358     rillig    633:                        dashDash = TRUE;
                    634:                        break;
1.1       cgd       635:                default:
1.358     rillig    636:                        if (!MainParseArg(c, argvalue))
                    637:                                goto noarg;
1.1       cgd       638:                }
1.98      ross      639:                argv += arginc;
                    640:                argc -= arginc;
1.1       cgd       641:        }
                    642:
                    643:        oldVars = TRUE;
                    644:
                    645:        /*
                    646:         * See if the rest of the arguments are variable assignments and
                    647:         * perform them if so. Else take them to be targets and stuff them
                    648:         * on the end of the "create" list.
                    649:         */
1.369     rillig    650:        for (; argc > 1; ++argv, --argc) {
                    651:                VarAssign var;
                    652:                if (Parse_IsVar(argv[1], &var)) {
1.410     rillig    653:                        Parse_DoVar(&var, VAR_CMDLINE);
1.67      sjg       654:                } else {
1.98      ross      655:                        if (!*argv[1])
1.1       cgd       656:                                Punt("illegal (null) argument.");
1.101     ross      657:                        if (*argv[1] == '-' && !dashDash)
1.1       cgd       658:                                goto rearg;
1.391     rillig    659:                        Lst_Append(opts.create, bmake_strdup(argv[1]));
1.1       cgd       660:                }
1.369     rillig    661:        }
1.122     christos  662:
                    663:        return;
                    664: noarg:
                    665:        (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
                    666:            progname, c);
                    667:        usage();
1.1       cgd       668: }
                    669:
1.361     rillig    670: /* Break a line of arguments into words and parse them.
1.85      wiz       671:  *
1.361     rillig    672:  * Used when a .MFLAGS or .MAKEFLAGS target is encountered during parsing and
                    673:  * by main() when reading the MAKEFLAGS environment variable. */
1.1       cgd       674: void
1.161     dsl       675: Main_ParseArgLine(const char *line)
1.1       cgd       676: {
1.331     rillig    677:        Words words;
1.412     rillig    678:        void *p1;
1.289     rillig    679:        const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
1.296     rillig    680:        char *buf;
1.1       cgd       681:
                    682:        if (line == NULL)
                    683:                return;
1.13      cgd       684:        for (; *line == ' '; ++line)
                    685:                continue;
1.1       cgd       686:        if (!*line)
                    687:                return;
                    688:
1.303     rillig    689:        buf = str_concat3(argv0, " ", line);
1.238     christos  690:        free(p1);
1.40      christos  691:
1.331     rillig    692:        words = Str_Words(buf, TRUE);
                    693:        if (words.words == NULL) {
1.159     christos  694:                Error("Unterminated quoted string [%s]", buf);
                    695:                free(buf);
                    696:                return;
                    697:        }
1.45      itohy     698:        free(buf);
1.331     rillig    699:        MainParseArgs((int)words.len, words.words);
1.40      christos  700:
1.331     rillig    701:        Words_Free(words);
1.1       cgd       702: }
                    703:
1.74      tv        704: Boolean
1.252     christos  705: Main_SetObjdir(const char *fmt, ...)
1.31      christos  706: {
                    707:        struct stat sb;
1.260     christos  708:        char *path;
                    709:        char buf[MAXPATHLEN + 1];
1.265     sjg       710:        char buf2[MAXPATHLEN + 1];
1.76      tv        711:        Boolean rc = FALSE;
1.252     christos  712:        va_list ap;
                    713:
                    714:        va_start(ap, fmt);
1.260     christos  715:        vsnprintf(path = buf, MAXPATHLEN, fmt, ap);
1.252     christos  716:        va_end(ap);
1.31      christos  717:
1.74      tv        718:        if (path[0] != '/') {
1.263     sjg       719:                snprintf(buf2, MAXPATHLEN, "%s/%s", curdir, path);
                    720:                path = buf2;
1.74      tv        721:        }
                    722:
                    723:        /* look for the directory and try to chdir there */
1.31      christos  724:        if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
1.420     sjg       725:                /* if not .CURDIR it must be writable */
                    726:                if ((strcmp(path, curdir) != 0 && access(path, W_OK) != 0) ||
                    727:                    chdir(path)) {
1.31      christos  728:                        (void)fprintf(stderr, "make warning: %s: %s.\n",
                    729:                                      path, strerror(errno));
1.74      tv        730:                } else {
1.295     rillig    731:                        snprintf(objdir, sizeof objdir, "%s", path);
1.277     rillig    732:                        Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
1.74      tv        733:                        setenv("PWD", objdir, 1);
1.79      tv        734:                        Dir_InitDot();
1.262     riastrad  735:                        purge_cached_realpaths();
1.74      tv        736:                        rc = TRUE;
1.391     rillig    737:                        if (opts.enterFlag && strcmp(objdir, curdir) != 0)
1.233     sjg       738:                                enterFlagObj = TRUE;
1.31      christos  739:                }
                    740:        }
                    741:
1.74      tv        742:        return rc;
1.31      christos  743: }
                    744:
1.252     christos  745: static Boolean
1.253     christos  746: Main_SetVarObjdir(const char *var, const char *suffix)
1.252     christos  747: {
1.412     rillig    748:        void *path_freeIt;
1.410     rillig    749:        const char *path = Var_Value(var, VAR_CMDLINE, &path_freeIt);
1.296     rillig    750:        const char *xpath;
                    751:        char *xpath_freeIt;
                    752:
1.288     rillig    753:        if (path == NULL || path[0] == '\0') {
1.290     rillig    754:                bmake_free(path_freeIt);
1.252     christos  755:                return FALSE;
1.288     rillig    756:        }
1.252     christos  757:
1.260     christos  758:        /* expand variable substitutions */
1.296     rillig    759:        xpath = path;
                    760:        xpath_freeIt = NULL;
1.341     rillig    761:        if (strchr(path, '$') != 0) {
                    762:                (void)Var_Subst(path, VAR_GLOBAL, VARE_WANTRES, &xpath_freeIt);
                    763:                /* TODO: handle errors */
                    764:                xpath = xpath_freeIt;
                    765:        }
1.260     christos  766:
                    767:        (void)Main_SetObjdir("%s%s", xpath, suffix);
                    768:
1.290     rillig    769:        bmake_free(xpath_freeIt);
                    770:        bmake_free(path_freeIt);
1.252     christos  771:        return TRUE;
                    772: }
                    773:
1.325     rillig    774: /* Read and parse the makefile.
1.387     rillig    775:  * Return TRUE if reading the makefile succeeded. */
1.386     rillig    776: static int
                    777: ReadMakefileSucceeded(void *fname, void *unused)
1.325     rillig    778: {
                    779:        return ReadMakefile(fname) == 0;
                    780: }
                    781:
1.197     sjg       782: int
1.338     rillig    783: str2Lst_Append(StringList *lp, char *str, const char *sep)
1.176     sjg       784: {
                    785:     char *cp;
                    786:     int n;
                    787:
                    788:     if (!sep)
                    789:        sep = " \t";
                    790:
                    791:     for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
1.320     rillig    792:        Lst_Append(lp, cp);
1.176     sjg       793:        n++;
                    794:     }
1.278     rillig    795:     return n;
1.176     sjg       796: }
                    797:
1.167     christos  798: #ifdef SIGINFO
                    799: /*ARGSUSED*/
                    800: static void
1.200     joerg     801: siginfo(int signo MAKE_ATTR_UNUSED)
1.167     christos  802: {
                    803:        char dir[MAXPATHLEN];
                    804:        char str[2 * MAXPATHLEN];
                    805:        int len;
                    806:        if (getcwd(dir, sizeof(dir)) == NULL)
                    807:                return;
1.168     christos  808:        len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir);
1.167     christos  809:        if (len > 0)
                    810:                (void)write(STDERR_FILENO, str, (size_t)len);
                    811: }
                    812: #endif
                    813:
1.176     sjg       814: /*
                    815:  * Allow makefiles some control over the mode we run in.
                    816:  */
                    817: void
                    818: MakeMode(const char *mode)
                    819: {
1.322     rillig    820:     char *mode_freeIt = NULL;
1.176     sjg       821:
1.341     rillig    822:     if (mode == NULL) {
                    823:        (void)Var_Subst("${" MAKE_MODE ":tl}",
                    824:                  VAR_GLOBAL, VARE_WANTRES, &mode_freeIt);
                    825:        /* TODO: handle errors */
                    826:        mode = mode_freeIt;
                    827:     }
1.176     sjg       828:
1.322     rillig    829:     if (mode[0] != '\0') {
1.176     sjg       830:        if (strstr(mode, "compat")) {
1.391     rillig    831:            opts.compatMake = TRUE;
1.176     sjg       832:            forceJobs = FALSE;
                    833:        }
1.190     sjg       834: #if USE_META
                    835:        if (strstr(mode, "meta"))
1.210     sjg       836:            meta_mode_init(mode);
1.190     sjg       837: #endif
1.176     sjg       838:     }
1.238     christos  839:
1.322     rillig    840:     free(mode_freeIt);
1.176     sjg       841: }
                    842:
1.266     christos  843: static void
1.383     rillig    844: PrintVar(const char *varname, Boolean expandVars)
                    845: {
                    846:        if (strchr(varname, '$')) {
1.384     rillig    847:                char *evalue;
                    848:                (void)Var_Subst(varname, VAR_GLOBAL, VARE_WANTRES, &evalue);
1.383     rillig    849:                /* TODO: handle errors */
1.384     rillig    850:                printf("%s\n", evalue);
                    851:                bmake_free(evalue);
                    852:
1.383     rillig    853:        } else if (expandVars) {
                    854:                char *expr = str_concat3("${", varname, "}");
1.384     rillig    855:                char *evalue;
                    856:                (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &evalue);
1.383     rillig    857:                /* TODO: handle errors */
                    858:                free(expr);
1.384     rillig    859:                printf("%s\n", evalue);
                    860:                bmake_free(evalue);
                    861:
1.383     rillig    862:        } else {
1.412     rillig    863:                void *freeIt;
1.384     rillig    864:                const char *value = Var_Value(varname, VAR_GLOBAL, &freeIt);
                    865:                printf("%s\n", value ? value : "");
                    866:                bmake_free(freeIt);
1.383     rillig    867:        }
                    868: }
                    869:
                    870: static void
1.266     christos  871: doPrintVars(void)
                    872: {
1.338     rillig    873:        StringListNode *ln;
1.266     christos  874:        Boolean expandVars;
                    875:
1.391     rillig    876:        if (opts.printVars == EXPAND_VARS)
1.272     christos  877:                expandVars = TRUE;
1.394     rillig    878:        else if (opts.debugVflag)
1.266     christos  879:                expandVars = FALSE;
                    880:        else
1.272     christos  881:                expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
1.266     christos  882:
1.391     rillig    883:        for (ln = opts.variables->first; ln != NULL; ln = ln->next) {
1.383     rillig    884:                const char *varname = ln->datum;
                    885:                PrintVar(varname, expandVars);
1.266     christos  886:        }
                    887: }
                    888:
                    889: static Boolean
                    890: runTargets(void)
                    891: {
1.338     rillig    892:        GNodeList *targs; /* target nodes to create -- passed to Make_Init */
1.351     rillig    893:        Boolean outOfDate;      /* FALSE if all targets up to date */
1.266     christos  894:
                    895:        /*
                    896:         * Have now read the entire graph and need to make a list of
                    897:         * targets to create. If none was given on the command line,
                    898:         * we consult the parsing module to find the main target(s)
                    899:         * to create.
                    900:         */
1.391     rillig    901:        if (Lst_IsEmpty(opts.create))
1.266     christos  902:                targs = Parse_MainName();
                    903:        else
1.391     rillig    904:                targs = Targ_FindList(opts.create);
1.266     christos  905:
1.391     rillig    906:        if (!opts.compatMake) {
1.266     christos  907:                /*
                    908:                 * Initialize job module before traversing the graph
                    909:                 * now that any .BEGIN and .END targets have been read.
                    910:                 * This is done only if the -q flag wasn't given
                    911:                 * (to prevent the .BEGIN from being executed should
                    912:                 * it exist).
                    913:                 */
1.391     rillig    914:                if (!opts.queryFlag) {
1.266     christos  915:                        Job_Init();
                    916:                        jobsRunning = TRUE;
                    917:                }
                    918:
                    919:                /* Traverse the graph, checking on all the targets */
                    920:                outOfDate = Make_Run(targs);
                    921:        } else {
                    922:                /*
                    923:                 * Compat_Init will take care of creating all the
                    924:                 * targets as well as initializing the module.
                    925:                 */
                    926:                Compat_Run(targs);
                    927:                outOfDate = FALSE;
                    928:        }
1.320     rillig    929:        Lst_Free(targs);
1.266     christos  930:        return outOfDate;
                    931: }
                    932:
1.343     rillig    933: /*
                    934:  * Set up the .TARGETS variable to contain the list of targets to be
                    935:  * created. If none specified, make the variable empty -- the parser
                    936:  * will fill the thing in with the default or .MAIN target.
                    937:  */
                    938: static void
                    939: InitVarTargets(void)
                    940: {
                    941:        StringListNode *ln;
                    942:
1.391     rillig    943:        if (Lst_IsEmpty(opts.create)) {
1.343     rillig    944:                Var_Set(".TARGETS", "", VAR_GLOBAL);
                    945:                return;
                    946:        }
                    947:
1.391     rillig    948:        for (ln = opts.create->first; ln != NULL; ln = ln->next) {
1.343     rillig    949:                char *name = ln->datum;
                    950:                Var_Append(".TARGETS", name, VAR_GLOBAL);
                    951:        }
                    952: }
                    953:
1.404     rillig    954: static void
                    955: InitRandom(void)
                    956: {
                    957:        struct timeval tv;
                    958:
                    959:        gettimeofday(&tv, NULL);
                    960:        srandom((unsigned int)(tv.tv_sec + tv.tv_usec));
                    961: }
                    962:
1.369     rillig    963: static const char *
                    964: init_machine(const struct utsname *utsname)
                    965: {
                    966:        const char *machine = getenv("MACHINE");
                    967:        if (machine != NULL)
                    968:                return machine;
                    969:
                    970: #ifdef MAKE_NATIVE
                    971:        return utsname->machine;
                    972: #else
                    973: #ifdef MAKE_MACHINE
                    974:        return MAKE_MACHINE;
                    975: #else
                    976:        return "unknown";
                    977: #endif
                    978: #endif
                    979: }
                    980:
                    981: static const char *
                    982: init_machine_arch(void)
                    983: {
                    984:        const char *env = getenv("MACHINE_ARCH");
                    985:        if (env != NULL)
                    986:                return env;
                    987:
                    988: #ifdef MAKE_NATIVE
                    989:        {
                    990:                struct utsname utsname;
                    991:                static char machine_arch_buf[sizeof(utsname.machine)];
                    992:                const int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
                    993:                size_t len = sizeof(machine_arch_buf);
                    994:
                    995:                if (sysctl(mib, __arraycount(mib), machine_arch_buf,
                    996:                        &len, NULL, 0) < 0) {
                    997:                    (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
                    998:                        strerror(errno));
                    999:                    exit(2);
                   1000:                }
                   1001:
                   1002:                return machine_arch_buf;
                   1003:        }
                   1004: #else
                   1005: #ifndef MACHINE_ARCH
                   1006: #ifdef MAKE_MACHINE_ARCH
                   1007:        return MAKE_MACHINE_ARCH;
                   1008: #else
                   1009:        return "unknown";
                   1010: #endif
                   1011: #else
                   1012:        return MACHINE_ARCH;
                   1013: #endif
                   1014: #endif
                   1015: }
                   1016:
1.381     rillig   1017: #ifndef NO_PWD_OVERRIDE
                   1018: /*
                   1019:  * All this code is so that we know where we are when we start up
                   1020:  * on a different machine with pmake.
1.382     rillig   1021:  *
1.381     rillig   1022:  * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
                   1023:  * since the value of curdir can vary depending on how we got
                   1024:  * here.  Ie sitting at a shell prompt (shell that provides $PWD)
                   1025:  * or via subdir.mk in which case its likely a shell which does
                   1026:  * not provide it.
1.382     rillig   1027:  *
1.381     rillig   1028:  * So, to stop it breaking this case only, we ignore PWD if
1.382     rillig   1029:  * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a variable expression.
1.381     rillig   1030:  */
                   1031: static void
1.382     rillig   1032: HandlePWD(const struct stat *curdir_st)
1.381     rillig   1033: {
1.382     rillig   1034:        char *pwd;
1.412     rillig   1035:        void *prefix_freeIt, *makeobjdir_freeIt;
1.382     rillig   1036:        const char *makeobjdir;
                   1037:        struct stat pwd_st;
1.381     rillig   1038:
                   1039:        if (ignorePWD || (pwd = getenv("PWD")) == NULL)
                   1040:                return;
                   1041:
1.410     rillig   1042:        if (Var_Value("MAKEOBJDIRPREFIX", VAR_CMDLINE, &prefix_freeIt) != NULL) {
1.382     rillig   1043:                bmake_free(prefix_freeIt);
                   1044:                return;
1.381     rillig   1045:        }
1.382     rillig   1046:
1.410     rillig   1047:        makeobjdir = Var_Value("MAKEOBJDIR", VAR_CMDLINE, &makeobjdir_freeIt);
1.382     rillig   1048:        if (makeobjdir != NULL && strchr(makeobjdir, '$') != NULL)
                   1049:                goto ignore_pwd;
                   1050:
                   1051:        if (stat(pwd, &pwd_st) == 0 &&
                   1052:            curdir_st->st_ino == pwd_st.st_ino &&
                   1053:            curdir_st->st_dev == pwd_st.st_dev)
                   1054:                (void)strncpy(curdir, pwd, MAXPATHLEN);
                   1055:
                   1056: ignore_pwd:
                   1057:        bmake_free(makeobjdir_freeIt);
1.381     rillig   1058: }
                   1059: #endif
                   1060:
1.407     rillig   1061: /*
                   1062:  * Find the .OBJDIR.  If MAKEOBJDIRPREFIX, or failing that,
                   1063:  * MAKEOBJDIR is set in the environment, try only that value
                   1064:  * and fall back to .CURDIR if it does not exist.
                   1065:  *
                   1066:  * Otherwise, try _PATH_OBJDIR.MACHINE-MACHINE_ARCH, _PATH_OBJDIR.MACHINE,
                   1067:  * and * finally _PATH_OBJDIRPREFIX`pwd`, in that order.  If none
                   1068:  * of these paths exist, just use .CURDIR.
                   1069:  */
                   1070: static void
                   1071: InitObjdir(const char *machine, const char *machine_arch)
                   1072: {
                   1073:        Dir_InitDir(curdir);
                   1074:        (void)Main_SetObjdir("%s", curdir);
                   1075:
                   1076:        if (!Main_SetVarObjdir("MAKEOBJDIRPREFIX", curdir) &&
                   1077:            !Main_SetVarObjdir("MAKEOBJDIR", "") &&
                   1078:            !Main_SetObjdir("%s.%s-%s", _PATH_OBJDIR, machine, machine_arch) &&
                   1079:            !Main_SetObjdir("%s.%s", _PATH_OBJDIR, machine) &&
                   1080:            !Main_SetObjdir("%s", _PATH_OBJDIR))
                   1081:                (void)Main_SetObjdir("%s%s", _PATH_OBJDIRPREFIX, curdir);
                   1082: }
                   1083:
1.393     rillig   1084: /* get rid of resource limit on file descriptors */
                   1085: static void
                   1086: UnlimitFiles(void)
                   1087: {
                   1088: #if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
                   1089:        struct rlimit rl;
                   1090:        if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
                   1091:            rl.rlim_cur != rl.rlim_max) {
                   1092:                rl.rlim_cur = rl.rlim_max;
                   1093:                (void)setrlimit(RLIMIT_NOFILE, &rl);
                   1094:        }
                   1095: #endif
                   1096: }
                   1097:
1.395     rillig   1098: static void
                   1099: CmdOpts_Init(void)
                   1100: {
                   1101:        opts.compatMake = FALSE;        /* No compat mode */
                   1102:        opts.debug = 0;                 /* No debug verbosity, please. */
                   1103:        /* opts.debug_file has been initialized earlier */
                   1104:        opts.debugVflag = FALSE;
1.396     rillig   1105:        opts.checkEnvFirst = FALSE;
1.395     rillig   1106:        opts.makefiles = Lst_New();
                   1107:        opts.ignoreErrors = FALSE;      /* Pay attention to non-zero returns */
                   1108:        opts.maxJobs = DEFMAXLOCAL;     /* Set default local max concurrency */
                   1109:        opts.keepgoing = FALSE;         /* Stop on error */
                   1110:        opts.noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
                   1111:        opts.noExecute = FALSE;         /* Execute all commands */
                   1112:        opts.queryFlag = FALSE;         /* This is not just a check-run */
                   1113:        opts.noBuiltins = FALSE;        /* Read the built-in rules */
                   1114:        opts.beSilent = FALSE;          /* Print commands as executed */
                   1115:        opts.touchFlag = FALSE;         /* Actually update targets */
                   1116:        opts.printVars = 0;
                   1117:        opts.variables = Lst_New();
1.396     rillig   1118:        opts.parseWarnFatal = FALSE;
                   1119:        opts.enterFlag = FALSE;
                   1120:        opts.varNoExportEnv = FALSE;
1.395     rillig   1121:        opts.create = Lst_New();
                   1122: }
                   1123:
1.406     rillig   1124: /* Initialize MAKE and .MAKE to the path of the executable, so that it can be
                   1125:  * found by execvp(3) and the shells, even after a chdir.
                   1126:  *
                   1127:  * If it's a relative path and contains a '/', resolve it to an absolute path.
                   1128:  * Otherwise keep it as is, assuming it will be found in the PATH. */
1.397     rillig   1129: static void
1.406     rillig   1130: InitVarMake(const char *argv0)
1.405     rillig   1131: {
1.406     rillig   1132:        const char *make = argv0;
1.405     rillig   1133:
1.406     rillig   1134:        if (argv0[0] != '/' && strchr(argv0, '/') != NULL) {
                   1135:                char pathbuf[MAXPATHLEN];
                   1136:                const char *abs = cached_realpath(argv0, pathbuf);
                   1137:                struct stat st;
                   1138:                if (abs != NULL && abs[0] == '/' && stat(make, &st) == 0)
                   1139:                        make = abs;
1.405     rillig   1140:        }
1.406     rillig   1141:
                   1142:        Var_Set("MAKE", make, VAR_GLOBAL);
                   1143:        Var_Set(".MAKE", make, VAR_GLOBAL);
1.405     rillig   1144: }
                   1145:
                   1146: static void
1.409     rillig   1147: InitDefSysIncPath(char *syspath)
1.397     rillig   1148: {
                   1149:        static char defsyspath[] = _PATH_DEFSYSPATH;
                   1150:        char *start, *cp;
                   1151:
                   1152:        /*
                   1153:         * If no user-supplied system path was given (through the -m option)
                   1154:         * add the directories from the DEFSYSPATH (more than one may be given
                   1155:         * as dir1:...:dirn) to the system include path.
                   1156:         */
                   1157:        /* XXX: mismatch: the -m option sets sysIncPath, not syspath */
                   1158:        if (syspath == NULL || syspath[0] == '\0')
                   1159:                syspath = defsyspath;
                   1160:        else
                   1161:                syspath = bmake_strdup(syspath);
                   1162:
                   1163:        for (start = syspath; *start != '\0'; start = cp) {
                   1164:                for (cp = start; *cp != '\0' && *cp != ':'; cp++)
                   1165:                        continue;
                   1166:                if (*cp == ':') {
                   1167:                        *cp++ = '\0';
                   1168:                }
                   1169:                /* look for magic parent directory search string */
                   1170:                if (strncmp(".../", start, 4) != 0) {
1.409     rillig   1171:                        (void)Dir_AddDir(defSysIncPath, start);
1.397     rillig   1172:                } else {
                   1173:                        char *dir = Dir_FindHereOrAbove(curdir, start + 4);
                   1174:                        if (dir != NULL) {
1.409     rillig   1175:                                (void)Dir_AddDir(defSysIncPath, dir);
1.397     rillig   1176:                                free(dir);
                   1177:                        }
                   1178:                }
                   1179:        }
                   1180:
                   1181:        if (syspath != defsyspath)
                   1182:                free(syspath);
                   1183: }
                   1184:
1.398     rillig   1185: static void
                   1186: ReadBuiltinRules(void)
                   1187: {
                   1188:        StringList *sysMkPath = Lst_New();
                   1189:        Dir_Expand(_PATH_DEFSYSMK,
1.409     rillig   1190:                   Lst_IsEmpty(sysIncPath) ? defSysIncPath : sysIncPath,
1.398     rillig   1191:                   sysMkPath);
                   1192:        if (Lst_IsEmpty(sysMkPath))
                   1193:                Fatal("%s: no system rules (%s).", progname, _PATH_DEFSYSMK);
                   1194:        if (!Lst_ForEachUntil(sysMkPath, ReadMakefileSucceeded, NULL))
                   1195:                Fatal("%s: cannot open %s.", progname,
                   1196:                      (char *)sysMkPath->first->datum);
                   1197:        /* XXX: sysMkPath is not freed */
                   1198: }
                   1199:
1.408     rillig   1200: static void
                   1201: InitMaxJobs(void)
                   1202: {
                   1203:        char *value;
                   1204:        int n;
                   1205:
                   1206:        if (forceJobs || opts.compatMake ||
                   1207:            !Var_Exists(".MAKE.JOBS", VAR_GLOBAL))
                   1208:                return;
                   1209:
                   1210:        (void)Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES, &value);
                   1211:        /* TODO: handle errors */
                   1212:        n = (int)strtol(value, NULL, 0);
                   1213:        if (n < 1) {
                   1214:                (void)fprintf(stderr,
                   1215:                              "%s: illegal value for .MAKE.JOBS "
                   1216:                              "-- must be positive integer!\n",
                   1217:                              progname);
                   1218:                exit(1);
                   1219:        }
                   1220:
                   1221:        if (n != opts.maxJobs) {
                   1222:                Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
                   1223:                Var_Append(MAKEFLAGS, value, VAR_GLOBAL);
                   1224:        }
                   1225:
                   1226:        opts.maxJobs = n;
                   1227:        maxJobTokens = opts.maxJobs;
                   1228:        forceJobs = TRUE;
                   1229:        free(value);
                   1230: }
                   1231:
1.400     rillig   1232: /*
                   1233:  * For compatibility, look at the directories in the VPATH variable
                   1234:  * and add them to the search path, if the variable is defined. The
                   1235:  * variable's value is in the same format as the PATH environment
                   1236:  * variable, i.e. <directory>:<directory>:<directory>...
                   1237:  */
                   1238: static void
                   1239: InitVpath(void)
                   1240: {
                   1241:        char *vpath, savec, *path;
1.410     rillig   1242:        if (!Var_Exists("VPATH", VAR_CMDLINE))
1.400     rillig   1243:                return;
                   1244:
1.410     rillig   1245:        (void)Var_Subst("${VPATH}", VAR_CMDLINE, VARE_WANTRES, &vpath);
1.400     rillig   1246:        /* TODO: handle errors */
                   1247:        path = vpath;
                   1248:        do {
                   1249:                char *cp;
                   1250:                /* skip to end of directory */
                   1251:                for (cp = path; *cp != ':' && *cp != '\0'; cp++)
                   1252:                        continue;
                   1253:                /* Save terminator character so know when to stop */
                   1254:                savec = *cp;
                   1255:                *cp = '\0';
                   1256:                /* Add directory to search path */
                   1257:                (void)Dir_AddDir(dirSearchPath, path);
                   1258:                *cp = savec;
                   1259:                path = cp + 1;
                   1260:        } while (savec == ':');
                   1261:        free(vpath);
                   1262: }
                   1263:
1.402     rillig   1264: static void
1.403     rillig   1265: ReadMakefiles(void)
                   1266: {
                   1267:        if (opts.makefiles->first != NULL) {
                   1268:                StringListNode *ln;
                   1269:
                   1270:                for (ln = opts.makefiles->first; ln != NULL; ln = ln->next) {
                   1271:                        if (ReadMakefile(ln->datum) != 0)
                   1272:                                Fatal("%s: cannot open %s.",
                   1273:                                      progname, (char *)ln->datum);
                   1274:                }
                   1275:        } else {
                   1276:                char *p1;
                   1277:                (void)Var_Subst("${" MAKEFILE_PREFERENCE "}",
1.410     rillig   1278:                                VAR_CMDLINE, VARE_WANTRES, &p1);
1.403     rillig   1279:                /* TODO: handle errors */
                   1280:                (void)str2Lst_Append(opts.makefiles, p1, NULL);
                   1281:                (void)Lst_ForEachUntil(opts.makefiles,
                   1282:                                       ReadMakefileSucceeded, NULL);
                   1283:                free(p1);
                   1284:        }
                   1285: }
                   1286:
                   1287: static void
1.402     rillig   1288: CleanUp(void)
                   1289: {
                   1290: #ifdef CLEANUP
                   1291:        Lst_Destroy(opts.variables, free);
                   1292:        Lst_Free(opts.makefiles);       /* don't free, may be used in GNodes */
                   1293:        Lst_Destroy(opts.create, free);
                   1294: #endif
                   1295:
                   1296:        /* print the graph now it's been processed if the user requested it */
                   1297:        if (DEBUG(GRAPH2))
                   1298:                Targ_PrintGraph(2);
                   1299:
                   1300:        Trace_Log(MAKEEND, 0);
                   1301:
                   1302:        if (enterFlagObj)
                   1303:                printf("%s: Leaving directory `%s'\n", progname, objdir);
                   1304:        if (opts.enterFlag)
                   1305:                printf("%s: Leaving directory `%s'\n", progname, curdir);
                   1306:
                   1307: #ifdef USE_META
                   1308:        meta_finish();
                   1309: #endif
                   1310:        Suff_End();
                   1311:        Targ_End();
                   1312:        Arch_End();
                   1313:        Var_End();
                   1314:        Parse_End();
                   1315:        Dir_End();
                   1316:        Job_End();
                   1317:        Trace_End();
                   1318: }
                   1319:
1.1       cgd      1320: /*-
                   1321:  * main --
                   1322:  *     The main function, for obvious reasons. Initializes variables
                   1323:  *     and a few modules, then parses the arguments give it in the
                   1324:  *     environment and on the command line. Reads the system makefile
                   1325:  *     followed by either Makefile, makefile or the file given by the
                   1326:  *     -f argument. Sets the .MAKEFLAGS PMake variable based on all the
                   1327:  *     flags it has received by then uses either the Make or the Compat
                   1328:  *     module to create the initial list of targets.
                   1329:  *
                   1330:  * Results:
                   1331:  *     If -q was given, exits -1 if anything was out-of-date. Else it exits
                   1332:  *     0.
                   1333:  *
                   1334:  * Side Effects:
                   1335:  *     The program exits when done. Targets are created. etc. etc. etc.
                   1336:  */
1.13      cgd      1337: int
1.85      wiz      1338: main(int argc, char **argv)
1.1       cgd      1339: {
1.351     rillig   1340:        Boolean outOfDate;      /* FALSE if all targets up to date */
1.381     rillig   1341:        struct stat sa;
1.369     rillig   1342:        const char *machine;
                   1343:        const char *machine_arch;
1.55      sjg      1344:        char *syspath = getenv("MAKESYSPATH");
1.119     tsutsui  1345:        struct utsname utsname;
1.107     sjg      1346:
1.154     apb      1347:        /* default to writing debug to stderr */
1.391     rillig   1348:        opts.debug_file = stderr;
1.133     dsl      1349:
1.167     christos 1350: #ifdef SIGINFO
1.188     sjg      1351:        (void)bmake_signal(SIGINFO, siginfo);
1.167     christos 1352: #endif
1.404     rillig   1353:
                   1354:        InitRandom();
1.277     rillig   1355:
1.53      christos 1356:        if ((progname = strrchr(argv[0], '/')) != NULL)
                   1357:                progname++;
                   1358:        else
                   1359:                progname = argv[0];
1.393     rillig   1360:
                   1361:        UnlimitFiles();
1.13      cgd      1362:
1.206     christos 1363:        if (uname(&utsname) == -1) {
                   1364:            (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
                   1365:                strerror(errno));
                   1366:            exit(2);
                   1367:        }
                   1368:
1.17      gwr      1369:        /*
                   1370:         * Get the name of this type of MACHINE from utsname
                   1371:         * so we can share an executable for similar machines.
                   1372:         * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
                   1373:         *
1.33      christos 1374:         * Note that both MACHINE and MACHINE_ARCH are decided at
                   1375:         * run-time.
1.17      gwr      1376:         */
1.369     rillig   1377:        machine = init_machine(&utsname);
                   1378:        machine_arch = init_machine_arch();
1.33      christos 1379:
1.183     sjg      1380:        myPid = getpid();               /* remember this for vFork() */
                   1381:
1.1       cgd      1382:        /*
1.51      sjg      1383:         * Just in case MAKEOBJDIR wants us to do something tricky.
                   1384:         */
                   1385:        Var_Init();             /* Initialize the lists of variables for
                   1386:                                 * parsing arguments */
1.277     rillig   1387:        Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL);
                   1388:        Var_Set("MACHINE", machine, VAR_GLOBAL);
                   1389:        Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
1.170     perry    1390: #ifdef MAKE_VERSION
1.277     rillig   1391:        Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
1.170     perry    1392: #endif
1.277     rillig   1393:        Var_Set(".newline", "\n", VAR_GLOBAL); /* handy for :@ loops */
1.176     sjg      1394:        /*
                   1395:         * This is the traditional preference for makefiles.
                   1396:         */
                   1397: #ifndef MAKEFILE_PREFERENCE_LIST
                   1398: # define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
                   1399: #endif
                   1400:        Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
1.277     rillig   1401:                VAR_GLOBAL);
                   1402:        Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
1.51      sjg      1403:
1.395     rillig   1404:        CmdOpts_Init();
1.1       cgd      1405:        allPrecious = FALSE;            /* Remove targets when interrupted */
1.251     dholland 1406:        deleteOnError = FALSE;          /* Historical default behavior */
1.1       cgd      1407:        jobsRunning = FALSE;
                   1408:
1.391     rillig   1409:        maxJobTokens = opts.maxJobs;
1.174     sjg      1410:        ignorePWD = FALSE;
1.13      cgd      1411:
1.1       cgd      1412:        /*
                   1413:         * Initialize the parsing, directory and variable modules to prepare
                   1414:         * for the reading of inclusion paths and variable settings on the
                   1415:         * command line
                   1416:         */
1.36      gwr      1417:
                   1418:        /*
1.1       cgd      1419:         * Initialize various variables.
                   1420:         *      MAKE also gets this name, for compatibility
                   1421:         *      .MAKEFLAGS gets set to the empty string just in case.
                   1422:         *      MFLAGS also gets initialized empty, for compatibility.
                   1423:         */
1.79      tv       1424:        Parse_Init();
1.406     rillig   1425:        InitVarMake(argv[0]);
1.277     rillig   1426:        Var_Set(MAKEFLAGS, "", VAR_GLOBAL);
                   1427:        Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL);
                   1428:        Var_Set("MFLAGS", "", VAR_GLOBAL);
                   1429:        Var_Set(".ALLTARGETS", "", VAR_GLOBAL);
1.217     sjg      1430:        /* some makefiles need to know this */
1.410     rillig   1431:        Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMDLINE);
1.1       cgd      1432:
                   1433:        /*
1.142     sjg      1434:         * Set some other useful macros
                   1435:         */
                   1436:        {
1.213     christos 1437:            char tmp[64], *ep;
1.142     sjg      1438:
1.220     christos 1439:            makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0;
                   1440:            if (makelevel < 0)
                   1441:                makelevel = 0;
                   1442:            snprintf(tmp, sizeof(tmp), "%d", makelevel);
1.277     rillig   1443:            Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL);
1.183     sjg      1444:            snprintf(tmp, sizeof(tmp), "%u", myPid);
1.277     rillig   1445:            Var_Set(".MAKE.PID", tmp, VAR_GLOBAL);
1.149     christos 1446:            snprintf(tmp, sizeof(tmp), "%u", getppid());
1.277     rillig   1447:            Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL);
1.142     sjg      1448:        }
1.220     christos 1449:        if (makelevel > 0) {
                   1450:                char pn[1024];
                   1451:                snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel);
1.221     christos 1452:                progname = bmake_strdup(pn);
1.220     christos 1453:        }
1.142     sjg      1454:
1.210     sjg      1455: #ifdef USE_META
                   1456:        meta_init();
                   1457: #endif
1.306     rillig   1458:        Dir_Init();
1.255     sjg      1459:
1.142     sjg      1460:        /*
1.1       cgd      1461:         * First snag any flags out of the MAKE environment variable.
                   1462:         * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
                   1463:         * in a different format).
                   1464:         */
                   1465: #ifdef POSIX
1.412     rillig   1466:        {
                   1467:            char *p1 = explode(getenv("MAKEFLAGS"));
                   1468:            Main_ParseArgLine(p1);
                   1469:            free(p1);
                   1470:        }
1.1       cgd      1471: #else
                   1472:        Main_ParseArgLine(getenv("MAKE"));
                   1473: #endif
1.31      christos 1474:
1.1       cgd      1475:        /*
1.175     sjg      1476:         * Find where we are (now).
                   1477:         * We take care of PWD for the automounter below...
1.174     sjg      1478:         */
                   1479:        if (getcwd(curdir, MAXPATHLEN) == NULL) {
1.194     dholland 1480:                (void)fprintf(stderr, "%s: getcwd: %s.\n",
                   1481:                    progname, strerror(errno));
1.174     sjg      1482:                exit(2);
                   1483:        }
                   1484:
1.175     sjg      1485:        MainParseArgs(argc, argv);
                   1486:
1.391     rillig   1487:        if (opts.enterFlag)
1.220     christos 1488:                printf("%s: Entering directory `%s'\n", progname, curdir);
                   1489:
1.175     sjg      1490:        /*
                   1491:         * Verify that cwd is sane.
                   1492:         */
1.174     sjg      1493:        if (stat(curdir, &sa) == -1) {
                   1494:            (void)fprintf(stderr, "%s: %s: %s.\n",
                   1495:                 progname, curdir, strerror(errno));
                   1496:            exit(2);
                   1497:        }
                   1498:
1.222     sjg      1499: #ifndef NO_PWD_OVERRIDE
1.381     rillig   1500:        HandlePWD(&sa);
1.222     sjg      1501: #endif
1.277     rillig   1502:        Var_Set(".CURDIR", curdir, VAR_GLOBAL);
1.174     sjg      1503:
1.407     rillig   1504:        InitObjdir(machine, machine_arch);
1.174     sjg      1505:
                   1506:        /*
1.1       cgd      1507:         * Initialize archive, target and suffix modules in preparation for
                   1508:         * parsing the makefile(s)
                   1509:         */
                   1510:        Arch_Init();
                   1511:        Targ_Init();
                   1512:        Suff_Init();
1.58      sommerfe 1513:        Trace_Init(tracefile);
1.1       cgd      1514:
1.157     dsl      1515:        DEFAULT = NULL;
1.1       cgd      1516:        (void)time(&now);
                   1517:
1.58      sommerfe 1518:        Trace_Log(MAKESTART, NULL);
1.279     rillig   1519:
1.343     rillig   1520:        InitVarTargets();
1.25      christos 1521:
1.409     rillig   1522:        InitDefSysIncPath(syspath);
1.25      christos 1523:
                   1524:        /*
                   1525:         * Read in the built-in rules first, followed by the specified
1.325     rillig   1526:         * makefiles, or the default makefile and Makefile, in that order,
                   1527:         * if no makefiles were given on the command line.
1.25      christos 1528:         */
1.398     rillig   1529:        if (!opts.noBuiltins)
                   1530:                ReadBuiltinRules();
1.403     rillig   1531:        ReadMakefiles();
                   1532:
1.138     dsl      1533:        /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
1.391     rillig   1534:        if (!opts.noBuiltins || !opts.printVars) {
1.389     sjg      1535:            /* ignore /dev/null and anything starting with "no" */
                   1536:            (void)Var_Subst("${.MAKE.DEPENDFILE:N/dev/null:Nno*:T}",
1.410     rillig   1537:                            VAR_CMDLINE, VARE_WANTRES, &makeDependfile);
1.389     sjg      1538:            if (makeDependfile[0] != '\0') {
                   1539:                /* TODO: handle errors */
                   1540:                doing_depend = TRUE;
                   1541:                (void)ReadMakefile(makeDependfile);
                   1542:                doing_depend = FALSE;
                   1543:            }
1.145     dsl      1544:        }
1.1       cgd      1545:
1.233     sjg      1546:        if (enterFlagObj)
                   1547:                printf("%s: Entering directory `%s'\n", progname, objdir);
1.279     rillig   1548:
1.176     sjg      1549:        MakeMode(NULL);
                   1550:
1.412     rillig   1551:        {
                   1552:            void *freeIt;
                   1553:            Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &freeIt),
                   1554:                       VAR_GLOBAL);
                   1555:            bmake_free(freeIt);
                   1556:
                   1557:        }
1.1       cgd      1558:
1.408     rillig   1559:        InitMaxJobs();
1.243     matthias 1560:
                   1561:        /*
                   1562:         * Be compatible if user did not specify -j and did not explicitly
                   1563:         * turned compatibility on
                   1564:         */
1.391     rillig   1565:        if (!opts.compatMake && !forceJobs) {
                   1566:            opts.compatMake = TRUE;
1.243     matthias 1567:        }
                   1568:
1.391     rillig   1569:        if (!opts.compatMake)
1.132     dsl      1570:            Job_ServerStart(maxJobTokens, jp_0, jp_1);
1.352     rillig   1571:        DEBUG5(JOB, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
1.391     rillig   1572:               jp_0, jp_1, opts.maxJobs, maxJobTokens, opts.compatMake ? 1 : 0);
1.58      sommerfe 1573:
1.391     rillig   1574:        if (!opts.printVars)
1.255     sjg      1575:            Main_ExportMAKEFLAGS(TRUE); /* initial export */
1.279     rillig   1576:
1.400     rillig   1577:        InitVpath();
1.1       cgd      1578:
                   1579:        /*
                   1580:         * Now that all search paths have been read for suffixes et al, it's
                   1581:         * time to add the default search path to their lists...
                   1582:         */
                   1583:        Suff_DoPaths();
1.50      mycroft  1584:
                   1585:        /*
                   1586:         * Propagate attributes through :: dependency lists.
                   1587:         */
                   1588:        Targ_Propagate();
1.1       cgd      1589:
                   1590:        /* print the initial graph, if the user requested it */
                   1591:        if (DEBUG(GRAPH1))
                   1592:                Targ_PrintGraph(1);
                   1593:
1.31      christos 1594:        /* print the values of any variables requested by the user */
1.391     rillig   1595:        if (opts.printVars) {
1.266     christos 1596:                doPrintVars();
                   1597:                outOfDate = FALSE;
1.138     dsl      1598:        } else {
1.266     christos 1599:                outOfDate = runTargets();
1.31      christos 1600:        }
                   1601:
1.402     rillig   1602:        CleanUp();
1.14      jtc      1603:
1.421   ! rillig   1604:        if (DEBUG(LINT) && (errors > 0 || Parse_GetFatals() > 0))
        !          1605:            return 2;           /* Not 1 so -q can distinguish error */
1.137     dsl      1606:        return outOfDate ? 1 : 0;
1.1       cgd      1607: }
                   1608:
1.321     rillig   1609: /* Open and parse the given makefile, with all its side effects.
1.1       cgd      1610:  *
                   1611:  * Results:
1.124     sjg      1612:  *     0 if ok. -1 if couldn't open file.
1.1       cgd      1613:  */
1.124     sjg      1614: static int
1.325     rillig   1615: ReadMakefile(const char *fname)
1.1       cgd      1616: {
1.140     dsl      1617:        int fd;
1.304     rillig   1618:        char *name, *path = NULL;
1.1       cgd      1619:
                   1620:        if (!strcmp(fname, "-")) {
1.193     dholland 1621:                Parse_File(NULL /*stdin*/, -1);
1.277     rillig   1622:                Var_Set("MAKEFILE", "", VAR_INTERNAL);
1.1       cgd      1623:        } else {
                   1624:                /* if we've chdir'd, rebuild the path name */
1.74      tv       1625:                if (strcmp(curdir, objdir) && *fname != '/') {
1.304     rillig   1626:                        path = str_concat3(curdir, "/", fname);
1.140     dsl      1627:                        fd = open(path, O_RDONLY);
                   1628:                        if (fd != -1) {
1.1       cgd      1629:                                fname = path;
                   1630:                                goto found;
                   1631:                        }
1.309     rillig   1632:                        free(path);
1.279     rillig   1633:
1.95      jmc      1634:                        /* If curdir failed, try objdir (ala .depend) */
1.304     rillig   1635:                        path = str_concat3(objdir, "/", fname);
1.140     dsl      1636:                        fd = open(path, O_RDONLY);
                   1637:                        if (fd != -1) {
1.95      jmc      1638:                                fname = path;
                   1639:                                goto found;
                   1640:                        }
1.140     dsl      1641:                } else {
                   1642:                        fd = open(fname, O_RDONLY);
                   1643:                        if (fd != -1)
                   1644:                                goto found;
                   1645:                }
1.1       cgd      1646:                /* look in -I and system include directories. */
                   1647:                name = Dir_FindFile(fname, parseIncPath);
1.409     rillig   1648:                if (!name) {
                   1649:                        SearchPath *sysInc = Lst_IsEmpty(sysIncPath)
                   1650:                                             ? defSysIncPath : sysIncPath;
                   1651:                        name = Dir_FindFile(fname, sysInc);
                   1652:                }
1.140     dsl      1653:                if (!name || (fd = open(name, O_RDONLY)) == -1) {
1.238     christos 1654:                        free(name);
1.48      christos 1655:                        free(path);
1.278     rillig   1656:                        return -1;
1.48      christos 1657:                }
1.1       cgd      1658:                fname = name;
                   1659:                /*
                   1660:                 * set the MAKEFILE variable desired by System V fans -- the
                   1661:                 * placement of the setting here means it gets set to the last
                   1662:                 * makefile specified, as it is set by SysV make.
                   1663:                 */
1.67      sjg      1664: found:
1.176     sjg      1665:                if (!doing_depend)
1.277     rillig   1666:                        Var_Set("MAKEFILE", fname, VAR_INTERNAL);
1.140     dsl      1667:                Parse_File(fname, fd);
1.1       cgd      1668:        }
1.48      christos 1669:        free(path);
1.278     rillig   1670:        return 0;
1.54      sjg      1671: }
                   1672:
                   1673:
1.29      christos 1674:
                   1675: /*-
                   1676:  * Cmd_Exec --
                   1677:  *     Execute the command in cmd, and return the output of that command
1.302     rillig   1678:  *     in a string.  In the output, newlines are replaced with spaces.
1.29      christos 1679:  *
                   1680:  * Results:
1.293     rillig   1681:  *     A string containing the output of the command, or the empty string.
                   1682:  *     *errfmt returns a format string describing the command failure,
                   1683:  *     if any, using a single %s conversion specification.
1.29      christos 1684:  *
                   1685:  * Side Effects:
                   1686:  *     The string must be freed by the caller.
                   1687:  */
                   1688: char *
1.293     rillig   1689: Cmd_Exec(const char *cmd, const char **errfmt)
1.29      christos 1690: {
1.351     rillig   1691:     const char *args[4];       /* Args for invoking the shell */
                   1692:     int                fds[2];         /* Pipe streams */
                   1693:     int                cpid;           /* Child PID */
                   1694:     int                pid;            /* PID from wait() */
1.29      christos 1695:     int                status;         /* command exit status */
                   1696:     Buffer     buf;            /* buffer to store the result */
1.298     rillig   1697:     ssize_t    bytes_read;
                   1698:     char       *res;           /* result */
                   1699:     size_t     res_len;
1.29      christos 1700:     char       *cp;
1.231     dholland 1701:     int                savederr;       /* saved errno */
1.29      christos 1702:
1.293     rillig   1703:     *errfmt = NULL;
1.29      christos 1704:
1.90      sjg      1705:     if (!shellName)
                   1706:        Shell_Init();
1.29      christos 1707:     /*
                   1708:      * Set up arguments for shell
                   1709:      */
1.90      sjg      1710:     args[0] = shellName;
1.29      christos 1711:     args[1] = "-c";
                   1712:     args[2] = cmd;
                   1713:     args[3] = NULL;
                   1714:
                   1715:     /*
                   1716:      * Open a pipe for fetching its output
                   1717:      */
                   1718:     if (pipe(fds) == -1) {
1.293     rillig   1719:        *errfmt = "Couldn't create pipe for \"%s\"";
1.29      christos 1720:        goto bad;
                   1721:     }
                   1722:
                   1723:     /*
                   1724:      * Fork
                   1725:      */
1.183     sjg      1726:     switch (cpid = vFork()) {
1.29      christos 1727:     case 0:
                   1728:        /*
                   1729:         * Close input side of pipe
                   1730:         */
1.112     christos 1731:        (void)close(fds[0]);
1.29      christos 1732:
                   1733:        /*
                   1734:         * Duplicate the output stream to the shell's output, then
                   1735:         * shut the extra thing down. Note we don't fetch the error
                   1736:         * stream...why not? Why?
                   1737:         */
1.112     christos 1738:        (void)dup2(fds[1], 1);
                   1739:        (void)close(fds[1]);
1.31      christos 1740:
1.143     sjg      1741:        Var_ExportVars();
                   1742:
1.112     christos 1743:        (void)execv(shellPath, UNCONST(args));
1.29      christos 1744:        _exit(1);
                   1745:        /*NOTREACHED*/
                   1746:
                   1747:     case -1:
1.293     rillig   1748:        *errfmt = "Couldn't exec \"%s\"";
1.29      christos 1749:        goto bad;
                   1750:
                   1751:     default:
                   1752:        /*
                   1753:         * No need for the writing half
                   1754:         */
1.112     christos 1755:        (void)close(fds[1]);
1.31      christos 1756:
1.232     sjg      1757:        savederr = 0;
1.297     rillig   1758:        Buf_Init(&buf, 0);
1.29      christos 1759:
                   1760:        do {
                   1761:            char   result[BUFSIZ];
1.298     rillig   1762:            bytes_read = read(fds[0], result, sizeof(result));
                   1763:            if (bytes_read > 0)
                   1764:                Buf_AddBytes(&buf, result, (size_t)bytes_read);
1.29      christos 1765:        }
1.298     rillig   1766:        while (bytes_read > 0 || (bytes_read == -1 && errno == EINTR));
                   1767:        if (bytes_read == -1)
1.231     dholland 1768:            savederr = errno;
1.29      christos 1769:
                   1770:        /*
                   1771:         * Close the input side of the pipe.
                   1772:         */
1.112     christos 1773:        (void)close(fds[0]);
1.29      christos 1774:
                   1775:        /*
                   1776:         * Wait for the process to exit.
                   1777:         */
1.189     sjg      1778:        while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) {
                   1779:            JobReapChild(pid, status, FALSE);
1.29      christos 1780:            continue;
1.189     sjg      1781:        }
1.350     rillig   1782:        res_len = Buf_Len(&buf);
1.163     dsl      1783:        res = Buf_Destroy(&buf, FALSE);
1.29      christos 1784:
1.231     dholland 1785:        if (savederr != 0)
1.293     rillig   1786:            *errfmt = "Couldn't read shell's output for \"%s\"";
1.29      christos 1787:
1.172     dholland 1788:        if (WIFSIGNALED(status))
1.293     rillig   1789:            *errfmt = "\"%s\" exited on a signal";
1.172     dholland 1790:        else if (WEXITSTATUS(status) != 0)
1.293     rillig   1791:            *errfmt = "\"%s\" returned non-zero status";
1.29      christos 1792:
1.299     rillig   1793:        /* Convert newlines to spaces.  A final newline is just stripped */
1.300     rillig   1794:        if (res_len > 0 && res[res_len - 1] == '\n')
                   1795:            res[res_len - 1] = '\0';
                   1796:        for (cp = res; *cp != '\0'; cp++)
1.299     rillig   1797:            if (*cp == '\n')
1.29      christos 1798:                *cp = ' ';
                   1799:        break;
                   1800:     }
                   1801:     return res;
                   1802: bad:
1.293     rillig   1803:     return bmake_strdup("");
1.1       cgd      1804: }
                   1805:
1.369     rillig   1806: /* Print a printf-style error message.
1.1       cgd      1807:  *
1.369     rillig   1808:  * This error message has no consequences, in particular it does not affect
                   1809:  * the exit status. */
1.1       cgd      1810: void
1.89      christos 1811: Error(const char *fmt, ...)
1.1       cgd      1812: {
                   1813:        va_list ap;
1.162     dsl      1814:        FILE *err_file;
1.85      wiz      1815:
1.391     rillig   1816:        err_file = opts.debug_file;
1.162     dsl      1817:        if (err_file == stdout)
                   1818:                err_file = stderr;
1.184     sjg      1819:        (void)fflush(stdout);
1.162     dsl      1820:        for (;;) {
                   1821:                va_start(ap, fmt);
                   1822:                fprintf(err_file, "%s: ", progname);
                   1823:                (void)vfprintf(err_file, fmt, ap);
                   1824:                va_end(ap);
                   1825:                (void)fprintf(err_file, "\n");
                   1826:                (void)fflush(err_file);
                   1827:                if (err_file == stderr)
                   1828:                        break;
                   1829:                err_file = stderr;
                   1830:        }
1.421   ! rillig   1831:        errors++;
1.1       cgd      1832: }
                   1833:
1.334     rillig   1834: /* Produce a Fatal error message, then exit immediately.
1.1       cgd      1835:  *
1.418     rillig   1836:  * If jobs are running, wait for them to finish. */
1.1       cgd      1837: void
1.89      christos 1838: Fatal(const char *fmt, ...)
1.1       cgd      1839: {
                   1840:        va_list ap;
1.85      wiz      1841:
1.13      cgd      1842:        va_start(ap, fmt);
1.1       cgd      1843:        if (jobsRunning)
                   1844:                Job_Wait();
                   1845:
1.184     sjg      1846:        (void)fflush(stdout);
1.1       cgd      1847:        (void)vfprintf(stderr, fmt, ap);
                   1848:        va_end(ap);
                   1849:        (void)fprintf(stderr, "\n");
                   1850:        (void)fflush(stderr);
                   1851:
1.176     sjg      1852:        PrintOnError(NULL, NULL);
1.67      sjg      1853:
1.94      dsl      1854:        if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
1.1       cgd      1855:                Targ_PrintGraph(2);
1.58      sommerfe 1856:        Trace_Log(MAKEERROR, 0);
1.1       cgd      1857:        exit(2);                /* Not 1 so -q can distinguish error */
                   1858: }
                   1859:
1.392     rillig   1860: /* Major exception once jobs are being created.
                   1861:  * Kills all jobs, prints a message and exits. */
1.1       cgd      1862: void
1.89      christos 1863: Punt(const char *fmt, ...)
1.1       cgd      1864: {
                   1865:        va_list ap;
1.85      wiz      1866:
1.13      cgd      1867:        va_start(ap, fmt);
1.184     sjg      1868:        (void)fflush(stdout);
1.63      christos 1869:        (void)fprintf(stderr, "%s: ", progname);
1.1       cgd      1870:        (void)vfprintf(stderr, fmt, ap);
                   1871:        va_end(ap);
                   1872:        (void)fprintf(stderr, "\n");
                   1873:        (void)fflush(stderr);
                   1874:
1.176     sjg      1875:        PrintOnError(NULL, NULL);
1.67      sjg      1876:
1.1       cgd      1877:        DieHorribly();
                   1878: }
                   1879:
1.392     rillig   1880: /* Exit without giving a message. */
1.1       cgd      1881: void
1.85      wiz      1882: DieHorribly(void)
1.1       cgd      1883: {
                   1884:        if (jobsRunning)
                   1885:                Job_AbortAll();
                   1886:        if (DEBUG(GRAPH2))
                   1887:                Targ_PrintGraph(2);
1.58      sommerfe 1888:        Trace_Log(MAKEERROR, 0);
1.1       cgd      1889:        exit(2);                /* Not 1, so -q can distinguish error */
                   1890: }
                   1891:
1.392     rillig   1892: /* Called when aborting due to errors in child shell to signal abnormal exit.
                   1893:  * The program exits.
                   1894:  * Errors is the number of errors encountered in Make_Make. */
1.1       cgd      1895: void
1.421   ! rillig   1896: Finish(int errs)
1.1       cgd      1897: {
1.275     sjg      1898:        if (dieQuietly(NULL, -1))
                   1899:                exit(2);
1.421   ! rillig   1900:        Fatal("%d error%s", errs, errs == 1 ? "" : "s");
1.1       cgd      1901: }
                   1902:
1.21      christos 1903: /*
1.208     dholland 1904:  * eunlink --
1.21      christos 1905:  *     Remove a file carefully, avoiding directories.
                   1906:  */
                   1907: int
1.85      wiz      1908: eunlink(const char *file)
1.21      christos 1909: {
                   1910:        struct stat st;
                   1911:
                   1912:        if (lstat(file, &st) == -1)
                   1913:                return -1;
                   1914:
                   1915:        if (S_ISDIR(st.st_mode)) {
                   1916:                errno = EISDIR;
                   1917:                return -1;
                   1918:        }
                   1919:        return unlink(file);
1.1       cgd      1920: }
                   1921:
1.373     rillig   1922: static void
                   1923: write_all(int fd, const void *data, size_t n)
                   1924: {
                   1925:        const char *mem = data;
                   1926:
                   1927:        while (n > 0) {
                   1928:                ssize_t written = write(fd, mem, n);
                   1929:                if (written == -1 && errno == EAGAIN)
                   1930:                        continue;
                   1931:                if (written == -1)
                   1932:                        break;
                   1933:                mem += written;
1.375     rillig   1934:                n -= (size_t)written;
1.373     rillig   1935:        }
                   1936: }
                   1937:
1.1       cgd      1938: /*
1.372     rillig   1939:  * execDie --
1.66      christos 1940:  *     Print why exec failed, avoiding stdio.
                   1941:  */
1.372     rillig   1942: void MAKE_ATTR_DEAD
                   1943: execDie(const char *af, const char *av)
1.66      christos 1944: {
1.373     rillig   1945:        Buffer buf;
                   1946:
                   1947:        Buf_Init(&buf, 0);
                   1948:        Buf_AddStr(&buf, progname);
                   1949:        Buf_AddStr(&buf, ": ");
                   1950:        Buf_AddStr(&buf, af);
                   1951:        Buf_AddStr(&buf, "(");
                   1952:        Buf_AddStr(&buf, av);
                   1953:        Buf_AddStr(&buf, ") failed (");
                   1954:        Buf_AddStr(&buf, strerror(errno));
                   1955:        Buf_AddStr(&buf, ")\n");
1.66      christos 1956:
1.373     rillig   1957:        write_all(STDERR_FILENO, Buf_GetAll(&buf, NULL), Buf_Len(&buf));
1.66      christos 1958:
1.373     rillig   1959:        Buf_Destroy(&buf, TRUE);
1.372     rillig   1960:        _exit(1);
1.66      christos 1961: }
                   1962:
                   1963: /*
1.1       cgd      1964:  * usage --
                   1965:  *     exit with usage message
                   1966:  */
1.13      cgd      1967: static void
1.85      wiz      1968: usage(void)
1.1       cgd      1969: {
1.220     christos 1970:        char *p;
                   1971:        if ((p = strchr(progname, '[')) != NULL)
1.292     rillig   1972:                *p = '\0';
1.220     christos 1973:
1.1       cgd      1974:        (void)fprintf(stderr,
1.292     rillig   1975: "usage: %s [-BeikNnqrstWwX] \n"
                   1976: "            [-C directory] [-D variable] [-d flags] [-f makefile]\n"
                   1977: "            [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n"
                   1978: "            [-V variable] [-v variable] [variable=value] [target ...]\n",
1.272     christos 1979:            progname);
1.1       cgd      1980:        exit(2);
1.14      jtc      1981: }
                   1982:
1.245     sjg      1983: /*
                   1984:  * realpath(3) can get expensive, cache results...
                   1985:  */
1.262     riastrad 1986: static GNode *cached_realpaths = NULL;
                   1987:
                   1988: static GNode *
                   1989: get_cached_realpaths(void)
                   1990: {
                   1991:
                   1992:     if (!cached_realpaths) {
                   1993:        cached_realpaths = Targ_NewGN("Realpath");
                   1994: #ifndef DEBUG_REALPATH_CACHE
                   1995:        cached_realpaths->flags = INTERNAL;
                   1996: #endif
                   1997:     }
                   1998:
                   1999:     return cached_realpaths;
                   2000: }
                   2001:
                   2002: /* purge any relative paths */
                   2003: static void
                   2004: purge_cached_realpaths(void)
                   2005: {
                   2006:     GNode *cache = get_cached_realpaths();
1.376     rillig   2007:     HashEntry *he, *nhe;
1.374     rillig   2008:     HashIter hi;
1.262     riastrad 2009:
1.374     rillig   2010:     HashIter_Init(&hi, &cache->context);
                   2011:     he = HashIter_Next(&hi);
                   2012:     while (he != NULL) {
                   2013:        nhe = HashIter_Next(&hi);
1.377     rillig   2014:        if (he->key[0] != '/') {
1.262     riastrad 2015:            if (DEBUG(DIR))
1.377     rillig   2016:                fprintf(stderr, "cached_realpath: purging %s\n", he->key);
1.390     rillig   2017:            HashTable_DeleteEntry(&cache->context, he);
1.262     riastrad 2018:        }
                   2019:        he = nhe;
                   2020:     }
                   2021: }
                   2022:
1.245     sjg      2023: char *
                   2024: cached_realpath(const char *pathname, char *resolved)
                   2025: {
1.262     riastrad 2026:     GNode *cache;
1.289     rillig   2027:     const char *rp;
1.412     rillig   2028:     void *freeIt;
1.245     sjg      2029:
                   2030:     if (!pathname || !pathname[0])
                   2031:        return NULL;
                   2032:
1.262     riastrad 2033:     cache = get_cached_realpaths();
                   2034:
1.412     rillig   2035:     if ((rp = Var_Value(pathname, cache, &freeIt)) != NULL) {
1.245     sjg      2036:        /* a hit */
1.248     christos 2037:        strncpy(resolved, rp, MAXPATHLEN);
                   2038:        resolved[MAXPATHLEN - 1] = '\0';
                   2039:     } else if ((rp = realpath(pathname, resolved)) != NULL) {
1.277     rillig   2040:        Var_Set(pathname, rp, cache);
1.248     christos 2041:     } /* else should we negative-cache? */
                   2042:
1.412     rillig   2043:     bmake_free(freeIt);
1.245     sjg      2044:     return rp ? resolved : NULL;
                   2045: }
                   2046:
1.275     sjg      2047: /*
                   2048:  * Return true if we should die without noise.
                   2049:  * For example our failing child was a sub-make
                   2050:  * or failure happend elsewhere.
                   2051:  */
                   2052: int
                   2053: dieQuietly(GNode *gn, int bf)
                   2054: {
                   2055:     static int quietly = -1;
                   2056:
                   2057:     if (quietly < 0) {
1.417     rillig   2058:        if (DEBUG(JOB) || !getBoolean(".MAKE.DIE_QUIETLY", TRUE))
1.275     sjg      2059:            quietly = 0;
                   2060:        else if (bf >= 0)
                   2061:            quietly = bf;
                   2062:        else
1.380     rillig   2063:            quietly = gn != NULL ? ((gn->type  & (OP_MAKE)) != 0) : 0;
1.275     sjg      2064:     }
                   2065:     return quietly;
                   2066: }
                   2067:
1.385     rillig   2068: static void
                   2069: SetErrorVars(GNode *gn)
                   2070: {
                   2071:     StringListNode *ln;
                   2072:
                   2073:     /*
                   2074:      * We can print this even if there is no .ERROR target.
                   2075:      */
                   2076:     Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL);
                   2077:     Var_Delete(".ERROR_CMD", VAR_GLOBAL);
                   2078:
                   2079:     for (ln = gn->commands->first; ln != NULL; ln = ln->next) {
                   2080:        const char *cmd = ln->datum;
                   2081:
                   2082:        if (cmd == NULL)
                   2083:            break;
                   2084:        Var_Append(".ERROR_CMD", cmd, VAR_GLOBAL);
                   2085:     }
                   2086: }
                   2087:
1.67      sjg      2088: void
1.176     sjg      2089: PrintOnError(GNode *gn, const char *s)
1.67      sjg      2090: {
1.177     sjg      2091:     static GNode *en = NULL;
1.296     rillig   2092:     const char *expr;
                   2093:     char *cp;
1.128     sjg      2094:
1.283     sjg      2095:     if (DEBUG(HASH)) {
                   2096:        Targ_Stats();
                   2097:        Var_Stats();
                   2098:     }
                   2099:
1.275     sjg      2100:     /* we generally want to keep quiet if a sub-make died */
                   2101:     if (dieQuietly(gn, -1))
                   2102:        return;
                   2103:
1.67      sjg      2104:     if (s)
1.176     sjg      2105:        printf("%s", s);
1.279     rillig   2106:
1.67      sjg      2107:     printf("\n%s: stopped in %s\n", progname, curdir);
1.176     sjg      2108:
1.177     sjg      2109:     if (en)
                   2110:        return;                         /* we've been here! */
1.385     rillig   2111:     if (gn)
1.411     rillig   2112:        SetErrorVars(gn);
1.296     rillig   2113:     expr = "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}";
1.341     rillig   2114:     (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &cp);
                   2115:     /* TODO: handle errors */
1.329     rillig   2116:     printf("%s", cp);
                   2117:     free(cp);
1.235     sjg      2118:     fflush(stdout);
                   2119:
1.176     sjg      2120:     /*
1.186     sjg      2121:      * Finally, see if there is a .ERROR target, and run it if so.
1.176     sjg      2122:      */
1.346     rillig   2123:     en = Targ_FindNode(".ERROR");
1.176     sjg      2124:     if (en) {
                   2125:        en->type |= OP_SPECIAL;
                   2126:        Compat_Make(en, en);
                   2127:     }
1.68      sjg      2128: }
                   2129:
                   2130: void
1.85      wiz      2131: Main_ExportMAKEFLAGS(Boolean first)
1.68      sjg      2132: {
1.322     rillig   2133:     static Boolean once = TRUE;
1.296     rillig   2134:     const char *expr;
                   2135:     char *s;
1.68      sjg      2136:
                   2137:     if (once != first)
                   2138:        return;
1.322     rillig   2139:     once = FALSE;
1.279     rillig   2140:
1.296     rillig   2141:     expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
1.410     rillig   2142:     (void)Var_Subst(expr, VAR_CMDLINE, VARE_WANTRES, &s);
1.341     rillig   2143:     /* TODO: handle errors */
1.322     rillig   2144:     if (s[0] != '\0') {
1.68      sjg      2145: #ifdef POSIX
                   2146:        setenv("MAKEFLAGS", s, 1);
                   2147: #else
                   2148:        setenv("MAKE", s, 1);
                   2149: #endif
                   2150:     }
1.1       cgd      2151: }
1.180     sjg      2152:
1.191     sjg      2153: char *
                   2154: getTmpdir(void)
1.180     sjg      2155: {
                   2156:     static char *tmpdir = NULL;
                   2157:
                   2158:     if (!tmpdir) {
                   2159:        struct stat st;
                   2160:
                   2161:        /*
                   2162:         * Honor $TMPDIR but only if it is valid.
                   2163:         * Ensure it ends with /.
                   2164:         */
1.341     rillig   2165:        (void)Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
                   2166:                        VARE_WANTRES, &tmpdir);
                   2167:        /* TODO: handle errors */
1.180     sjg      2168:        if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
                   2169:            free(tmpdir);
                   2170:            tmpdir = bmake_strdup(_PATH_TMP);
                   2171:        }
                   2172:     }
1.191     sjg      2173:     return tmpdir;
                   2174: }
                   2175:
                   2176: /*
                   2177:  * Create and open a temp file using "pattern".
1.414     rillig   2178:  * If out_fname is provided, set it to a copy of the filename created.
1.191     sjg      2179:  * Otherwise unlink the file once open.
                   2180:  */
                   2181: int
1.414     rillig   2182: mkTempFile(const char *pattern, char **out_fname)
1.191     sjg      2183: {
                   2184:     static char *tmpdir = NULL;
                   2185:     char tfile[MAXPATHLEN];
                   2186:     int fd;
1.279     rillig   2187:
1.414     rillig   2188:     if (pattern != NULL)
1.191     sjg      2189:        pattern = TMPPAT;
1.414     rillig   2190:     if (tmpdir == NULL)
1.191     sjg      2191:        tmpdir = getTmpdir();
1.180     sjg      2192:     if (pattern[0] == '/') {
1.181     dholland 2193:        snprintf(tfile, sizeof(tfile), "%s", pattern);
1.180     sjg      2194:     } else {
                   2195:        snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern);
                   2196:     }
                   2197:     if ((fd = mkstemp(tfile)) < 0)
                   2198:        Punt("Could not create temporary file %s: %s", tfile, strerror(errno));
1.414     rillig   2199:     if (out_fname) {
                   2200:        *out_fname = bmake_strdup(tfile);
1.180     sjg      2201:     } else {
                   2202:        unlink(tfile);                  /* we just want the descriptor */
                   2203:     }
                   2204:     return fd;
                   2205: }
1.201     sjg      2206:
1.240     sjg      2207: /*
                   2208:  * Convert a string representation of a boolean.
                   2209:  * Anything that looks like "No", "False", "Off", "0" etc,
                   2210:  * is FALSE, otherwise TRUE.
                   2211:  */
                   2212: Boolean
                   2213: s2Boolean(const char *s, Boolean bf)
                   2214: {
1.416     rillig   2215:     switch(s[0]) {
                   2216:     case '\0':                 /* not set - the default wins */
                   2217:        break;
                   2218:     case '0':
                   2219:     case 'F':
                   2220:     case 'f':
                   2221:     case 'N':
                   2222:     case 'n':
                   2223:        return FALSE;
                   2224:     case 'O':
                   2225:     case 'o':
                   2226:        return s[1] != 'F' && s[1] != 'f';
                   2227:     default:
                   2228:        return TRUE;
1.240     sjg      2229:     }
1.278     rillig   2230:     return bf;
1.240     sjg      2231: }
1.201     sjg      2232:
                   2233: /*
1.417     rillig   2234:  * Return a Boolean based on a variable.
1.201     sjg      2235:  *
1.417     rillig   2236:  * If the knob is not set, return the fallback.
                   2237:  * If set, anything that looks or smells like "No", "False", "Off", "0", etc.
1.201     sjg      2238:  * is FALSE, otherwise TRUE.
                   2239:  */
                   2240: Boolean
1.417     rillig   2241: getBoolean(const char *varname, Boolean fallback)
1.201     sjg      2242: {
1.417     rillig   2243:     char *expr = str_concat3("${", varname, ":U}");
1.341     rillig   2244:     char *value;
                   2245:     Boolean res;
                   2246:
                   2247:     (void)Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES, &value);
                   2248:     /* TODO: handle errors */
                   2249:     res = s2Boolean(value, fallback);
1.328     rillig   2250:     free(value);
                   2251:     free(expr);
                   2252:     return res;
1.201     sjg      2253: }

CVSweb <webmaster@jp.NetBSD.org>