Skip to content

Commit

Permalink
run_command: report failure to execute the program, but optionally don't
Browse files Browse the repository at this point in the history
In the case where a program was not found, it was still the task of the
caller to report an error to the user. Usually, this is an interesting case
but only few callers actually reported a specific error (though many call
sites report a generic error message regardless of the cause).

With this change the error is reported by run_command, but since there is
one call site in git.c that does not want that, an option is added to
struct child_process, which is used to turn the error off.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Johannes Sixt authored and Junio C Hamano committed Jul 6, 2009
1 parent b99d5f4 commit c024beb
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 13 deletions.
4 changes: 1 addition & 3 deletions builtin-receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ static const char post_receive_hook[] = "hooks/post-receive";

static int run_status(int code, const char *cmd_name)
{
if (code < 0 && errno == ENOENT)
return error("execute of %s failed", cmd_name);
else if (code > 0)
if (code > 0)
error("%s exited with error code %d", cmd_name, code);
return code;
}
Expand Down
2 changes: 1 addition & 1 deletion git.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ static void execv_dashed_external(const char **argv)
* if we fail because the command is not found, it is
* OK to return. Otherwise, we just pass along the status code.
*/
status = run_command_v_opt(argv, 0);
status = run_command_v_opt(argv, RUN_SILENT_EXEC_FAILURE);
if (status >= 0 || errno != ENOENT)
exit(status);

Expand Down
12 changes: 8 additions & 4 deletions run-command.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ int start_command(struct child_process *cmd)

cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env);
failed_errno = errno;
if (cmd->pid < 0 && errno != ENOENT)
if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
error("cannot spawn %s: %s", cmd->argv[0], strerror(errno));

if (cmd->env)
Expand Down Expand Up @@ -233,7 +233,7 @@ int start_command(struct child_process *cmd)
return 0;
}

static int wait_or_whine(pid_t pid, const char *argv0)
static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure)
{
int status, code = -1;
pid_t waiting;
Expand Down Expand Up @@ -264,6 +264,9 @@ static int wait_or_whine(pid_t pid, const char *argv0)
if (code == 127) {
code = -1;
failed_errno = ENOENT;
if (!silent_exec_failure)
error("cannot run %s: %s", argv0,
strerror(ENOENT));
}
} else {
error("waitpid is confused (%s)", argv0);
Expand All @@ -274,7 +277,7 @@ static int wait_or_whine(pid_t pid, const char *argv0)

int finish_command(struct child_process *cmd)
{
return wait_or_whine(cmd->pid, cmd->argv[0]);
return wait_or_whine(cmd->pid, cmd->argv[0], cmd->silent_exec_failure);
}

int run_command(struct child_process *cmd)
Expand All @@ -294,6 +297,7 @@ static void prepare_run_command_v_opt(struct child_process *cmd,
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;
cmd->silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0;
}

int run_command_v_opt(const char **argv, int opt)
Expand Down Expand Up @@ -358,7 +362,7 @@ int start_async(struct async *async)
int finish_async(struct async *async)
{
#ifndef __MINGW32__
int ret = wait_or_whine(async->pid, "child process");
int ret = wait_or_whine(async->pid, "child process", 0);
#else
DWORD ret = 0;
if (WaitForSingleObject(async->tid, INFINITE) != WAIT_OBJECT_0)
Expand Down
2 changes: 2 additions & 0 deletions run-command.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct child_process {
unsigned no_stdout:1;
unsigned no_stderr:1;
unsigned git_cmd:1; /* if this is to be git sub-command */
unsigned silent_exec_failure:1;
unsigned stdout_to_stderr:1;
void (*preexec_cb)(void);
};
Expand All @@ -44,6 +45,7 @@ extern int run_hook(const char *index_file, const char *name, ...);
#define RUN_COMMAND_NO_STDIN 1
#define RUN_GIT_CMD 2 /*If this is to be git sub-command */
#define RUN_COMMAND_STDOUT_TO_STDERR 4
#define RUN_SILENT_EXEC_FAILURE 8
int run_command_v_opt(const char **argv, int opt);

/*
Expand Down
6 changes: 1 addition & 5 deletions transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,6 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
{
const char **argv;
int argc;
int err;

if (flags & TRANSPORT_PUSH_MIRROR)
return error("http transport does not support mirror mode");
Expand All @@ -416,10 +415,7 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
while (refspec_nr--)
argv[argc++] = *refspec++;
argv[argc] = NULL;
err = run_command_v_opt(argv, RUN_GIT_CMD);
if (err < 0 && errno == ENOENT)
error("unable to exec %s", argv[0]);
return !!err;
return !!run_command_v_opt(argv, RUN_GIT_CMD);
}

static struct ref *get_refs_via_curl(struct transport *transport, int for_push)
Expand Down

0 comments on commit c024beb

Please sign in to comment.