From: espie Date: Thu, 31 Aug 2023 06:53:28 +0000 (+0000) Subject: reuse the code to exec command for VAR != cmd *and* normal target processing X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=e2e5a33cfe22afa60a150b22a4a44126ac7d2cb8;p=openbsd reuse the code to exec command for VAR != cmd *and* normal target processing okay tb@ --- diff --git a/usr.bin/make/cmd_exec.c b/usr.bin/make/cmd_exec.c index ca0ecd25f82..70e28f93f9a 100644 --- a/usr.bin/make/cmd_exec.c +++ b/usr.bin/make/cmd_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd_exec.c,v 1.11 2020/01/16 16:07:18 espie Exp $ */ +/* $OpenBSD: cmd_exec.c,v 1.12 2023/08/31 06:53:28 espie Exp $ */ /* * Copyright (c) 2001 Marc Espie. * @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "config.h" #include "defines.h" @@ -36,11 +37,93 @@ #include "memory.h" #include "pathnames.h" #include "job.h" +#include "str.h" + +/* The following array is used to make a fast determination of which + * characters are interpreted specially by the shell. If a command + * contains any of these characters, it is executed by the shell, not + * directly by us. */ +static char meta[256]; + +void +CmdExec_Init(void) +{ + char *p; + + for (p = "#=|^(){};&<>*?[]:$`\\\n~"; *p != '\0'; p++) + meta[(unsigned char) *p] = 1; + /* The null character serves as a sentinel in the string. */ + meta[0] = 1; +} + +static char ** +recheck_command_for_shell(char **av) +{ + char *runsh[] = { + "!", "alias", "cd", "eval", "exit", "read", "set", "ulimit", + "unalias", "unset", "wait", "umask", NULL + }; + + char **p; + + /* optimization: if exec cmd, we avoid the intermediate shell */ + if (strcmp(av[0], "exec") == 0) + av++; + + if (!av[0]) + return NULL; + + for (p = runsh; *p; p++) + if (strcmp(av[0], *p) == 0) + return NULL; + + return av; +} + +void +run_command(const char *cmd, bool errCheck) +{ + const char *p; + char *shargv[4]; + char **todo; + + shargv[0] = _PATH_BSHELL; + + shargv[1] = errCheck ? "-ec" : "-c"; + shargv[2] = (char *)cmd; + shargv[3] = NULL; + + todo = shargv; + + + /* Search for meta characters in the command. If there are no meta + * characters, there's no need to execute a shell to execute the + * command. */ + for (p = cmd; !meta[(unsigned char)*p]; p++) + continue; + if (*p == '\0') { + char *bp; + char **av; + int argc; + /* No meta-characters, so probably no need to exec a shell. + * Break the command into words to form an argument vector + * we can execute. */ + av = brk_string(cmd, &argc, &bp); + av = recheck_command_for_shell(av); + if (av != NULL) + todo = av; + } + execvp(todo[0], todo); + if (errno == ENOENT) + fprintf(stderr, "%s: not found\n", todo[0]); + else + perror(todo[0]); + _exit(1); +} char * Cmd_Exec(const char *cmd, char **err) { - char *args[4]; /* Args for invoking the shell */ int fds[2]; /* Pipe streams */ pid_t cpid; /* Child PID */ char *result; /* Result */ @@ -53,12 +136,6 @@ Cmd_Exec(const char *cmd, char **err) *err = NULL; - /* Set up arguments for the shell. */ - args[0] = "sh"; - args[1] = "-c"; - args[2] = (char *)cmd; - args[3] = NULL; - /* Open a pipe for retrieving shell's output. */ if (pipe(fds) == -1) { *err = "Couldn't create pipe for \"%s\""; @@ -82,8 +159,7 @@ Cmd_Exec(const char *cmd, char **err) (void)close(fds[1]); } - (void)execv(_PATH_BSHELL, args); - _exit(1); + run_command(cmd, false); /*NOTREACHED*/ case -1: diff --git a/usr.bin/make/cmd_exec.h b/usr.bin/make/cmd_exec.h index c7735b62118..c1a99aab23b 100644 --- a/usr.bin/make/cmd_exec.h +++ b/usr.bin/make/cmd_exec.h @@ -1,6 +1,6 @@ #ifndef CMD_EXEC_H #define CMD_EXEC_H -/* $OpenBSD: cmd_exec.h,v 1.4 2010/07/19 19:46:43 espie Exp $ */ +/* $OpenBSD: cmd_exec.h,v 1.5 2023/08/31 06:53:28 espie Exp $ */ /* * Copyright (c) 2001 Marc Espie. @@ -34,4 +34,6 @@ * The output result should always be freed by the caller. */ extern char *Cmd_Exec(const char *, char **); +extern void CmdExec_Init(void); +extern __dead void run_command(const char *, bool); #endif diff --git a/usr.bin/make/engine.c b/usr.bin/make/engine.c index d1967eab92a..193c038d9ab 100644 --- a/usr.bin/make/engine.c +++ b/usr.bin/make/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.71 2023/05/30 04:42:21 espie Exp $ */ +/* $OpenBSD: engine.c,v 1.72 2023/08/31 06:53:28 espie Exp $ */ /* * Copyright (c) 2012 Marc Espie. * @@ -75,6 +75,7 @@ #include #include "config.h" #include "defines.h" +#include "cmd_exec.h" #include "dir.h" #include "engine.h" #include "arch.h" @@ -88,7 +89,6 @@ #include "make.h" #include "pathnames.h" #include "error.h" -#include "str.h" #include "memory.h" #include "buf.h" #include "job.h" @@ -96,9 +96,6 @@ static void MakeTimeStamp(void *, void *); static int rewrite_time(const char *); -static void setup_meta(void); -static void setup_engine(void); -static char **recheck_command_for_shell(char **); static void list_parents(GNode *, FILE *); /* XXX due to a bug in make's logic, targets looking like *.a or -l* @@ -508,88 +505,6 @@ Make_OODate(GNode *gn) return oodate; } -/* The following array is used to make a fast determination of which - * characters are interpreted specially by the shell. If a command - * contains any of these characters, it is executed by the shell, not - * directly by us. */ -static char meta[256]; - -void -setup_meta(void) -{ - char *p; - - for (p = "#=|^(){};&<>*?[]:$`\\\n~"; *p != '\0'; p++) - meta[(unsigned char) *p] = 1; - /* The null character serves as a sentinel in the string. */ - meta[0] = 1; -} - -static char ** -recheck_command_for_shell(char **av) -{ - char *runsh[] = { - "!", "alias", "cd", "eval", "exit", "read", "set", "ulimit", - "unalias", "unset", "wait", "umask", NULL - }; - - char **p; - - /* optimization: if exec cmd, we avoid the intermediate shell */ - if (strcmp(av[0], "exec") == 0) - av++; - - if (!av[0]) - return NULL; - - for (p = runsh; *p; p++) - if (strcmp(av[0], *p) == 0) - return NULL; - - return av; -} - -static void -run_command(const char *cmd, bool errCheck) -{ - const char *p; - char *shargv[4]; - char **todo; - - shargv[0] = _PATH_BSHELL; - - shargv[1] = errCheck ? "-ec" : "-c"; - shargv[2] = (char *)cmd; - shargv[3] = NULL; - - todo = shargv; - - - /* Search for meta characters in the command. If there are no meta - * characters, there's no need to execute a shell to execute the - * command. */ - for (p = cmd; !meta[(unsigned char)*p]; p++) - continue; - if (*p == '\0') { - char *bp; - char **av; - int argc; - /* No meta-characters, so probably no need to exec a shell. - * Break the command into words to form an argument vector - * we can execute. */ - av = brk_string(cmd, &argc, &bp); - av = recheck_command_for_shell(av); - if (av != NULL) - todo = av; - } - execvp(todo[0], todo); - - if (errno == ENOENT) - fprintf(stderr, "%s: not found\n", todo[0]); - else - perror(todo[0]); - _exit(1); -} void job_attach_node(Job *job, GNode *node) @@ -696,17 +611,6 @@ run_gnode(GNode *gn) } -static void -setup_engine(void) -{ - static int already_setup = 0; - - if (!already_setup) { - setup_meta(); - already_setup = 1; - } -} - static bool do_run_command(Job *job, const char *pre) { @@ -799,7 +703,6 @@ job_run_next(Job *job) bool started; GNode *gn = job->node; - setup_engine(); while (job->next_cmd != NULL) { struct command *command = Lst_Datum(job->next_cmd); diff --git a/usr.bin/make/init.c b/usr.bin/make/init.c index db5a224a19e..ae8d6897117 100644 --- a/usr.bin/make/init.c +++ b/usr.bin/make/init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init.c,v 1.8 2020/01/16 16:07:18 espie Exp $ */ +/* $OpenBSD: init.c,v 1.9 2023/08/31 06:53:28 espie Exp $ */ /* * Copyright (c) 2001 Marc Espie. @@ -37,11 +37,13 @@ #include "targ.h" #include "suff.h" #include "job.h" +#include "cmd_exec.h" void Init(void) { Sigset_Init(); + CmdExec_Init(); Init_Timestamp(); Init_Stats(); Targ_Init();