[BACK]Return to engine.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Annotation of src/usr.bin/make/engine.c, Revision 1.10

1.10    ! espie       1: /*     $OpenBSD$ */
1.1       espie       2: /*
                      3:  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
                      4:  * Copyright (c) 1988, 1989 by Adam de Boor
                      5:  * Copyright (c) 1989 by Berkeley Softworks
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to Berkeley by
                      9:  * Adam de Boor.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  */
                     35:
1.10    ! espie      36: #include <sys/types.h>
        !            37: #include <sys/wait.h>
1.1       espie      38: #include <limits.h>
                     39: #include <stdio.h>
1.10    ! espie      40: #include <stdlib.h>
        !            41: #include <ctype.h>
1.1       espie      42: #include <errno.h>
                     43: #include <fcntl.h>
                     44: #include <unistd.h>
                     45: #include <string.h>
1.10    ! espie      46: #include <signal.h>
1.1       espie      47: #include "config.h"
                     48: #include "defines.h"
                     49: #include "dir.h"
                     50: #include "engine.h"
                     51: #include "arch.h"
                     52: #include "gnode.h"
                     53: #include "targ.h"
                     54: #include "var.h"
                     55: #include "extern.h"
                     56: #include "lst.h"
                     57: #include "timestamp.h"
                     58: #include "make.h"
1.10    ! espie      59: #include "pathnames.h"
        !            60: #include "error.h"
        !            61: #include "str.h"
        !            62: #include "memory.h"
1.1       espie      63:
                     64: static void MakeTimeStamp(void *, void *);
                     65: static void MakeAddAllSrc(void *, void *);
1.6       espie      66: static int rewrite_time(const char *);
1.10    ! espie      67: static void setup_signal(int);
        !            68: static void setup_all_signals(void);
        !            69: static void setup_meta(void);
        !            70: static char **recheck_command_for_shell(char **);
        !            71:
        !            72: static int setup_and_run_command(char *, GNode *, int);
        !            73: static void run_command(const char *, bool);
        !            74: static void handle_compat_interrupts(GNode *);
1.1       espie      75:
                     76: bool
1.3       espie      77: Job_CheckCommands(GNode *gn, void (*abortProc)(char *, ...))
1.1       espie      78: {
1.3       espie      79:        if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) &&
1.9       espie      80:            (gn->type & (OP_NODEFAULT | OP_LIB)) == 0) {
1.3       espie      81:                /*
                     82:                 * No commands. Look for .DEFAULT rule from which we might infer
                     83:                 * commands
                     84:                 */
1.9       espie      85:                if ((DEFAULT->type & OP_DUMMY) == 0 &&
                     86:                    !Lst_IsEmpty(&DEFAULT->commands)) {
1.3       espie      87:                        /*
                     88:                         * Make only looks for a .DEFAULT if the node was never
                     89:                         * the target of an operator, so that's what we do too.
                     90:                         * If a .DEFAULT was given, we substitute its commands
                     91:                         * for gn's commands and set the IMPSRC variable to be
                     92:                         * the target's name The DEFAULT node acts like a
                     93:                         * transformation rule, in that gn also inherits any
                     94:                         * attributes or sources attached to .DEFAULT itself.
                     95:                         */
                     96:                        Make_HandleUse(DEFAULT, gn);
                     97:                        Varq_Set(IMPSRC_INDEX, Varq_Value(TARGET_INDEX, gn), gn);
                     98:                } else if (is_out_of_date(Dir_MTime(gn))) {
                     99:                        /*
                    100:                         * The node wasn't the target of an operator we have no
                    101:                         * .DEFAULT rule to go on and the target doesn't
                    102:                         * already exist. There's nothing more we can do for
                    103:                         * this branch. If the -k flag wasn't given, we stop in
                    104:                         * our tracks, otherwise we just don't update this
                    105:                         * node's parents so they never get examined.
                    106:                         */
1.5       espie     107:                        static const char msg[] =
1.3       espie     108:                            "make: don't know how to make";
                    109:
                    110:                        if (gn->type & OP_OPTIONAL) {
1.5       espie     111:                                (void)fprintf(stdout, "%s %s(ignored)\n", msg,
1.3       espie     112:                                    gn->name);
                    113:                                (void)fflush(stdout);
                    114:                        } else if (keepgoing) {
1.5       espie     115:                                (void)fprintf(stdout, "%s %s(continuing)\n",
1.3       espie     116:                                    msg, gn->name);
                    117:                                (void)fflush(stdout);
                    118:                                return false;
                    119:                        } else {
1.5       espie     120:                                (*abortProc)("%s %s. Stop in %s.", msg,
1.3       espie     121:                                    gn->name, Var_Value(".CURDIR"));
                    122:                                return false;
                    123:                        }
                    124:                }
1.1       espie     125:        }
1.3       espie     126:        return true;
1.1       espie     127: }
                    128:
1.6       espie     129: /* touch files the hard way, by writing stuff to them */
                    130: static int
                    131: rewrite_time(const char *name)
                    132: {
                    133:        int fd;
                    134:        char c;
                    135:
                    136:        fd = open(name, O_RDWR | O_CREAT, 0666);
                    137:        if (fd < 0)
                    138:                return -1;
                    139:        /*
                    140:         * Read and write a byte to the file to change
                    141:         * the modification time.
                    142:         */
                    143:        if (read(fd, &c, 1) == 1) {
                    144:                (void)lseek(fd, 0, SEEK_SET);
                    145:                (void)write(fd, &c, 1);
                    146:        }
                    147:
                    148:        (void)close(fd);
                    149:        return 0;
                    150: }
                    151:
1.1       espie     152: void
1.3       espie     153: Job_Touch(GNode *gn, bool silent)
1.1       espie     154: {
1.3       espie     155:        if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
                    156:                /*
1.9       espie     157:                 * .JOIN, .USE, and .OPTIONAL targets are "virtual" targets
                    158:                 * and, as such, shouldn't really be created.
1.3       espie     159:                 */
                    160:                return;
                    161:        }
1.1       espie     162:
1.3       espie     163:        if (!silent) {
                    164:                (void)fprintf(stdout, "touch %s\n", gn->name);
                    165:                (void)fflush(stdout);
                    166:        }
1.1       espie     167:
1.3       espie     168:        if (noExecute) {
                    169:                return;
                    170:        }
1.1       espie     171:
1.3       espie     172:        if (gn->type & OP_ARCHV) {
                    173:                Arch_Touch(gn);
                    174:        } else if (gn->type & OP_LIB) {
                    175:                Arch_TouchLib(gn);
                    176:        } else {
                    177:                const char *file = gn->path != NULL ? gn->path : gn->name;
                    178:
                    179:                if (set_times(file) == -1){
1.6       espie     180:                        if (rewrite_time(file) == -1) {
1.5       espie     181:                                (void)fprintf(stdout,
                    182:                                    "*** couldn't touch %s: %s", file,
1.3       espie     183:                                    strerror(errno));
                    184:                                (void)fflush(stdout);
1.9       espie     185:                        }
1.1       espie     186:                }
                    187:        }
                    188: }
                    189:
                    190: void
1.7       espie     191: Make_TimeStamp(GNode *parent, GNode *child)
1.1       espie     192: {
1.8       espie     193:        if (is_strictly_before(parent->cmtime, child->mtime))
                    194:                parent->cmtime = child->mtime;
1.1       espie     195: }
                    196:
                    197: void
1.9       espie     198: Make_HandleUse(GNode   *cgn,   /* The .USE node */
1.1       espie     199:     GNode      *pgn)   /* The target of the .USE node */
                    200: {
1.3       espie     201:        GNode   *gn;    /* A child of the .USE node */
                    202:        LstNode ln;     /* An element in the children list */
1.1       espie     203:
1.3       espie     204:        if (cgn->type & (OP_USE|OP_TRANSFORM)) {
                    205:                if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) {
1.9       espie     206:                        /* .USE or transformation and target has no commands
                    207:                         * -- append the child's commands to the parent.  */
1.3       espie     208:                        Lst_Concat(&pgn->commands, &cgn->commands);
                    209:                }
1.1       espie     210:
1.5       espie     211:                for (ln = Lst_First(&cgn->children); ln != NULL;
1.3       espie     212:                    ln = Lst_Adv(ln)) {
                    213:                        gn = (GNode *)Lst_Datum(ln);
                    214:
                    215:                        if (Lst_AddNew(&pgn->children, gn)) {
                    216:                                Lst_AtEnd(&gn->parents, pgn);
1.4       espie     217:                                pgn->unmade++;
1.3       espie     218:                        }
                    219:                }
1.1       espie     220:
1.3       espie     221:                pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM);
1.1       espie     222:
1.3       espie     223:                /*
                    224:                 * This child node is now "made", so we decrement the count of
                    225:                 * unmade children in the parent... We also remove the child
                    226:                 * from the parent's list to accurately reflect the number of
                    227:                 * decent children the parent has. This is used by Make_Run to
1.9       espie     228:                 * decide whether to queue the parent or examine its children...
1.3       espie     229:                 */
1.9       espie     230:                if (cgn->type & OP_USE)
1.3       espie     231:                        pgn->unmade--;
1.1       espie     232:        }
                    233: }
                    234:
                    235: static void
1.9       espie     236: MakeAddAllSrc(void *cgnp, void *pgnp)
1.1       espie     237: {
1.9       espie     238:        GNode   *child = (GNode *)cgnp;
                    239:        GNode   *parent = (GNode *)pgnp;
                    240:        if ((child->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
                    241:                const char *target;
1.3       espie     242:
1.9       espie     243:                if (OP_NOP(child->type) ||
                    244:                    (target = Varq_Value(TARGET_INDEX, child)) == NULL) {
1.3       espie     245:                        /*
                    246:                         * this node is only source; use the specific pathname
                    247:                         * for it
                    248:                         */
1.9       espie     249:                        target = child->path != NULL ? child->path :
                    250:                            child->name;
1.3       espie     251:                }
1.1       espie     252:
1.9       espie     253:                Varq_Append(ALLSRC_INDEX, target, parent);
                    254:                if (parent->type & OP_JOIN) {
                    255:                        if (child->made == MADE)
                    256:                                Varq_Append(OODATE_INDEX, target, parent);
                    257:                } else if (is_strictly_before(parent->mtime, child->mtime) ||
                    258:                   (!is_strictly_before(child->mtime, now) &&
                    259:                   child->made == MADE)) {
1.3       espie     260:                        /*
                    261:                         * It goes in the OODATE variable if the parent is
                    262:                         * younger than the child or if the child has been
                    263:                         * modified more recently than the start of the make.
1.9       espie     264:                         * This is to keep make from getting confused if
                    265:                         * something else updates the parent after the
                    266:                         * make starts (shouldn't happen, I know, but sometimes
                    267:                         * it does). In such a case, if we've updated the kid,
                    268:                         * the parent is likely to have a modification time
                    269:                         * later than that of the kid and anything that relies
                    270:                         * on the OODATE variable will be hosed.
1.3       espie     271:                         */
1.9       espie     272:                        Varq_Append(OODATE_INDEX, target, parent);
1.3       espie     273:                }
1.1       espie     274:        }
                    275: }
                    276:
                    277: void
                    278: Make_DoAllVar(GNode *gn)
                    279: {
1.3       espie     280:        Lst_ForEach(&gn->children, MakeAddAllSrc, gn);
1.1       espie     281:
1.3       espie     282:        if (Varq_Value(OODATE_INDEX, gn) == NULL)
                    283:                Varq_Set(OODATE_INDEX, "", gn);
                    284:        if (Varq_Value(ALLSRC_INDEX, gn) == NULL)
                    285:                Varq_Set(ALLSRC_INDEX, "", gn);
1.1       espie     286:
1.3       espie     287:        if (gn->type & OP_JOIN)
                    288:                Varq_Set(TARGET_INDEX, Varq_Value(ALLSRC_INDEX, gn), gn);
1.1       espie     289: }
                    290:
                    291: /* Wrapper to call Make_TimeStamp from a forEach loop. */
                    292: static void
1.9       espie     293: MakeTimeStamp(void *parent, void *child)
1.1       espie     294: {
1.9       espie     295:     Make_TimeStamp((GNode *)parent, (GNode *)child);
1.1       espie     296: }
                    297:
                    298: bool
1.9       espie     299: Make_OODate(GNode *gn)
1.1       espie     300: {
1.9       espie     301:        bool        oodate;
1.1       espie     302:
                    303:        /*
1.3       espie     304:         * Certain types of targets needn't even be sought as their datedness
                    305:         * doesn't depend on their modification time...
1.1       espie     306:         */
1.3       espie     307:        if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) {
                    308:                (void)Dir_MTime(gn);
                    309:                if (DEBUG(MAKE)) {
1.9       espie     310:                        if (!is_out_of_date(gn->mtime))
1.5       espie     311:                                printf("modified %s...",
1.3       espie     312:                                    time_to_string(gn->mtime));
1.9       espie     313:                        else
1.3       espie     314:                                printf("non-existent...");
                    315:                }
1.1       espie     316:        }
                    317:
                    318:        /*
1.3       espie     319:         * A target is remade in one of the following circumstances:
1.9       espie     320:         * - its modification time is smaller than that of its youngest child
                    321:         *   and it would actually be run (has commands or type OP_NOP)
                    322:         * - it's the object of a force operator
                    323:         * - it has no children, was on the lhs of an operator and doesn't
                    324:         *   exist already.
1.3       espie     325:         *
                    326:         * Libraries are only considered out-of-date if the archive module says
                    327:         * they are.
1.1       espie     328:         */
1.3       espie     329:        if (gn->type & OP_USE) {
                    330:                /*
                    331:                 * If the node is a USE node it is *never* out of date
                    332:                 * no matter *what*.
                    333:                 */
1.9       espie     334:                if (DEBUG(MAKE))
1.3       espie     335:                        printf(".USE node...");
                    336:                oodate = false;
                    337:        } else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) {
1.9       espie     338:                if (DEBUG(MAKE))
                    339:                    printf("library...");
1.3       espie     340:
1.9       espie     341:                /* always out of date if no children and :: target */
1.3       espie     342:                oodate = Arch_LibOODate(gn) ||
                    343:                    (is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP));
                    344:        } else if (gn->type & OP_JOIN) {
                    345:                /*
                    346:                 * A target with the .JOIN attribute is only considered
                    347:                 * out-of-date if any of its children was out-of-date.
                    348:                 */
1.9       espie     349:                if (DEBUG(MAKE))
1.3       espie     350:                        printf(".JOIN node...");
                    351:                oodate = gn->childMade;
                    352:        } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
                    353:                /*
1.9       espie     354:                 * A node which is the object of the force (!) operator or which
                    355:                 * has the .EXEC attribute is always considered out-of-date.
1.3       espie     356:                 */
                    357:                if (DEBUG(MAKE)) {
1.9       espie     358:                        if (gn->type & OP_FORCE)
1.3       espie     359:                                printf("! operator...");
1.9       espie     360:                        else if (gn->type & OP_PHONY)
1.3       espie     361:                                printf(".PHONY node...");
1.9       espie     362:                        else
1.3       espie     363:                                printf(".EXEC node...");
                    364:                }
                    365:                oodate = true;
                    366:        } else if (is_strictly_before(gn->mtime, gn->cmtime) ||
1.9       espie     367:           (is_out_of_date(gn->cmtime) &&
1.3       espie     368:            (is_out_of_date(gn->mtime) || (gn->type & OP_DOUBLEDEP)))) {
                    369:                /*
                    370:                 * A node whose modification time is less than that of its
                    371:                 * youngest child or that has no children (cmtime ==
                    372:                 * OUT_OF_DATE) and either doesn't exist (mtime == OUT_OF_DATE)
1.9       espie     373:                 * or was the object of a :: operator is out-of-date.
1.3       espie     374:                 */
                    375:                if (DEBUG(MAKE)) {
1.9       espie     376:                        if (is_strictly_before(gn->mtime, gn->cmtime))
1.3       espie     377:                                printf("modified before source...");
1.9       espie     378:                        else if (is_out_of_date(gn->mtime))
1.3       espie     379:                                printf("non-existent and no sources...");
1.9       espie     380:                        else
1.3       espie     381:                                printf(":: operator and no sources...");
                    382:                }
                    383:                oodate = true;
                    384:        } else {
                    385:                oodate = false;
                    386:        }
1.1       espie     387:
1.3       espie     388:        /*
                    389:         * If the target isn't out-of-date, the parents need to know its
                    390:         * modification time. Note that targets that appear to be out-of-date
                    391:         * but aren't, because they have no commands and aren't of type OP_NOP,
                    392:         * have their mtime stay below their children's mtime to keep parents
                    393:         * from thinking they're out-of-date.
                    394:         */
                    395:        if (!oodate)
                    396:                Lst_ForEach(&gn->parents, MakeTimeStamp, gn);
1.1       espie     397:
1.3       espie     398:        return oodate;
1.1       espie     399: }
                    400:
1.10    ! espie     401: volatile sig_atomic_t got_signal;
        !           402:
        !           403: volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT,
        !           404:     got_SIGTERM, got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, got_SIGWINCH;
        !           405:
        !           406: static void
        !           407: setup_signal(int sig)
        !           408: {
        !           409:        if (signal(sig, SIG_IGN) != SIG_IGN) {
        !           410:                (void)signal(sig, SigHandler);
        !           411:        }
        !           412: }
        !           413:
        !           414: void
        !           415: setup_all_signals()
        !           416: {
        !           417:        /*
        !           418:         * Catch the four signals that POSIX specifies if they aren't ignored.
        !           419:         * handle_signal will take care of calling JobInterrupt if appropriate.
        !           420:         */
        !           421:        setup_signal(SIGINT);
        !           422:        setup_signal(SIGHUP);
        !           423:        setup_signal(SIGQUIT);
        !           424:        setup_signal(SIGTERM);
        !           425:        /*
        !           426:         * There are additional signals that need to be caught and passed if
        !           427:         * either the export system wants to be told directly of signals or if
        !           428:         * we're giving each job its own process group (since then it won't get
        !           429:         * signals from the terminal driver as we own the terminal)
        !           430:         */
        !           431: #if defined(USE_PGRP)
        !           432:        setup_signal(SIGTSTP);
        !           433:        setup_signal(SIGTTOU);
        !           434:        setup_signal(SIGTTIN);
        !           435:        setup_signal(SIGWINCH);
        !           436: #endif
        !           437: }
        !           438:
        !           439: void
        !           440: SigHandler(int sig)
        !           441: {
        !           442:        switch(sig) {
        !           443:        case SIGINT:
        !           444:                got_SIGINT++;
        !           445:                got_signal = 1;
        !           446:                break;
        !           447:        case SIGHUP:
        !           448:                got_SIGHUP++;
        !           449:                got_signal = 1;
        !           450:                break;
        !           451:        case SIGQUIT:
        !           452:                got_SIGQUIT++;
        !           453:                got_signal = 1;
        !           454:                break;
        !           455:        case SIGTERM:
        !           456:                got_SIGTERM++;
        !           457:                got_signal = 1;
        !           458:                break;
        !           459: #ifdef USE_PGRP
        !           460:        case SIGTSTP:
        !           461:                got_SIGTSTP++;
        !           462:                got_signal = 1;
        !           463:                break;
        !           464:        case SIGTTOU:
        !           465:                got_SIGTTOU++;
        !           466:                got_signal = 1;
        !           467:                break;
        !           468:        case SIGTTIN:
        !           469:                got_SIGTTIN++;
        !           470:                got_signal = 1;
        !           471:                break;
        !           472:        case SIGWINCH:
        !           473:                got_SIGWINCH++;
        !           474:                got_signal = 1;
        !           475:                break;
        !           476: #endif
        !           477:        }
        !           478: }
        !           479:
        !           480: /* The following array is used to make a fast determination of which
        !           481:  * characters are interpreted specially by the shell.  If a command
        !           482:  * contains any of these characters, it is executed by the shell, not
        !           483:  * directly by us.  */
        !           484: static char        meta[256];
        !           485:
        !           486: void
        !           487: setup_meta(void)
        !           488: {
        !           489:        char *p;
        !           490:
        !           491:        for (p = "#=|^(){};&<>*?[]:$`\\\n"; *p != '\0'; p++)
        !           492:                meta[(unsigned char) *p] = 1;
        !           493:        /* The null character serves as a sentinel in the string.  */
        !           494:        meta[0] = 1;
        !           495: }
        !           496:
        !           497: static char **
        !           498: recheck_command_for_shell(char **av)
        !           499: {
        !           500:        char *runsh[] = {
        !           501:                "alias", "cd", "eval", "exit", "read", "set", "ulimit",
        !           502:                "unalias", "unset", "wait", "umask", NULL
        !           503:        };
        !           504:
        !           505:        char **p;
        !           506:
        !           507:        /* optimization: if exec cmd, we avoid the intermediate shell */
        !           508:        if (strcmp(av[0], "exec") == 0)
        !           509:                av++;
        !           510:
        !           511:        for (p = runsh; *p; p++)
        !           512:                if (strcmp(av[0], *p) == 0)
        !           513:                        return NULL;
        !           514:
        !           515:        return av;
        !           516: }
        !           517:
        !           518: static void
        !           519: run_command(const char *cmd, bool errCheck)
        !           520: {
        !           521:        const char *p;
        !           522:        char *shargv[4];
        !           523:        char **todo;
        !           524:
        !           525:        shargv[0] = _PATH_BSHELL;
        !           526:
        !           527:        shargv[1] = errCheck ? "-ec" : "-c";
        !           528:        shargv[2] = (char *)cmd;
        !           529:        shargv[3] = NULL;
        !           530:
        !           531:        todo = shargv;
        !           532:
        !           533:
        !           534:        /* Search for meta characters in the command. If there are no meta
        !           535:         * characters, there's no need to execute a shell to execute the
        !           536:         * command.  */
        !           537:        for (p = cmd; !meta[(unsigned char)*p]; p++)
        !           538:                continue;
        !           539:        if (*p == '\0') {
        !           540:                char *bp;
        !           541:                char **av;
        !           542:                int argc;
        !           543:                /* No meta-characters, so probably no need to exec a shell.
        !           544:                 * Break the command into words to form an argument vector
        !           545:                 * we can execute.  */
        !           546:                av = brk_string(cmd, &argc, &bp);
        !           547:                av = recheck_command_for_shell(av);
        !           548:                if (av != NULL)
        !           549:                        todo = av;
        !           550:        }
        !           551:        execvp(todo[0], todo);
        !           552:
        !           553:        if (errno == ENOENT)
        !           554:                fprintf(stderr, "%s: not found\n", todo[0]);
        !           555:        else
        !           556:                perror(todo[0]);
        !           557:        _exit(1);
        !           558: }
        !           559:
        !           560: /*-
        !           561:  *-----------------------------------------------------------------------
        !           562:  * setup_and_run_command --
        !           563:  *     Execute the next command for a target. If the command returns an
        !           564:  *     error, the node's made field is set to ERROR and creation stops.
        !           565:  *
        !           566:  * Results:
        !           567:  *     0 in case of error, 1 if ok.
        !           568:  *
        !           569:  * Side Effects:
        !           570:  *     The node's 'made' field may be set to ERROR.
        !           571:  *-----------------------------------------------------------------------
        !           572:  */
        !           573: static int
        !           574: setup_and_run_command(char *cmd, GNode *gn, int dont_fork)
        !           575: {
        !           576:        char *cmdStart; /* Start of expanded command */
        !           577:        bool silent;    /* Don't print command */
        !           578:        bool doExecute; /* Execute the command */
        !           579:        bool errCheck;  /* Check errors */
        !           580:        int reason;     /* Reason for child's death */
        !           581:        int status;     /* Description of child's death */
        !           582:        pid_t cpid;     /* Child actually found */
        !           583:        pid_t stat;     /* Status of fork */
        !           584:
        !           585:        silent = gn->type & OP_SILENT;
        !           586:        errCheck = !(gn->type & OP_IGNORE);
        !           587:        doExecute = !noExecute;
        !           588:
        !           589:        cmdStart = Var_Subst(cmd, &gn->context, false);
        !           590:
        !           591:        /* How can we execute a null command ? we warn the user that the
        !           592:         * command expanded to nothing (is this the right thing to do?).  */
        !           593:        if (*cmdStart == '\0') {
        !           594:                free(cmdStart);
        !           595:                Error("%s expands to empty string", cmd);
        !           596:                return 1;
        !           597:        } else
        !           598:                cmd = cmdStart;
        !           599:
        !           600:        for (;; cmd++) {
        !           601:                if (*cmd == '@')
        !           602:                        silent = DEBUG(LOUD) ? false : true;
        !           603:                else if (*cmd == '-')
        !           604:                        errCheck = false;
        !           605:                else if (*cmd == '+')
        !           606:                        doExecute = true;
        !           607:                else
        !           608:                        break;
        !           609:        }
        !           610:        while (isspace(*cmd))
        !           611:                cmd++;
        !           612:        /* Print the command before echoing if we're not supposed to be quiet
        !           613:         * for this one. We also print the command if -n given.  */
        !           614:        if (!silent || noExecute) {
        !           615:                printf("%s\n", cmd);
        !           616:                fflush(stdout);
        !           617:        }
        !           618:        /* If we're not supposed to execute any commands, this is as far as
        !           619:         * we go...  */
        !           620:        if (!doExecute)
        !           621:                return 1;
        !           622:
        !           623:        /* if we're running in parallel mode, we try not to fork the last
        !           624:         * command, since it's exit status will be just fine... unless
        !           625:         * errCheck is not set, in which case we must deal with the
        !           626:         * status ourselves.
        !           627:         */
        !           628:        if (dont_fork && errCheck)
        !           629:                run_command(cmd, errCheck);
        !           630:                /*NOTREACHED*/
        !           631:
        !           632:        /* Fork and execute the single command. If the fork fails, we abort.  */
        !           633:        switch (cpid = fork()) {
        !           634:        case -1:
        !           635:                Fatal("Could not fork");
        !           636:                /*NOTREACHED*/
        !           637:        case 0:
        !           638:                run_command(cmd, errCheck);
        !           639:                /*NOTREACHED*/
        !           640:        default:
        !           641:                break;
        !           642:        }
        !           643:        free(cmdStart);
        !           644:
        !           645:        /* The child is off and running. Now all we can do is wait...  */
        !           646:        while (1) {
        !           647:
        !           648:                while ((stat = wait(&reason)) != cpid) {
        !           649:                        if (stat == -1 && errno != EINTR)
        !           650:                                break;
        !           651:                }
        !           652:
        !           653:                if (got_signal)
        !           654:                        break;
        !           655:
        !           656:                if (stat != -1) {
        !           657:                        if (WIFSTOPPED(reason))
        !           658:                                status = WSTOPSIG(reason);      /* stopped */
        !           659:                        else if (WIFEXITED(reason)) {
        !           660:                                status = WEXITSTATUS(reason);   /* exited */
        !           661:                                if (status != 0)
        !           662:                                    printf("*** Error code %d", status);
        !           663:                        } else {
        !           664:                                status = WTERMSIG(reason);      /* signaled */
        !           665:                                printf("*** Signal %d", status);
        !           666:                        }
        !           667:
        !           668:
        !           669:                        if (!WIFEXITED(reason) || status != 0) {
        !           670:                                if (errCheck) {
        !           671:                                        gn->made = ERROR;
        !           672:                                        if (keepgoing)
        !           673:                                                /* Abort the current target,
        !           674:                                                 * but let others continue.  */
        !           675:                                                printf(" (continuing)\n");
        !           676:                                } else {
        !           677:                                        /* Continue executing commands for
        !           678:                                         * this target.  If we return 0,
        !           679:                                         * this will happen...  */
        !           680:                                        printf(" (ignored)\n");
        !           681:                                        status = 0;
        !           682:                                }
        !           683:                        }
        !           684:                        return !status;
        !           685:                } else
        !           686:                        Fatal("error in wait: %d", stat);
        !           687:                        /*NOTREACHED*/
        !           688:        }
        !           689:        return 0;
        !           690: }
        !           691:
        !           692: static void
        !           693: handle_compat_interrupts(GNode *gn)
        !           694: {
        !           695:        if (!Targ_Precious(gn)) {
        !           696:                char      *file = Varq_Value(TARGET_INDEX, gn);
        !           697:
        !           698:                if (!noExecute && eunlink(file) != -1)
        !           699:                        Error("*** %s removed\n", file);
        !           700:        }
        !           701:        if (got_SIGINT) {
        !           702:                signal(SIGINT, SIG_IGN);
        !           703:                signal(SIGTERM, SIG_IGN);
        !           704:                signal(SIGHUP, SIG_IGN);
        !           705:                signal(SIGQUIT, SIG_IGN);
        !           706:                got_signal = 0;
        !           707:                got_SIGINT = 0;
        !           708:                run_gnode(interrupt_node, 0);
        !           709:                exit(255);
        !           710:        }
        !           711:        exit(255);
        !           712: }
        !           713:
        !           714: int
        !           715: run_gnode(GNode *gn, int parallel)
        !           716: {
        !           717:        LstNode ln, nln;
        !           718:
        !           719:        if (gn != NULL && (gn->type & OP_DUMMY) == 0) {
        !           720:                gn->made = MADE;
        !           721:                for (ln = Lst_First(&gn->commands); ln != NULL; ln = nln) {
        !           722:                        nln = Lst_Adv(ln);
        !           723:                        if (setup_and_run_command(Lst_Datum(ln), gn,
        !           724:                            parallel && nln == NULL) == 0)
        !           725:                                break;
        !           726:                }
        !           727:                if (got_signal && !parallel)
        !           728:                        handle_compat_interrupts(gn);
        !           729:                return gn->made;
        !           730:        } else
        !           731:                return NOSUCHNODE;
        !           732: }
        !           733:
        !           734: void
        !           735: setup_engine()
        !           736: {
        !           737:        static int already_setup = 0;
        !           738:
        !           739:        if (!already_setup) {
        !           740:                setup_meta();
        !           741:                setup_all_signals();
        !           742:                already_setup = 1;
        !           743:        }
        !           744: }