iowatcher: Separate program running from waiting
authorAndrew Price <anprice@redhat.com>
Sat, 26 Apr 2014 14:31:19 +0000 (15:31 +0100)
committerChris Mason <clm@fb.com>
Wed, 24 Sep 2014 19:02:09 +0000 (12:02 -0700)
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>
iowatcher/blkparse.c
iowatcher/tracers.c
iowatcher/tracers.h

index 1555845f6c98a616dba67c3671e180c607c42b84..447d14cf9d6de2d153e7184baf17b5f6e1452d02 100644 (file)
@@ -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;
 }
index f42958b57f900183bb704ccce4416ca59363eaa4..12efb4e6ffea26921b66c8d58d916171761415e1 100644 (file)
@@ -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;
 }
index 0db19b4bb1da5b7c53ac8fa402f571bfa5f79cdc..d0b8b6ba768d7b8a3c38d7070805f5112efe5786 100644 (file)
@@ -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);