]> git.itanic.dy.fi Git - rrdd/commitdiff
Add support for executing process while piping std{in,out} to parent
authorTimo Kokkonen <kaapeli@ee.oulu.fi>
Mon, 31 Mar 2008 17:48:30 +0000 (20:48 +0300)
committerTimo Kokkonen <kaapeli@ee.oulu.fi>
Mon, 31 Mar 2008 17:48:30 +0000 (20:48 +0300)
process.c
process.h

index a04e495a2ff1eaa66757d6b22c9f3b12a8a37714..c016eab8337cf0e614e2f828c28838c9dc2379d3 100644 (file)
--- a/process.c
+++ b/process.c
@@ -2,7 +2,7 @@
 
 int child_count = 0;
 
-int run(const char *p, char *const argv[])
+int run(const char *cmd, char *const argv[])
 {
        int child, error;
        child = fork();
@@ -18,22 +18,21 @@ int run(const char *p, char *const argv[])
                return child;
        }
 
-       execvp(p, argv);
+       execvp(cmd, argv);
        error = errno;
-       printf("Failed to execv: %s\n", strerror(error));
+       printf("Failed to execv command %s: %s\n", cmd, strerror(error));
        exit(1);
        return 0;
 }
 
-int harvest_zombies()
+int harvest_zombies(int pid)
 {
        int status;
-       pid_t pid;
 
        if (child_count == 0)
                return 0;
 
-       pid = wait(&status);
+       pid = waitpid(pid, &status, 0);
        if (status == 0)
                printf("pid %d: terminated with exit code %d\n", pid, status);
 
@@ -41,3 +40,91 @@ int harvest_zombies()
        return 1;
 }
 
+/*
+ * Runs a command cmd with params argv, connects stdin and stdout to
+ * readfd and writefd
+ *
+ * Returns the pid of the executed process
+ */
+int run_piped(const char *cmd, char *const argv[], int *readfd, int *writefd)
+{
+       int rfd[2], wfd[2], error, pid;
+
+       if (pipe(rfd)) {
+               error = errno;
+               fprintf(stderr, "pipe() failed: %s\n", strerror(error));
+               return -1;
+       }
+
+       if (pipe(wfd)) {
+               error = errno;
+               fprintf(stderr, "pipe() failed: %s\n", strerror(error));
+               return -1;
+       }
+
+       pid = fork();
+       if (pid < 0) {
+               printf("parent\n");
+               error = errno;
+               fprintf(stderr, "fork() failed: %s\n", strerror(error));
+               return -1;
+       }
+
+       if (pid) {
+               close(rfd[1]);
+               close(wfd[0]);
+               *readfd = rfd[0];
+               *writefd = wfd[1];
+               return pid;
+       }
+
+       close(rfd[0]);
+       close(wfd[1]);
+       dup2(wfd[0], STDIN_FILENO);
+       dup2(rfd[1], STDOUT_FILENO);
+
+       /* Now we have redirected both stdin and stdout to parent process */
+       execvp(cmd, argv);
+       error = errno;
+       printf("Failed to execv command %s: %s\n", cmd, strerror(error));
+       exit(1);
+       return 0;
+}
+
+/*
+ * Runs a command cmd with params argv, connects stdin and stdout to
+ * readfd and writefd
+ *
+ * Returns the pid of the executed process
+ */
+int run_piped_stream(const char *cmd, char *const argv[],
+                    FILE **readf, FILE **writef)
+{
+       int rfd, wfd, pid, error;
+
+       pid = run_piped(cmd, argv, &rfd, &wfd);
+
+       if (readf) {
+               *readf = fdopen(rfd, "r");
+               if (*readf == NULL) {
+                       error = errno;
+                       fprintf(stderr,
+                               "Error opening file stream for fd %d: %s\n",
+                               rfd, strerror(error));
+                       return -1;
+               }
+       }
+
+       if (writef) {
+               *writef = fdopen(wfd, "w");
+               if (*writef == NULL) {
+                       error = errno;
+                       fprintf(stderr,
+                               "Error opening file stream for fd %d: %s\n",
+                               wfd, strerror(error));
+                       return -1;
+               }
+       }
+
+       return pid;
+}
index 0497d74f2aff7239d799fa9ab0d14b9ce4250bb9..a44cad0f1e77f1c0809445ab2a5d2fb8a693b5ca 100644 (file)
--- a/process.h
+++ b/process.h
 #include <errno.h>
 
 int run(const char *p, char *const argv[]);
-int harvest_zombies();
+int harvest_zombies(int pid);
+int run_piped(const char *cmd, char *const argv[], int *readfd, int *writefd);
+int run_piped_stream(const char *cmd, char *const argv[],
+                    FILE **readf, FILE **writef);
 
 extern int child_count;