From 33e3face4ae0c7e0f67e3a92edc8d1e818ef6515 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Sat, 26 Apr 2014 15:31:19 +0100 Subject: [PATCH] iowatcher: Separate program running from waiting Until now run_program2() was a replacement for system() so it always waited for the process to end before returning. To make this function more useful move the waiting code into a separate function and add a mechanism to expect a specific exit code. Signed-off-by: Andrew Price --- iowatcher/blkparse.c | 2 +- iowatcher/tracers.c | 47 +++++++++++++++++++++++++++++--------------- iowatcher/tracers.h | 3 ++- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/iowatcher/blkparse.c b/iowatcher/blkparse.c index 1555845..447d14c 100644 --- a/iowatcher/blkparse.c +++ b/iowatcher/blkparse.c @@ -801,7 +801,7 @@ static int dump_traces(struct tracelist *traces, int count, char *dumpfile) argv[i++] = tl->name; } - err = run_program2(argc, argv); + err = run_program2(argc, argv, 0, NULL); free(argv); return err; } diff --git a/iowatcher/tracers.c b/iowatcher/tracers.c index f42958b..12efb4e 100644 --- a/iowatcher/tracers.c +++ b/iowatcher/tracers.c @@ -36,6 +36,7 @@ #include "plot.h" #include "blkparse.h" #include "list.h" +#include "tracers.h" extern char **environ; @@ -178,33 +179,47 @@ int run_program(char *str) return 0; } -int run_program2(int argc, char **argv) +int wait_program(pid_t pid, const char *pname, int expexit) +{ + int status; + int ret = 0; + + waitpid(pid, &status, 0); + if (WIFEXITED(status)) { + ret = WEXITSTATUS(status); + if (ret == 127) /* spawnp failed after forking */ + fprintf(stderr, "Failed to run '%s'\n", pname); + else if (ret != expexit) + fprintf(stderr, "'%s' exit status %d, expected %d\n", + pname, ret, expexit); + } else if (WIFSIGNALED(status)) { + fprintf(stderr, "'%s' killed by signal %d\n", pname, WTERMSIG(status)); + ret = -1; + } + return ret; +} + +int run_program2(int argc, char **argv, int expexit, pid_t *pid) { int i; int err; - int status; - pid_t pid; + pid_t _pid; fprintf(stderr, "running"); for (i = 0; i < argc; i++) fprintf(stderr, " '%s'", argv[i]); fprintf(stderr, "\n"); - err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ); + err = posix_spawnp(&_pid, argv[0], NULL, NULL, argv, environ); if (err != 0) { fprintf(stderr, "Could not run '%s': %s\n", argv[0], strerror(err)); - return -err; - } - waitpid(pid, &status, 0); - if (WIFEXITED(status)) { - err = WEXITSTATUS(status); - if (err == 127) /* spawnp failed after forking */ - fprintf(stderr, "Failed to run '%s'\n", argv[0]); - else if (err) - fprintf(stderr, "'%s' failed with exit status %d\n", argv[0], err); - } else if (WIFSIGNALED(status)) { - fprintf(stderr, "'%s' killed by signal %d\n", argv[0], WTERMSIG(status)); - return 1; + } else if (expexit >= 0) { + err = wait_program(_pid, argv[0], expexit); + } else if (!pid) { + fprintf(stderr, "Warning: %s (%ld): Not saving pid and not waiting for it.\n", + argv[0], (long)_pid); + } else { + *pid = _pid; } return err; } diff --git a/iowatcher/tracers.h b/iowatcher/tracers.h index 0db19b4..d0b8b6b 100644 --- a/iowatcher/tracers.h +++ b/iowatcher/tracers.h @@ -18,7 +18,8 @@ #ifndef __IOWATCH_TRACERS #define __IOWATCH_TRACERS int run_program(char *str); -int run_program2(int argc, char **argv); +int run_program2(int argc, char **argv, int expexit, pid_t *pid); +int wait_program(pid_t pid, const char *pname, int expexit); int stop_blktrace(void); int start_blktrace(char **devices, int num_devices, char *trace_name, char *dest); int start_mpstat(char *trace_name); -- 2.25.1