Merge branch 'ab/run-command'

API clean-up.

* ab/run-command:
  run-command API: remove "env" member, always use "env_array"
  difftool: use "env_array" to simplify memory management
  run-command API: remove "argv" member, always use "args"
  run-command API users: use strvec_push(), not argv construction
  run-command API users: use strvec_pushl(), not argv construction
  run-command tests: use strvec_pushv(), not argv assignment
  run-command API users: use strvec_pushv(), not argv assignment
  upload-archive: use regular "struct child_process" pattern
  worktree: stop being overly intimate with run_command() internals
This commit is contained in:
Junio C Hamano
2021-12-15 09:39:47 -08:00
33 changed files with 157 additions and 223 deletions

View File

@ -380,7 +380,7 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr)
switch (cerr->err) {
case CHILD_ERR_CHDIR:
error_errno("exec '%s': cd to '%s' failed",
cmd->argv[0], cmd->dir);
cmd->args.v[0], cmd->dir);
break;
case CHILD_ERR_DUP2:
error_errno("dup2() in child failed");
@ -392,12 +392,12 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr)
error_errno("sigprocmask failed restoring signals");
break;
case CHILD_ERR_ENOENT:
error_errno("cannot run %s", cmd->argv[0]);
error_errno("cannot run %s", cmd->args.v[0]);
break;
case CHILD_ERR_SILENT:
break;
case CHILD_ERR_ERRNO:
error_errno("cannot exec '%s'", cmd->argv[0]);
error_errno("cannot exec '%s'", cmd->args.v[0]);
break;
}
set_error_routine(old_errfn);
@ -405,7 +405,7 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr)
static int prepare_cmd(struct strvec *out, const struct child_process *cmd)
{
if (!cmd->argv[0])
if (!cmd->args.v[0])
BUG("command is empty");
/*
@ -415,11 +415,11 @@ static int prepare_cmd(struct strvec *out, const struct child_process *cmd)
strvec_push(out, SHELL_PATH);
if (cmd->git_cmd) {
prepare_git_cmd(out, cmd->argv);
prepare_git_cmd(out, cmd->args.v);
} else if (cmd->use_shell) {
prepare_shell_cmd(out, cmd->argv);
prepare_shell_cmd(out, cmd->args.v);
} else {
strvec_pushv(out, cmd->argv);
strvec_pushv(out, cmd->args.v);
}
/*
@ -654,15 +654,10 @@ static void trace_run_command(const struct child_process *cp)
sq_quote_buf_pretty(&buf, cp->dir);
strbuf_addch(&buf, ';');
}
/*
* The caller is responsible for initializing cp->env from
* cp->env_array if needed. We only check one place.
*/
if (cp->env)
trace_add_env(&buf, cp->env);
trace_add_env(&buf, cp->env_array.v);
if (cp->git_cmd)
strbuf_addstr(&buf, " git");
sq_quote_argv_pretty(&buf, cp->argv);
sq_quote_argv_pretty(&buf, cp->args.v);
trace_printf("%s", buf.buf);
strbuf_release(&buf);
@ -675,11 +670,6 @@ int start_command(struct child_process *cmd)
int failed_errno;
char *str;
if (!cmd->argv)
cmd->argv = cmd->args.v;
if (!cmd->env)
cmd->env = cmd->env_array.v;
/*
* In case of errors we must keep the promise to close FDs
* that have been passed in via ->in and ->out.
@ -728,7 +718,7 @@ int start_command(struct child_process *cmd)
str = "standard error";
fail_pipe:
error("cannot create %s pipe for %s: %s",
str, cmd->argv[0], strerror(failed_errno));
str, cmd->args.v[0], strerror(failed_errno));
child_process_clear(cmd);
errno = failed_errno;
return -1;
@ -757,7 +747,7 @@ fail_pipe:
failed_errno = errno;
cmd->pid = -1;
if (!cmd->silent_exec_failure)
error_errno("cannot run %s", cmd->argv[0]);
error_errno("cannot run %s", cmd->args.v[0]);
goto end_of_spawn;
}
@ -769,7 +759,7 @@ fail_pipe:
set_cloexec(null_fd);
}
childenv = prep_childenv(cmd->env);
childenv = prep_childenv(cmd->env_array.v);
atfork_prepare(&as);
/*
@ -867,7 +857,7 @@ fail_pipe:
}
atfork_parent(&as);
if (cmd->pid < 0)
error_errno("cannot fork() for %s", cmd->argv[0]);
error_errno("cannot fork() for %s", cmd->args.v[0]);
else if (cmd->clean_on_exit)
mark_child_for_cleanup(cmd->pid, cmd);
@ -884,7 +874,7 @@ fail_pipe:
* At this point we know that fork() succeeded, but exec()
* failed. Errors have been reported to our stderr.
*/
wait_or_whine(cmd->pid, cmd->argv[0], 0);
wait_or_whine(cmd->pid, cmd->args.v[0], 0);
child_err_spew(cmd, &cerr);
failed_errno = errno;
cmd->pid = -1;
@ -901,7 +891,7 @@ end_of_spawn:
#else
{
int fhin = 0, fhout = 1, fherr = 2;
const char **sargv = cmd->argv;
const char **sargv = cmd->args.v;
struct strvec nargv = STRVEC_INIT;
if (cmd->no_stdin)
@ -928,20 +918,20 @@ end_of_spawn:
fhout = dup(cmd->out);
if (cmd->git_cmd)
cmd->argv = prepare_git_cmd(&nargv, cmd->argv);
cmd->args.v = prepare_git_cmd(&nargv, sargv);
else if (cmd->use_shell)
cmd->argv = prepare_shell_cmd(&nargv, cmd->argv);
cmd->args.v = prepare_shell_cmd(&nargv, sargv);
cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env,
cmd->pid = mingw_spawnvpe(cmd->args.v[0], cmd->args.v, (char**) cmd->env_array.v,
cmd->dir, fhin, fhout, fherr);
failed_errno = errno;
if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
error_errno("cannot spawn %s", cmd->argv[0]);
error_errno("cannot spawn %s", cmd->args.v[0]);
if (cmd->clean_on_exit && cmd->pid >= 0)
mark_child_for_cleanup(cmd->pid, cmd);
strvec_clear(&nargv);
cmd->argv = sargv;
cmd->args.v = sargv;
if (fhin != 0)
close(fhin);
if (fhout != 1)
@ -991,7 +981,7 @@ end_of_spawn:
int finish_command(struct child_process *cmd)
{
int ret = wait_or_whine(cmd->pid, cmd->argv[0], 0);
int ret = wait_or_whine(cmd->pid, cmd->args.v[0], 0);
trace2_child_exit(cmd, ret);
child_process_clear(cmd);
invalidate_lstat_cache();
@ -1000,7 +990,7 @@ int finish_command(struct child_process *cmd)
int finish_command_in_signal(struct child_process *cmd)
{
int ret = wait_or_whine(cmd->pid, cmd->argv[0], 1);
int ret = wait_or_whine(cmd->pid, cmd->args.v[0], 1);
trace2_child_exit(cmd, ret);
return ret;
}
@ -1038,7 +1028,7 @@ int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir,
const char *const *env, const char *tr2_class)
{
struct child_process cmd = CHILD_PROCESS_INIT;
cmd.argv = argv;
strvec_pushv(&cmd.args, argv);
cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
@ -1048,7 +1038,8 @@ int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir,
cmd.wait_after_clean = opt & RUN_WAIT_AFTER_CLEAN ? 1 : 0;
cmd.close_object_store = opt & RUN_CLOSE_OBJECT_STORE ? 1 : 0;
cmd.dir = dir;
cmd.env = env;
if (env)
strvec_pushv(&cmd.env_array, (const char **)env);
cmd.trace2_child_class = tr2_class;
return run_command(&cmd);
}
@ -1334,7 +1325,8 @@ int run_hook_ve(const char *const *env, const char *name, va_list args)
strvec_push(&hook.args, p);
while ((p = va_arg(args, const char *)))
strvec_push(&hook.args, p);
hook.env = env;
if (env)
strvec_pushv(&hook.env_array, (const char **)env);
hook.no_stdin = 1;
hook.stdout_to_stderr = 1;
hook.trace2_hook_name = name;