diff options
author | Andrew Price <anprice@redhat.com> | 2014-04-26 15:31:19 +0100 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-09-24 12:02:09 -0700 |
commit | 33e3face4ae0c7e0f67e3a92edc8d1e818ef6515 (patch) | |
tree | 1e29a8a22026a20bf055d2664ef4b91446266bc7 | |
parent | 7f64c1928f85235e01e6f268fdc4cbfc921b5c42 (diff) | |
download | blktrace-33e3face4ae0c7e0f67e3a92edc8d1e818ef6515.tar.gz |
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 <anprice@redhat.com>
-rw-r--r-- | iowatcher/blkparse.c | 2 | ||||
-rw-r--r-- | iowatcher/tracers.c | 47 | ||||
-rw-r--r-- | 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); |