diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2023-06-28 21:27:29 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2023-06-28 21:27:29 +0000 |
commit | 28e09b5eb76919122f8baf57899154b3dd5fdaa0 (patch) | |
tree | 21559ec98d7f0f876fa0e2a5115744e396fd68d0 /src/libstddjb/child_spawn0.c | |
parent | d64a3751ca805c08bfda6a330d73a09e87e993c0 (diff) | |
download | skalibs-28e09b5eb76919122f8baf57899154b3dd5fdaa0.tar.xz |
Add workaround for bad QoI posix_spawn()
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libstddjb/child_spawn0.c')
-rw-r--r-- | src/libstddjb/child_spawn0.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/src/libstddjb/child_spawn0.c b/src/libstddjb/child_spawn0.c index 5b59b20..cfd78f8 100644 --- a/src/libstddjb/child_spawn0.c +++ b/src/libstddjb/child_spawn0.c @@ -1,42 +1,59 @@ /* ISC license. */ #include <skalibs/sysdeps.h> + #include <errno.h> #ifdef SKALIBS_HASPOSIXSPAWN #include <signal.h> -#include <spawn.h> #include <stdlib.h> +#include <spawn.h> #include <skalibs/config.h> +#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN +# include <skalibs/djbunix.h> +# include "child_spawn-internal.h" +#endif + pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const *envp) { pid_t pid ; posix_spawnattr_t attr ; + sigset_t set ; int e ; int nopath = !getenv("PATH") ; +#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN + int p[2] ; + if (pipecoe(p) == -1) return 0 ; +#endif e = posix_spawnattr_init(&attr) ; if (e) goto err ; - { - sigset_t set ; - sigemptyset(&set) ; - e = posix_spawnattr_setsigmask(&attr, &set) ; - if (e) goto errattr ; - e = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK) ; - if (e) goto errattr ; - } + sigemptyset(&set) ; + e = posix_spawnattr_setsigmask(&attr, &set) ; + if (e) goto errattr ; + e = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK) ; + if (e) goto errattr ; if (nopath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)) { e = errno ; goto errattr ; } e = posix_spawnp(&pid, prog, 0, &attr, (char *const *)argv, (char *const *)envp) ; if (nopath) unsetenv("PATH") ; + if (e) goto errattr ; + posix_spawnattr_destroy(&attr) ; - if (e) goto err ; +#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN + return child_spawn_workaround(pid, p) ; +#else return pid ; +#endif errattr: posix_spawnattr_destroy(&attr) ; err: +#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN + fd_close(p[1]) ; + fd_close(p[0]) ; +#endif errno = e ; return 0 ; } @@ -44,10 +61,8 @@ pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const #else #include <unistd.h> -#include <string.h> #include <skalibs/allreadwrite.h> -#include <skalibs/strerr.h> #include <skalibs/sig.h> #include <skalibs/djbunix.h> #include <skalibs/exec.h> @@ -56,8 +71,9 @@ pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const { pid_t pid ; int p[2] ; - unsigned char c ; - if (pipecoe(p) < 0) return 0 ; + char c ; + + if (pipecoe(p) == -1) return 0 ; pid = fork() ; if (pid < 0) { @@ -67,20 +83,14 @@ pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const } if (!pid) { - size_t len = strlen(PROG) ; - char name[len + 9] ; - memcpy(name, PROG, len) ; - memcpy(name + len, " (child)", 9) ; - PROG = name ; - fd_close(p[0]) ; sig_blocknone() ; exec_ae(prog, argv, envp) ; c = errno ; - fd_write(p[1], (char *)&c, 1) ; + fd_write(p[1], &c, 1) ; _exit(127) ; } fd_close(p[1]) ; - p[1] = fd_read(p[0], (char *)&c, 1) ; + p[1] = fd_read(p[0], &c, 1) ; if (p[1] < 0) { fd_close(p[0]) ; @@ -90,7 +100,7 @@ pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const if (p[1]) { wait_pid(pid, &p[0]) ; - errno = c ; + errno = (unsigned char)c ; return 0 ; } return pid ; |