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");
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);
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");
/*
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);
}
/*
trace_add_env(&buf, cp->env);
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);
int failed_errno;
char *str;
- if (!cmd->argv)
- cmd->argv = cmd->args.v;
if (!cmd->env)
cmd->env = cmd->env_array.v;
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;
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;
}
}
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);
* 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;
#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)
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,
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)
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();
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;
}
struct child_process {
/**
- * The .argv member is set up as an array of string pointers (NULL
- * terminated), of which .argv[0] is the program name to run (usually
- * without a path). If the command to run is a git command, set argv[0] to
- * the command name without the 'git-' prefix and set .git_cmd = 1.
+ * The .args is a `struct strvec', use that API to manipulate
+ * it, e.g. strvec_pushv() to add an existing "const char **"
+ * vector.
*
- * Note that the ownership of the memory pointed to by .argv stays with the
- * caller, but it should survive until `finish_command` completes. If the
- * .argv member is NULL, `start_command` will point it at the .args
- * `strvec` (so you may use one or the other, but you must use exactly
- * one). The memory in .args will be cleaned up automatically during
- * `finish_command` (or during `start_command` when it is unsuccessful).
+ * If the command to run is a git command, set the first
+ * element in the strvec to the command name without the
+ * 'git-' prefix and set .git_cmd = 1.
*
+ * The memory in .args will be cleaned up automatically during
+ * `finish_command` (or during `start_command` when it is unsuccessful).
*/
- const char **argv;
-
struct strvec args;
struct strvec env_array;
pid_t pid;