1
0
mirror of https://github.com/openbsd/src.git synced 2024-12-22 07:27:59 -08:00

reuse the code to exec command for VAR != cmd *and* normal target processing

okay tb@
This commit is contained in:
espie 2023-08-31 06:53:28 +00:00
parent ed0ab3e867
commit e2e5a33cfe
4 changed files with 94 additions and 111 deletions

View File

@ -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 <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#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:

View File

@ -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

View File

@ -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 <unistd.h>
#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);

View File

@ -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();