summaryrefslogtreecommitdiff
path: root/src/libstddjb/child_spawn0.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-06-28 21:27:29 +0000
committerLaurent Bercot <ska@appnovation.com>2023-06-28 21:27:29 +0000
commit28e09b5eb76919122f8baf57899154b3dd5fdaa0 (patch)
tree21559ec98d7f0f876fa0e2a5115744e396fd68d0 /src/libstddjb/child_spawn0.c
parentd64a3751ca805c08bfda6a330d73a09e87e993c0 (diff)
downloadskalibs-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.c56
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 ;