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