Skip to content

Commit

Permalink
Merge branch 'js/run-command-updates'
Browse files Browse the repository at this point in the history
* js/run-command-updates:
  api-run-command.txt: describe error behavior of run_command functions
  run-command.c: squelch a "use before assignment" warning
  receive-pack: remove unnecessary run_status report
  run_command: report failure to execute the program, but optionally don't
  run_command: encode deadly signal number in the return value
  run_command: report system call errors instead of returning error codes
  run_command: return exit code as positive value
  MinGW: simplify waitpid() emulation macros
  • Loading branch information
Junio C Hamano committed Aug 11, 2009
2 parents 0c4f21e + 0b91322 commit 08ac696
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 125 deletions.
31 changes: 28 additions & 3 deletions Documentation/technical/api-run-command.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,32 @@ Functions
Convenience functions that encapsulate a sequence of
start_command() followed by finish_command(). The argument argv
specifies the program and its arguments. The argument opt is zero
or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`, or
`RUN_COMMAND_STDOUT_TO_STDERR` that correspond to the members
.no_stdin, .git_cmd, .stdout_to_stderr of `struct child_process`.
or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`,
`RUN_COMMAND_STDOUT_TO_STDERR`, or `RUN_SILENT_EXEC_FAILURE`
that correspond to the members .no_stdin, .git_cmd,
.stdout_to_stderr, .silent_exec_failure of `struct child_process`.
The argument dir corresponds the member .dir. The argument env
corresponds to the member .env.

The functions above do the following:

. If a system call failed, errno is set and -1 is returned. A diagnostic
is printed.

. If the program was not found, then -1 is returned and errno is set to
ENOENT; a diagnostic is printed only if .silent_exec_failure is 0.

. Otherwise, the program is run. If it terminates regularly, its exit
code is returned. No diagnistic is printed, even if the exit code is
non-zero.

. If the program terminated due to a signal, then the return value is the
signal number - 128, ie. it is negative and so indicates an unusual
condition; a diagnostic is printed. This return value can be passed to
exit(2), which will report the same code to the parent process that a
POSIX shell's $? would report for a program that died from the signal.


`start_async`::

Run a function asynchronously. Takes a pointer to a `struct
Expand Down Expand Up @@ -143,6 +163,11 @@ string pointers (NULL terminated) in .env:
To specify a new initial working directory for the sub-process,
specify it in the .dir member.

If the program cannot be found, the functions return -1 and set
errno to ENOENT. Normally, an error message is printed, but if
.silent_exec_failure is set to 1, no message is printed for this
special error condition.


* `struct async`

Expand Down
2 changes: 1 addition & 1 deletion builtin-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
discard_cache();
if (read_cache() < 0)
die("failed to read the cache");
return -ret;
return ret;
}
}

Expand Down
38 changes: 4 additions & 34 deletions builtin-receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,31 +123,6 @@ static struct command *commands;
static const char pre_receive_hook[] = "hooks/pre-receive";
static const char post_receive_hook[] = "hooks/post-receive";

static int run_status(int code, const char *cmd_name)
{
switch (code) {
case 0:
return 0;
case -ERR_RUN_COMMAND_FORK:
return error("fork of %s failed", cmd_name);
case -ERR_RUN_COMMAND_EXEC:
return error("execute of %s failed", cmd_name);
case -ERR_RUN_COMMAND_PIPE:
return error("pipe failed");
case -ERR_RUN_COMMAND_WAITPID:
return error("waitpid failed");
case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
return error("waitpid is confused");
case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
return error("%s died of signal", cmd_name);
case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
return error("%s died strangely", cmd_name);
default:
error("%s exited with error code %d", cmd_name, -code);
return -code;
}
}

static int run_receive_hook(const char *hook_name)
{
static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
Expand All @@ -174,7 +149,7 @@ static int run_receive_hook(const char *hook_name)

code = start_command(&proc);
if (code)
return run_status(code, hook_name);
return code;
for (cmd = commands; cmd; cmd = cmd->next) {
if (!cmd->error_string) {
size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
Expand All @@ -186,7 +161,7 @@ static int run_receive_hook(const char *hook_name)
}
}
close(proc.in);
return run_status(finish_command(&proc), hook_name);
return finish_command(&proc);
}

static int run_update_hook(struct command *cmd)
Expand All @@ -203,9 +178,8 @@ static int run_update_hook(struct command *cmd)
argv[3] = sha1_to_hex(cmd->new_sha1);
argv[4] = NULL;

return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
RUN_COMMAND_STDOUT_TO_STDERR),
update_hook);
return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
RUN_COMMAND_STDOUT_TO_STDERR);
}

static int is_ref_checked_out(const char *ref)
Expand Down Expand Up @@ -419,7 +393,6 @@ static void run_update_post_hook(struct command *cmd)
argv[argc] = NULL;
status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
| RUN_COMMAND_STDOUT_TO_STDERR);
run_status(status, update_post_hook);
}

static void execute_commands(const char *unpacker_error)
Expand Down Expand Up @@ -537,7 +510,6 @@ static const char *unpack(void)
code = run_command_v_opt(unpacker, RUN_GIT_CMD);
if (!code)
return NULL;
run_status(code, unpacker[0]);
return "unpack-objects abnormal exit";
} else {
const char *keeper[7];
Expand All @@ -563,7 +535,6 @@ static const char *unpack(void)
ip.git_cmd = 1;
status = start_command(&ip);
if (status) {
run_status(status, keeper[0]);
return "index-pack fork failed";
}
pack_lockfile = index_pack_lockfile(ip.out);
Expand All @@ -573,7 +544,6 @@ static const char *unpack(void)
reprepare_packed_git();
return NULL;
}
run_status(status, keeper[0]);
return "index-pack abnormal exit";
}
}
Expand Down
5 changes: 3 additions & 2 deletions compat/mingw.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ typedef int pid_t;
#define S_IROTH 0
#define S_IXOTH 0

#define WIFEXITED(x) ((unsigned)(x) < 259) /* STILL_ACTIVE */
#define WIFEXITED(x) 1
#define WIFSIGNALED(x) 0
#define WEXITSTATUS(x) ((x) & 0xff)
#define WIFSIGNALED(x) ((unsigned)(x) > 259)
#define WTERMSIG(x) SIGTERM

#define SIGHUP 1
#define SIGQUIT 3
Expand Down
2 changes: 1 addition & 1 deletion convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static int filter_buffer(int fd, void *data)

status = finish_command(&child_process);
if (status)
error("external filter %s failed %d", params->cmd, -status);
error("external filter %s failed %d", params->cmd, status);
return (write_err || status);
}

Expand Down
10 changes: 3 additions & 7 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,13 +416,9 @@ 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);
if (status != -ERR_RUN_COMMAND_EXEC) {
if (IS_RUN_COMMAND_ERR(status))
die("unable to run '%s'", argv[0]);
exit(-status);
}
errno = ENOENT; /* as if we called execvp */
status = run_command_v_opt(argv, RUN_SILENT_EXEC_FAILURE);
if (status >= 0 || errno != ENOENT)
exit(status);

argv[0] = tmp;

Expand Down
4 changes: 0 additions & 4 deletions ll-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,6 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,

args[2] = cmd.buf;
status = run_command_v_opt(args, 0);
if (status < -ERR_RUN_COMMAND_FORK)
; /* failure in run-command */
else
status = -status;
fd = open(temp[1], O_RDONLY);
if (fd < 0)
goto bad;
Expand Down
Loading

0 comments on commit 08ac696

Please sign in to comment.