summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-06-07 21:49:17 +0200
committerLouis Burda <quent.burda@gmail.com>2023-06-07 21:49:17 +0200
commitfd350bad9f011b443d27740667c141fc57d2d36e (patch)
tree9301dcd988062b384b8ada824dce187f6a1cb50e
parent8432d5ce27e628b0fec22720f57e31665dcd0dd5 (diff)
downloadpipeln-fd350bad9f011b443d27740667c141fc57d2d36e.tar.gz
pipeln-fd350bad9f011b443d27740667c141fc57d2d36e.zip
Parallelize process execution
-rw-r--r--main.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/main.c b/main.c
index 98ae079..aeb952f 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,7 @@
-#include <sys/wait.h>
+#include <asm-generic/errno-base.h>
#include <linux/limits.h>
+#include <sys/wait.h>
+#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <wait.h>
@@ -66,10 +68,9 @@ findbin(const char *name)
die("findbin %s", name);
}
-int
+void
run(int *in, int *out, const char **argv)
{
- int status;
pid_t child;
if (!argv[0]) die("run: empty command");
@@ -83,26 +84,39 @@ run(int *in, int *out, const char **argv)
if (!child) {
if (in) {
close(0);
- dup2(in[0], 0);
+ if (dup2(in[0], 0) < 0)
+ die("dup2:");
}
if (out) {
close(1);
- dup2(out[1], 1);
+ if (dup2(out[1], 1) < 0)
+ die("dup2:");
}
execv(argv[0], (char *const *) argv);
die("execv %s:", argv[0]);
}
if (in) close(in[0]);
if (out) close(out[1]);
+}
- do {
- waitpid(child, &status, 0);
- } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+void
+waitall(void)
+{
+ int rc, status, exitcode;
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- else
- return 128 + WTERMSIG(status);
+ errno = 0;
+ exitcode = 0;
+ do {
+ rc = waitpid(-1, &status, 0);
+ if (rc < 0 && errno != EINTR && errno != ECHILD)
+ die("waitpid:");
+ if (!exitcode && WIFEXITED(status))
+ exitcode = WEXITSTATUS(status);
+ else if (!exitcode && WIFSIGNALED(status))
+ exitcode = WTERMSIG(status);
+ } while (rc >= 0 && errno != ECHILD);
+
+ exit(exitcode);
}
int
@@ -126,8 +140,8 @@ main(int argc, const char **argv)
/* run piped cmd */
*arg = NULL;
run(in, out, cmdargs);
+ if (!out) waitall();
cmdargs = arg + 1;
- if (!out) break;
/* out => in */
in = out;