diff options
author | joerg <joerg@pkgsrc.org> | 2015-05-19 21:36:43 +0000 |
---|---|---|
committer | joerg <joerg@pkgsrc.org> | 2015-05-19 21:36:43 +0000 |
commit | 41f4d684ea949e703f7e4cdb02fffeb278231228 (patch) | |
tree | 2b7216a215b93c3db4db0c3a78c3ab11b8eaec34 /devel/bmake/files/main.c | |
parent | 7cb16bb66575467ac59352068eaec344242b439a (diff) | |
download | pkgsrc-41f4d684ea949e703f7e4cdb02fffeb278231228.tar.gz |
Import bmake-20150505
Diffstat (limited to 'devel/bmake/files/main.c')
-rw-r--r-- | devel/bmake/files/main.c | 471 |
1 files changed, 210 insertions, 261 deletions
diff --git a/devel/bmake/files/main.c b/devel/bmake/files/main.c index 0a8420f59f4..36ac02ced02 100644 --- a/devel/bmake/files/main.c +++ b/devel/bmake/files/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $ */ +/* $NetBSD: main.c,v 1.1.1.11 2015/05/19 21:36:44 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,7 +69,7 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $"; +static char rcsid[] = "$NetBSD: main.c,v 1.1.1.11 2015/05/19 21:36:44 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint @@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ #if 0 static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $"); +__RCSID("$NetBSD: main.c,v 1.1.1.11 2015/05/19 21:36:44 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -99,14 +99,14 @@ __RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $"); * * Error Print a tagged error message. The global * MAKE variable must have been defined. This - * takes a format string and two optional - * arguments for it. + * takes a format string and optional arguments + * for it. * * Fatal Print an error message and exit. Also takes - * a format string and two arguments. + * a format string and arguments for it. * * Punt Aborts all jobs and exits with a message. Also - * takes a format string and two arguments. + * takes a format string and arguments for it. * * Finish Finish things up by printing the number of * errors which occurred, as passed to it, and @@ -117,19 +117,21 @@ __RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $"); #include <sys/time.h> #include <sys/param.h> #include <sys/resource.h> -#include <signal.h> #include <sys/stat.h> -#ifdef MAKE_NATIVE -#include <sys/utsname.h> +#if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL) +#include <sys/sysctl.h> #endif +#include <sys/utsname.h> #include "wait.h" #include <errno.h> #include <fcntl.h> +#include <signal.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <time.h> +#include <ctype.h> #include "make.h" #include "hash.h" @@ -146,6 +148,10 @@ __RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $"); #define DEFMAXLOCAL DEFMAXJOBS #endif /* DEFMAXLOCAL */ +#ifndef __arraycount +# define __arraycount(__x) (sizeof(__x) / sizeof(__x[0])) +#endif + Lst create; /* Targets to be made */ time_t now; /* Time at start of make */ GNode *DEFAULT; /* .DEFAULT node */ @@ -159,11 +165,13 @@ int maxJobs; /* -j argument */ static int maxJobTokens; /* -j argument */ Boolean compatMake; /* -B argument */ int debug; /* -d argument */ +Boolean debugVflag; /* -dV */ Boolean noExecute; /* -n flag */ Boolean noRecursiveExecute; /* -N flag */ Boolean keepgoing; /* -k flag */ Boolean queryFlag; /* -q flag */ Boolean touchFlag; /* -t flag */ +Boolean enterFlag; /* -w flag */ Boolean ignoreErrors; /* -i flag */ Boolean beSilent; /* -s flag */ Boolean oldVars; /* variable substitution style */ @@ -175,12 +183,9 @@ Boolean varNoExportEnv; /* -X flag */ Boolean doing_depend; /* Set while reading .depend */ static Boolean jobsRunning; /* TRUE if the jobs might be running */ static const char * tracefile; -#ifndef NO_CHECK_MAKE_CHDIR -static char * Check_Cwd_av(int, char **, int); -#endif static void MainParseArgs(int, char **); static int ReadMakefile(const void *, const void *); -static void usage(void); +static void usage(void) MAKE_ATTR_DEAD; static Boolean ignorePWD; /* if we use -C, PWD is meaningless */ static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */ @@ -188,6 +193,7 @@ char curdir[MAXPATHLEN + 1]; /* Startup directory */ char *progname; /* the program name */ char *makeDependfile; pid_t myPid; +int makelevel; Boolean forceJobs = FALSE; @@ -202,6 +208,38 @@ Boolean forceJobs = FALSE; extern Lst parseIncPath; +/* + * For compatibility with the POSIX version of MAKEFLAGS that includes + * all the options with out -, convert flags to -f -l -a -g -s. + */ +static char * +explode(const char *flags) +{ + size_t len; + char *nf, *st; + const char *f; + + if (flags == NULL) + return NULL; + + for (f = flags; *f; f++) + if (!isalpha((unsigned char)*f)) + break; + + if (*f) + return bmake_strdup(flags); + + len = strlen(flags); + st = nf = bmake_malloc(len * 3 + 1); + while (*flags) { + *nf++ = '-'; + *nf++ = *flags++; + *nf++ = ' '; + } + *nf = '\0'; + return st; +} + static void parse_debug_options(const char *argvalue) { @@ -271,6 +309,9 @@ parse_debug_options(const char *argvalue) case 't': debug |= DEBUG_TARG; break; + case 'V': + debugVflag = TRUE; + break; case 'v': debug |= DEBUG_VAR; break; @@ -280,9 +321,10 @@ parse_debug_options(const char *argvalue) case 'F': if (debug_file != stdout && debug_file != stderr) fclose(debug_file); - if (*++modules == '+') + if (*++modules == '+') { + modules++; mode = "a"; - else + } else mode = "w"; if (strcmp(modules, "stdout") == 0) { debug_file = stdout; @@ -350,7 +392,7 @@ MainParseArgs(int argc, char **argv) Boolean inOption, dashDash = FALSE; char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ -#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst" +#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstw" /* Can't actually use getopt(3) because rescanning is not portable */ getopt_def = OPTFLAGS; @@ -558,6 +600,10 @@ rearg: touchFlag = TRUE; Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); break; + case 'w': + enterFlag = TRUE; + Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL); + break; case '-': dashDash = TRUE; break; @@ -735,7 +781,7 @@ str2Lst_Append(Lst lp, char *str, const char *sep) #ifdef SIGINFO /*ARGSUSED*/ static void -siginfo(int signo __unused) +siginfo(int signo MAKE_ATTR_UNUSED) { char dir[MAXPATHLEN]; char str[2 * MAXPATHLEN]; @@ -766,7 +812,7 @@ MakeMode(const char *mode) } #if USE_META if (strstr(mode, "meta")) - meta_init(mode); + meta_mode_init(mode); #endif } if (mp) @@ -796,7 +842,7 @@ main(int argc, char **argv) Lst targs; /* target nodes to create -- passed to Make_Init */ Boolean outOfDate = FALSE; /* FALSE if all targets up to date */ struct stat sb, sa; - char *p1, *path, *pwd; + char *p1, *path; char mdpath[MAXPATHLEN]; #ifdef FORCE_MACHINE const char *machine = FORCE_MACHINE; @@ -811,9 +857,7 @@ main(int argc, char **argv) static char defsyspath[] = _PATH_DEFSYSPATH; char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ struct timeval rightnow; /* to initialize random seed */ -#ifdef MAKE_NATIVE struct utsname utsname; -#endif /* default to writing debug to stderr */ debug_file = stderr; @@ -832,7 +876,7 @@ main(int argc, char **argv) progname++; else progname = argv[0]; -#ifdef RLIMIT_NOFILE +#if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)) /* * get rid of resource limit on file descriptors */ @@ -846,6 +890,12 @@ main(int argc, char **argv) } #endif + if (uname(&utsname) == -1) { + (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, + strerror(errno)); + exit(2); + } + /* * Get the name of this type of MACHINE from utsname * so we can share an executable for similar machines. @@ -856,11 +906,6 @@ main(int argc, char **argv) */ if (!machine) { #ifdef MAKE_NATIVE - if (uname(&utsname) == -1) { - (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, - strerror(errno)); - exit(2); - } machine = utsname.machine; #else #ifdef MAKE_MACHINE @@ -872,6 +917,20 @@ main(int argc, char **argv) } if (!machine_arch) { +#if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL) && defined(CTL_HW) && defined(HW_MACHINE_ARCH) + static char machine_arch_buf[sizeof(utsname.machine)]; + int mib[2] = { CTL_HW, HW_MACHINE_ARCH }; + size_t len = sizeof(machine_arch_buf); + + if (sysctl(mib, __arraycount(mib), machine_arch_buf, + &len, NULL, 0) < 0) { + (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname, + strerror(errno)); + exit(2); + } + + machine_arch = machine_arch_buf; +#else #ifndef MACHINE_ARCH #ifdef MAKE_MACHINE_ARCH machine_arch = MAKE_MACHINE_ARCH; @@ -881,6 +940,7 @@ main(int argc, char **argv) #else machine_arch = MACHINE_ARCH; #endif +#endif } myPid = getpid(); /* remember this for vFork() */ @@ -890,6 +950,7 @@ main(int argc, char **argv) */ Var_Init(); /* Initialize the lists of variables for * parsing arguments */ + Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0); Var_Set("MACHINE", machine, VAR_GLOBAL, 0); Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); #ifdef MAKE_VERSION @@ -909,6 +970,7 @@ main(int argc, char **argv) create = Lst_Init(FALSE); makefiles = Lst_Init(FALSE); printVars = FALSE; + debugVflag = FALSE; variables = Lst_Init(FALSE); beSilent = FALSE; /* Print commands as executed */ ignoreErrors = FALSE; /* Pay attention to non-zero returns */ @@ -962,32 +1024,43 @@ main(int argc, char **argv) Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0); Var_Set("MFLAGS", "", VAR_GLOBAL, 0); Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0); + /* some makefiles need to know this */ + Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMD, 0); /* * Set some other useful macros */ { - char tmp[64]; - const char *ep; + char tmp[64], *ep; - if (!(ep = getenv(MAKE_LEVEL))) { - ep = "0"; - } - Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0); + makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0; + if (makelevel < 0) + makelevel = 0; + snprintf(tmp, sizeof(tmp), "%d", makelevel); + Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL, 0); snprintf(tmp, sizeof(tmp), "%u", myPid); Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0); snprintf(tmp, sizeof(tmp), "%u", getppid()); Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0); } - Job_SetPrefix(); + if (makelevel > 0) { + char pn[1024]; + snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel); + progname = bmake_strdup(pn); + } +#ifdef USE_META + meta_init(); +#endif /* * First snag any flags out of the MAKE environment variable. * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's * in a different format). */ #ifdef POSIX - Main_ParseArgLine(getenv("MAKEFLAGS")); + p1 = explode(getenv("MAKEFLAGS")); + Main_ParseArgLine(p1); + free(p1); #else Main_ParseArgLine(getenv("MAKE")); #endif @@ -1004,6 +1077,9 @@ main(int argc, char **argv) MainParseArgs(argc, argv); + if (enterFlag) + printf("%s: Entering directory `%s'\n", progname, curdir); + /* * Verify that cwd is sane. */ @@ -1025,16 +1101,23 @@ main(int argc, char **argv) * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform. */ #ifndef NO_PWD_OVERRIDE - if (!ignorePWD && - (pwd = getenv("PWD")) != NULL && - getenv("MAKEOBJDIRPREFIX") == NULL) { - const char *makeobjdir = getenv("MAKEOBJDIR"); - - if (makeobjdir == NULL || !strchr(makeobjdir, '$')) { - if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && - sa.st_dev == sb.st_dev) - (void)strncpy(curdir, pwd, MAXPATHLEN); + if (!ignorePWD) { + char *pwd, *ptmp1 = NULL, *ptmp2 = NULL; + + if ((pwd = getenv("PWD")) != NULL && + Var_Value("MAKEOBJDIRPREFIX", VAR_CMD, &ptmp1) == NULL) { + const char *makeobjdir = Var_Value("MAKEOBJDIR", + VAR_CMD, &ptmp2); + + if (makeobjdir == NULL || !strchr(makeobjdir, '$')) { + if (stat(pwd, &sb) == 0 && + sa.st_ino == sb.st_ino && + sa.st_dev == sb.st_dev) + (void)strncpy(curdir, pwd, MAXPATHLEN); + } } + free(ptmp1); + free(ptmp2); } #endif Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0); @@ -1051,11 +1134,13 @@ main(int argc, char **argv) Dir_Init(curdir); (void)Main_SetObjdir(curdir); - if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) { + if ((path = Var_Value("MAKEOBJDIRPREFIX", VAR_CMD, &p1)) != NULL) { (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir); (void)Main_SetObjdir(mdpath); - } else if ((path = getenv("MAKEOBJDIR")) != NULL) { + free(p1); + } else if ((path = Var_Value("MAKEOBJDIR", VAR_CMD, &p1)) != NULL) { (void)Main_SetObjdir(path); + free(p1); } else { (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine); if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) { @@ -1195,10 +1280,6 @@ main(int argc, char **argv) Main_ExportMAKEFLAGS(TRUE); /* initial export */ -#ifndef NO_CHECK_MAKE_CHDIR - Check_Cwd_av(0, NULL, 0); /* initialize it */ -#endif - /* * For compatibility, look at the directories in the VPATH variable * and add them to the search path, if the variable is defined. The @@ -1249,7 +1330,12 @@ main(int argc, char **argv) /* print the values of any variables requested by the user */ if (printVars) { LstNode ln; + Boolean expandVars; + if (debugVflag) + expandVars = FALSE; + else + expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE); for (ln = Lst_First(variables); ln != NULL; ln = Lst_Succ(ln)) { char *var = (char *)Lst_Datum(ln); @@ -1257,6 +1343,13 @@ main(int argc, char **argv) if (strchr(var, '$')) { value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0); + } else if (expandVars) { + char tmp[128]; + + if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp))) + Fatal("%s: variable name too big: %s", + progname, var); + value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); } else { value = Var_Value(var, VAR_GLOBAL, &p1); } @@ -1313,6 +1406,9 @@ main(int argc, char **argv) Trace_Log(MAKEEND, 0); + if (enterFlag) + printf("%s: Leaving directory `%s'\n", progname, curdir); + Suff_End(); Targ_End(); Arch_End(); @@ -1336,7 +1432,7 @@ main(int argc, char **argv) * lots */ static int -ReadMakefile(const void *p, const void *q __unused) +ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED) { const char *fname = p; /* makefile to read */ int fd; @@ -1345,7 +1441,7 @@ ReadMakefile(const void *p, const void *q __unused) if (!strcmp(fname, "-")) { Parse_File(NULL /*stdin*/, -1); - Var_Set("MAKEFILE", "", VAR_GLOBAL, 0); + Var_Set("MAKEFILE", "", VAR_INTERNAL, 0); } else { /* if we've chdir'd, rebuild the path name */ if (strcmp(curdir, objdir) && *fname != '/') { @@ -1394,7 +1490,7 @@ ReadMakefile(const void *p, const void *q __unused) */ found: if (!doing_depend) - Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0); + Var_Set("MAKEFILE", fname, VAR_INTERNAL, 0); Parse_File(fname, fd); } free(path); @@ -1402,208 +1498,6 @@ found: } -/* - * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR - * in situations that would not arrise with ./obj (links or not). - * This tends to break things like: - * - * build: - * ${MAKE} includes - * - * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as - * opposed to an argument) in a command line and if so returns - * ${.CURDIR} so caller can chdir() so that the assumptions made by - * the Makefile hold true. - * - * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped. - * - * The chdir() only happens in the child process, and does nothing if - * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it - * should not break anything. Also if NOCHECKMAKECHDIR is set we - * do nothing - to ensure historic semantics can be retained. - */ -#ifdef NO_CHECK_MAKE_CHDIR -char * -Check_Cwd_Cmd(cmd) - char *cmd; -{ - return 0; -} - -void -Check_Cwd(argv) - char **argv; -{ - return; -} - -#else - -static int Check_Cwd_Off = 0; - -static char * -Check_Cwd_av(int ac, char **av, int copy) -{ - static char *make[4]; - static char *cur_dir = NULL; - char **mp; - char *cp; - int is_cmd, next_cmd; - int i; - int n; - - if (Check_Cwd_Off) { - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: check is off.\n"); - return NULL; - } - - if (make[0] == NULL) { - if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) { - Check_Cwd_Off = 1; - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: turning check off.\n"); - return NULL; - } - - make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp); - if ((make[0] = strrchr(make[1], '/')) == NULL) { - make[0] = make[1]; - make[1] = NULL; - } else - ++make[0]; - make[2] = NULL; - cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp); - } - if (ac == 0 || av == NULL) { - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: empty command.\n"); - return NULL; /* initialization only */ - } - - if (getenv("MAKEOBJDIR") == NULL && - getenv("MAKEOBJDIRPREFIX") == NULL) { - if (DEBUG(CWD)) - fprintf(debug_file, "check_cwd: no obj dirs.\n"); - return NULL; - } - - - next_cmd = 1; - for (i = 0; i < ac; ++i) { - is_cmd = next_cmd; - - n = strlen(av[i]); - cp = &(av[i])[n - 1]; - if (strspn(av[i], "|&;") == (size_t)n) { - next_cmd = 1; - continue; - } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') { - next_cmd = 1; - if (copy) { - do { - *cp-- = '\0'; - } while (*cp == ';' || *cp == '&' || *cp == '|' || - *cp == ')' || *cp == '}') ; - } else { - /* - * XXX this should not happen. - */ - fprintf(stderr, "%s: WARNING: raw arg ends in shell meta '%s'\n", - progname, av[i]); - } - } else - next_cmd = 0; - - cp = av[i]; - if (*cp == ';' || *cp == '&' || *cp == '|') - is_cmd = 1; - - if (DEBUG(CWD)) - fprintf(debug_file, "av[%d] == %s '%s'", - i, (is_cmd) ? "cmd" : "arg", av[i]); - if (is_cmd != 0) { - if (*cp == '(' || *cp == '{' || - *cp == ';' || *cp == '&' || *cp == '|') { - do { - ++cp; - } while (*cp == '(' || *cp == '{' || - *cp == ';' || *cp == '&' || *cp == '|'); - if (*cp == '\0') { - next_cmd = 1; - continue; - } - } - if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) { - if (DEBUG(CWD)) - fprintf(debug_file, " == cd, done.\n"); - return NULL; - } - for (mp = make; *mp != NULL; ++mp) { - n = strlen(*mp); - if (strcmp(cp, *mp) == 0) { - if (DEBUG(CWD)) - fprintf(debug_file, " %s == '%s', chdir(%s)\n", - cp, *mp, cur_dir); - return cur_dir; - } - } - } - if (DEBUG(CWD)) - fprintf(debug_file, "\n"); - } - return NULL; -} - -char * -Check_Cwd_Cmd(const char *cmd) -{ - char *cp, *bp; - char **av; - int ac; - - if (Check_Cwd_Off) - return NULL; - - if (cmd) { - av = brk_string(cmd, &ac, TRUE, &bp); - if (DEBUG(CWD)) - fprintf(debug_file, "splitting: '%s' -> %d words\n", - cmd, ac); - } else { - ac = 0; - av = NULL; - bp = NULL; - } - cp = Check_Cwd_av(ac, av, 1); - if (bp) - free(bp); - if (av) - free(av); - return cp; -} - -void -Check_Cwd(const char **argv) -{ - char *cp; - int ac; - - if (Check_Cwd_Off) - return; - - for (ac = 0; argv[ac] != NULL; ++ac) - /* NOTHING */; - if (ac == 3 && *argv[1] == '-') { - cp = Check_Cwd_Cmd(argv[2]); - } else { - cp = Check_Cwd_av(ac, UNCONST(argv), 0); - } - if (cp) { - chdir(cp); - } -} -#endif /* NO_CHECK_MAKE_CHDIR */ /*- * Cmd_Exec -- @@ -1628,7 +1522,8 @@ Cmd_Exec(const char *cmd, const char **errnum) WAIT_T status; /* command exit status */ Buffer buf; /* buffer to store the result */ char *cp; - int cc; + int cc; /* bytes read, or -1 */ + int savederr; /* saved errno */ *errnum = NULL; @@ -1685,6 +1580,7 @@ Cmd_Exec(const char *cmd, const char **errnum) */ (void)close(fds[1]); + savederr = 0; Buf_Init(&buf, 0); do { @@ -1694,6 +1590,8 @@ Cmd_Exec(const char *cmd, const char **errnum) Buf_AddBytes(&buf, cc, result); } while (cc > 0 || (cc == -1 && errno == EINTR)); + if (cc == -1) + savederr = errno; /* * Close the input side of the pipe. @@ -1710,7 +1608,7 @@ Cmd_Exec(const char *cmd, const char **errnum) cc = Buf_Size(&buf); res = Buf_Destroy(&buf, FALSE); - if (cc == 0) + if (savederr != 0) *errnum = "Couldn't read shell's output for \"%s\""; if (WIFSIGNALED(status)) @@ -1885,7 +1783,7 @@ Finish(int errors) } /* - * enunlink -- + * eunlink -- * Remove a file carefully, avoiding directories. */ int @@ -1931,7 +1829,8 @@ execError(const char *af, const char *av) IOADD(")\n"); #ifdef USE_IOVEC - (void)writev(2, iov, 8); + while (writev(2, iov, 8) == -1 && errno == EAGAIN) + continue; #endif } @@ -1942,8 +1841,12 @@ execError(const char *af, const char *av) static void usage(void) { + char *p; + if ((p = strchr(progname, '[')) != NULL) + *p = '\0'; + (void)fprintf(stderr, -"usage: %s [-BeikNnqrstWX] \n\ +"usage: %s [-BeikNnqrstWwX] \n\ [-C directory] [-D variable] [-d flags] [-f makefile]\n\ [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\ [-V variable] [variable=value] [target ...]\n", progname); @@ -2072,3 +1975,49 @@ mkTempFile(const char *pattern, char **fnamep) } return fd; } + + +/* + * Return a Boolean based on setting of a knob. + * + * If the knob is not set, the supplied default is the return value. + * If set, anything that looks or smells like "No", "False", "Off", "0" etc, + * is FALSE, otherwise TRUE. + */ +Boolean +getBoolean(const char *name, Boolean bf) +{ + char tmp[64]; + char *cp; + + if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) { + cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + + if (cp) { + switch(*cp) { + case '\0': /* not set - the default wins */ + break; + case '0': + case 'f': + case 'n': + bf = FALSE; + break; + case 'o': + switch (cp[1]) { + case 'f': + bf = FALSE; + break; + default: + bf = TRUE; + break; + } + break; + default: + bf = TRUE; + break; + } + free(cp); + } + } + return (bf); +} |