2 #include <sys/select.h>
7 static int child_count = 0;
8 static int parent_count = 0;
9 static int process_count = 0;
11 int get_child_count(void)
16 int get_parent_count(void)
21 int get_sibling_count(void)
32 pr_err("fork() failed: %s\n", strerror(error));
38 pr_info("Fork %d, child %d\n", child_count, child);
42 process_count = child_count;
43 /* reset child's child count */
49 int harvest_zombies(int pid)
57 pr_info("Waiting on pid %d, children left: %d\n", pid,
60 pid = waitpid(pid, &status, 0);
63 pr_err("Error on wait(): %s\n", strerror(error));
64 child_count--; /* Decrement child count anyway */
68 pr_info("pid %d: exit code %d. Children left: %d\n", pid,
76 * Runs a command cmd with params argv, connects stdin and stdout to
79 * Returns the pid of the executed process
81 int run_piped(const char *cmd, char *const argv[],
82 int *stdinfd, int *stdoutfd, int *stderrfd)
84 int ifd[2], ofd[2], efd[2], error, pid;
86 pr_info("Running command %s\n", cmd);
88 if (stdinfd && pipe(ifd)) {
90 pr_err("pipe() failed: %s\n", strerror(error));
94 if (stdoutfd && pipe(ofd)) {
96 pr_err("pipe() failed: %s\n", strerror(error));
100 if (stderrfd && pipe(efd)) {
102 pr_err("pipe() failed: %s\n", strerror(error));
107 if (pid) { /* Parent side */
128 dup2(ifd[0], STDIN_FILENO);
133 dup2(ofd[1], STDOUT_FILENO);
138 dup2(efd[1], STDERR_FILENO);
141 /* Now we have redirected standard streams to parent process */
144 pr_err("Failed to execv command %s: %s\n", cmd, strerror(error));
151 * Runs a command cmd with params argv, connects stdin and stdout to
154 * Returns the pid of the executed process
156 int run_piped_stream(const char *cmd, char *const argv[],
157 FILE **stdinf, FILE **stdoutf, FILE **stderrf)
159 int ifd, ofd, efd, pid, error;
175 pid = run_piped(cmd, argv, i, o, e);
178 *stdinf = fdopen(ifd, "r");
179 if (*stdinf == NULL) {
181 pr_err("Error opening file stream for fd %d: %s\n",
182 ifd, strerror(error));
188 *stdoutf = fdopen(ofd, "r");
189 if (*stdoutf == NULL) {
191 pr_err("Error opening file stream for fd %d: %s\n",
192 ofd, strerror(error));
198 *stderrf = fdopen(efd, "r");
199 if (*stderrf == NULL) {
201 pr_err("Error opening file stream for fd %d: %s\n",
202 efd, strerror(error));
211 * Forks a child and executes a command to run on parallel
214 #define max(a,b) (a) < (b) ? (b) : (a)
215 #define BUF_SIZE (128*1024)
216 int run(const char *cmd, char *const argv[])
223 char stdoutstr[32], stderrstr[32], indent[16] = { " " };
225 indent[get_parent_count() + 1] = 0;
227 if ((child = do_fork()))
230 child = run_piped(cmd, argv, NULL, &ofd, &efd);
231 snprintf(stdoutstr, 32, "%sstdout", green_color);
232 snprintf(stderrstr, 32, "%sstderr", red_color);
244 maxfd = max(ofd, efd);
245 error = select(maxfd, &rfds, NULL, NULL, NULL);
248 printf("Error with select: %m\n");
252 if (FD_ISSET(ofd, &rfds)) {
254 bytes = read(ofd, rbuf, BUF_SIZE);
258 if (FD_ISSET(efd, &rfds)) {
260 bytes = read(efd, rbuf, BUF_SIZE);
264 pr_err("select() returned unknown fd\n");
270 pr_err("read() failed: %s\n", strerror(error));
275 * Workaround: When a process had die and it has only
276 * written to stderr, select() doesn't indicate that
277 * there might be something to read in stderr fd. To
278 * work around this issue, we try to read stderr just
279 * in case in order to ensure everything gets read.
282 bytes = read(efd, rbuf, BUF_SIZE);
291 printf("%s[%5d %s] %s: %s%s\n", indent,
292 child, cmd, typestr, sptr, normal_color);
302 harvest_zombies(child);