
The argc parameter is never used by the run_command_v family of functions. Instead they require that the passed argv[] be NULL terminated so they can rely on the operating system's execvp function to correctly pass the arguments to the new process. Making the caller pass the argc is just confusing, as the caller could be mislead into believing that the argc might take precendece over the argv, or that the argv does not need to be NULL terminated. So goodbye argc. Don't come back. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
74 lines
1.5 KiB
C
74 lines
1.5 KiB
C
#include "cache.h"
|
|
#include "run-command.h"
|
|
#include "exec_cmd.h"
|
|
|
|
int run_command_v_opt(const char **argv, int flags)
|
|
{
|
|
pid_t pid = fork();
|
|
|
|
if (pid < 0)
|
|
return -ERR_RUN_COMMAND_FORK;
|
|
if (!pid) {
|
|
if (flags & RUN_COMMAND_NO_STDIO) {
|
|
int fd = open("/dev/null", O_RDWR);
|
|
dup2(fd, 0);
|
|
dup2(fd, 1);
|
|
close(fd);
|
|
}
|
|
if (flags & RUN_GIT_CMD) {
|
|
execv_git_cmd(argv);
|
|
} else {
|
|
execvp(argv[0], (char *const*) argv);
|
|
}
|
|
die("exec %s failed.", argv[0]);
|
|
}
|
|
for (;;) {
|
|
int status, code;
|
|
pid_t waiting = waitpid(pid, &status, 0);
|
|
|
|
if (waiting < 0) {
|
|
if (errno == EINTR)
|
|
continue;
|
|
error("waitpid failed (%s)", strerror(errno));
|
|
return -ERR_RUN_COMMAND_WAITPID;
|
|
}
|
|
if (waiting != pid)
|
|
return -ERR_RUN_COMMAND_WAITPID_WRONG_PID;
|
|
if (WIFSIGNALED(status))
|
|
return -ERR_RUN_COMMAND_WAITPID_SIGNAL;
|
|
|
|
if (!WIFEXITED(status))
|
|
return -ERR_RUN_COMMAND_WAITPID_NOEXIT;
|
|
code = WEXITSTATUS(status);
|
|
if (code)
|
|
return -code;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int run_command_v(const char **argv)
|
|
{
|
|
return run_command_v_opt(argv, 0);
|
|
}
|
|
|
|
int run_command(const char *cmd, ...)
|
|
{
|
|
int argc;
|
|
const char *argv[MAX_RUN_COMMAND_ARGS];
|
|
const char *arg;
|
|
va_list param;
|
|
|
|
va_start(param, cmd);
|
|
argv[0] = (char*) cmd;
|
|
argc = 1;
|
|
while (argc < MAX_RUN_COMMAND_ARGS) {
|
|
arg = argv[argc++] = va_arg(param, char *);
|
|
if (!arg)
|
|
break;
|
|
}
|
|
va_end(param);
|
|
if (MAX_RUN_COMMAND_ARGS <= argc)
|
|
return error("too many args to run %s", cmd);
|
|
return run_command_v_opt(argv, 0);
|
|
}
|