And persistent_waitpid() to recover the information from the last run.
Signed-off-by: Felipe Contreras <[email protected]>
---
run-command.c | 46 ++++++++++++++++++++++++++++++++++++++++------
run-command.h | 6 ++++++
2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/run-command.c b/run-command.c
index 07e27ff..16833df 100644
--- a/run-command.c
+++ b/run-command.c
@@ -226,14 +226,27 @@ static inline void set_cloexec(int fd)
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
-static int wait_or_whine(pid_t pid, const char *argv0)
+static pid_t persistent_waitpid(struct child_process *cmd, pid_t pid, int
*stat_loc)
+{
+ if (cmd->last_wait.code) {
+ errno = cmd->last_wait.failed_errno;
+ *stat_loc = cmd->last_wait.status;
+ return errno ? -1 : pid;
+ } else {
+ pid_t waiting;
+ while ((waiting = waitpid(pid, stat_loc, 0)) < 0 && errno ==
EINTR)
+ ; /* nothing */
+ return waiting;
+ }
+}
+
+static int wait_or_whine(struct child_process *cmd, pid_t pid, const char
*argv0)
{
int status, code = -1;
pid_t waiting;
int failed_errno = 0;
- while ((waiting = waitpid(pid, &status, 0)) < 0 && errno == EINTR)
- ; /* nothing */
+ waiting = persistent_waitpid(cmd, pid, &status);
if (waiting < 0) {
failed_errno = errno;
@@ -437,7 +450,7 @@ fail_pipe:
* At this point we know that fork() succeeded, but execvp()
* failed. Errors have been reported to our stderr.
*/
- wait_or_whine(cmd->pid, cmd->argv[0]);
+ wait_or_whine(cmd, cmd->pid, cmd->argv[0]);
failed_errno = errno;
cmd->pid = -1;
}
@@ -542,7 +555,7 @@ fail_pipe:
int finish_command(struct child_process *cmd)
{
- return wait_or_whine(cmd->pid, cmd->argv[0]);
+ return wait_or_whine(cmd, cmd->pid, cmd->argv[0]);
}
int run_command(struct child_process *cmd)
@@ -553,6 +566,27 @@ int run_command(struct child_process *cmd)
return finish_command(cmd);
}
+int check_command(struct child_process *cmd)
+{
+ int status;
+ pid_t waiting;
+ int failed_errno = 0;
+
+ waiting = waitpid(cmd->pid, &status, WNOHANG);
+
+ if (waiting != cmd->pid)
+ return 1;
+
+ if (waiting < 0)
+ failed_errno = errno;
+
+ cmd->last_wait.code = -1;
+ cmd->last_wait.failed_errno = failed_errno;
+ cmd->last_wait.status = status;
+
+ return 0;
+}
+
static void prepare_run_command_v_opt(struct child_process *cmd,
const char **argv,
int opt)
@@ -729,7 +763,7 @@ error:
int finish_async(struct async *async)
{
#ifdef NO_PTHREADS
- return wait_or_whine(async->pid, "child process");
+ return wait_or_whine(cmd, async->pid, "child process");
#else
void *ret = (void *)(intptr_t)(-1);
diff --git a/run-command.h b/run-command.h
index 221ce33..66aaac7 100644
--- a/run-command.h
+++ b/run-command.h
@@ -39,11 +39,17 @@ struct child_process {
unsigned stdout_to_stderr:1;
unsigned use_shell:1;
unsigned clean_on_exit:1;
+ struct last_wait {
+ int code;
+ int failed_errno;
+ int status;
+ } last_wait;
};
int start_command(struct child_process *);
int finish_command(struct child_process *);
int run_command(struct child_process *);
+int check_command(struct child_process *);
extern char *find_hook(const char *name);
extern int run_hook(const char *index_file, const char *name, ...);
--
1.8.2
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html