pipeln

Pipeline creation tool
git clone https://git.sinitax.com/sinitax/pipeln
Log | Files | Refs | README | LICENSE | sfeed.txt

commit fd350bad9f011b443d27740667c141fc57d2d36e
parent 8432d5ce27e628b0fec22720f57e31665dcd0dd5
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed,  7 Jun 2023 21:49:17 +0200

Parallelize process execution

Diffstat:
Mmain.c | 40+++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)

diff --git 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;