-/* $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.
*
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include "config.h"
#include "defines.h"
#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 */
*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\"";
(void)close(fds[1]);
}
- (void)execv(_PATH_BSHELL, args);
- _exit(1);
+ run_command(cmd, false);
/*NOTREACHED*/
case -1:
#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.
* 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
-/* $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.
*
#include <unistd.h>
#include "config.h"
#include "defines.h"
+#include "cmd_exec.h"
#include "dir.h"
#include "engine.h"
#include "arch.h"
#include "make.h"
#include "pathnames.h"
#include "error.h"
-#include "str.h"
#include "memory.h"
#include "buf.h"
#include "job.h"
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*
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)
}
-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)
{
bool started;
GNode *gn = job->node;
- setup_engine();
while (job->next_cmd != NULL) {
struct command *command = Lst_Datum(job->next_cmd);
-/* $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.
#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();