]> git.itanic.dy.fi Git - rrdd/blob - process.c
Move all fork operations to do_fork() functino
[rrdd] / process.c
1 #include "process.h"
2
3 int child_count = 0;
4
5 int do_fork(void)
6 {
7         int child, error;
8         child = fork();
9         if (child < 0) {
10                 error = errno;
11                 fprintf(stderr, "fork() failed: %s\n", strerror(error));
12                 return -1;
13         }
14
15         if (child) {
16                 printf("%d: Forked child %d\n", getpid(), child);
17                 child_count++;
18                 return child;
19         }
20
21         /* reset child's child count */
22         child_count = 0;
23         return 0;
24 }
25
26 int run(const char *cmd, char *const argv[])
27 {
28         int child, error;
29         if ((child = do_fork()))
30             return child;
31
32         execvp(cmd, argv);
33         error = errno;
34         printf("Failed to execv command %s: %s\n", cmd, strerror(error));
35         exit(1);
36         return 0;
37 }
38
39 int harvest_zombies(int pid)
40 {
41         int status, error;
42
43         if (child_count == 0)
44                 return 0;
45
46         pid = waitpid(pid, &status, 0);
47         if (pid < 0) {
48                 error = errno;
49                 fprintf(stderr, "%d: Error on wait(): %s\n", getpid(),
50                         strerror(error));
51         }
52         else
53                 printf("pid %d: exit %d. %d still running\n", pid, status,
54                        child_count--);
55
56         return 1;
57 }
58
59 /*
60  * Runs a command cmd with params argv, connects stdin and stdout to
61  * readfd and writefd
62  *
63  * Returns the pid of the executed process
64  */
65 int run_piped(const char *cmd, char *const argv[], int *readfd, int *writefd)
66 {
67         int rfd[2], wfd[2], error, pid;
68
69         if (pipe(rfd)) {
70                 error = errno;
71                 fprintf(stderr, "pipe() failed: %s\n", strerror(error));
72                 return -1;
73         }
74
75         if (pipe(wfd)) {
76                 error = errno;
77                 fprintf(stderr, "pipe() failed: %s\n", strerror(error));
78                 return -1;
79         }
80
81         pid = do_fork();
82         if (pid) {
83                 close(rfd[1]);
84                 close(wfd[0]);
85                 *readfd = rfd[0];
86                 *writefd = wfd[1];
87                 child_count++;
88                 return pid;
89         }
90
91         close(rfd[0]);
92         close(wfd[1]);
93         dup2(wfd[0], STDIN_FILENO);
94         dup2(rfd[1], STDOUT_FILENO);
95
96         /* Now we have redirected both stdin and stdout to parent process */
97         execvp(cmd, argv);
98         error = errno;
99         printf("Failed to execv command %s: %s\n", cmd, strerror(error));
100         exit(1);
101         return 0;
102 }
103
104 /*
105  * Runs a command cmd with params argv, connects stdin and stdout to
106  * readfd and writefd
107  *
108  * Returns the pid of the executed process
109  */
110 int run_piped_stream(const char *cmd, char *const argv[],
111                      FILE **readf, FILE **writef)
112 {
113         int rfd, wfd, pid, error;
114
115         pid = run_piped(cmd, argv, &rfd, &wfd);
116
117         if (readf) {
118                 *readf = fdopen(rfd, "r");
119                 if (*readf == NULL) {
120                         error = errno;
121                         fprintf(stderr,
122                                 "Error opening file stream for fd %d: %s\n",
123                                 rfd, strerror(error));
124                         return -1;
125                 }
126         }
127
128         if (writef) {
129                 *writef = fdopen(wfd, "w");
130                 if (*writef == NULL) {
131                         error = errno;
132                         fprintf(stderr,
133                                 "Error opening file stream for fd %d: %s\n",
134                                 wfd, strerror(error));
135                         return -1;
136                 }
137         }
138
139         return pid;
140 }