diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2024-04-30 19:09:43 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2024-04-30 19:09:43 +0000 |
commit | 02926ee3447b1ea0d04b53b8fcb08d8b1a4deec5 (patch) | |
tree | f0cffb716e9ba61382795b460203df506e13ed4b /src/libstddjb | |
parent | 944a9d260a41b30f32730ccb12b3f5dafb507b7d (diff) | |
download | skalibs-02926ee3447b1ea0d04b53b8fcb08d8b1a4deec5.tar.xz |
Add mspawn functions to cspawn.h; move everything to libenvexec
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libstddjb')
-rw-r--r-- | src/libstddjb/child_spawn.c | 61 | ||||
-rw-r--r-- | src/libstddjb/child_spawn0.c | 8 | ||||
-rw-r--r-- | src/libstddjb/child_spawn1_internal.c | 27 | ||||
-rw-r--r-- | src/libstddjb/child_spawn1_pipe.c | 17 | ||||
-rw-r--r-- | src/libstddjb/child_spawn1_socket.c | 16 | ||||
-rw-r--r-- | src/libstddjb/child_spawn2.c | 39 | ||||
-rw-r--r-- | src/libstddjb/child_spawn3.c | 55 | ||||
-rw-r--r-- | src/libstddjb/cspawn-internal.h | 10 | ||||
-rw-r--r-- | src/libstddjb/cspawn.c | 297 | ||||
-rw-r--r-- | src/libstddjb/gcspawn.c | 48 |
10 files changed, 0 insertions, 578 deletions
diff --git a/src/libstddjb/child_spawn.c b/src/libstddjb/child_spawn.c deleted file mode 100644 index 164f1b2..0000000 --- a/src/libstddjb/child_spawn.c +++ /dev/null @@ -1,61 +0,0 @@ -/* ISC license. */ - -#include <string.h> -#include <unistd.h> - -#include <skalibs/types.h> -#include <skalibs/djbunix.h> -#include <skalibs/env.h> -#include <skalibs/cspawn.h> - -pid_t child_spawn (char const *prog, char const *const *argv, char const *const *envp, int *fds, size_t n) -{ - pid_t pid ; - cspawn_fileaction fa[2] = - { - [0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = 1 } } }, - [1] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = 0 } } } - } ; - size_t m = sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR) ; - size_t envlen = env_len(envp) ; - size_t i = 0 ; - int p[n ? n : 1][2] ; - char const *newenv[envlen + 2] ; - char modifs[m + 1 + n * UINT_FMT] ; - - for (; i < n ; i++) - { - if (pipe(p[i]) == -1) goto errpi ; - if ((ndelay_on(p[i][i & 1]) == -1) || (coe(p[i][i & 1]) == -1)) goto errpip ; - } - - memcpy(modifs, SKALIBS_CHILD_SPAWN_FDS_ENVVAR "=", sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR)) ; - for (i = 2 ; i < n ; i++) - { - m += uint_fmt(modifs + m, p[i][!(i & 1)]) ; - if (i+1 < n) modifs[m++] = ',' ; - } - modifs[m++] = 0 ; - env_mergen(newenv, envlen + 2, envp, envlen, modifs, m, 1) ; - if (n) fa[0].x.fd2[1] = p[0][1] ; - if (n >= 2) fa[1].x.fd2[1] = p[1][0] ; - pid = cspawn(prog, argv, newenv, CSPAWN_FLAGS_SIGBLOCKNONE, fa, n < 2 ? n : 2) ; - if (!pid) goto errpi ; - - for (i = 0 ; i < n ; i++) - { - fd_close(p[i][!(i & 1)]) ; - fds[i] = p[i][i & 1] ; - } - return pid ; - - errpip: - i++ ; - errpi: - while (i--) - { - fd_close(p[i][1]) ; - fd_close(p[i][0]) ; - } - return 0 ; -} diff --git a/src/libstddjb/child_spawn0.c b/src/libstddjb/child_spawn0.c deleted file mode 100644 index b1353b6..0000000 --- a/src/libstddjb/child_spawn0.c +++ /dev/null @@ -1,8 +0,0 @@ -/* ISC license. */ - -#include <skalibs/cspawn.h> - -pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const *envp) -{ - return cspawn(prog, argv, envp, CSPAWN_FLAGS_SIGBLOCKNONE, 0, 0) ; -} diff --git a/src/libstddjb/child_spawn1_internal.c b/src/libstddjb/child_spawn1_internal.c deleted file mode 100644 index e65b588..0000000 --- a/src/libstddjb/child_spawn1_internal.c +++ /dev/null @@ -1,27 +0,0 @@ -/* ISC license. */ - -#include <skalibs/djbunix.h> -#include <skalibs/cspawn.h> -#include "cspawn-internal.h" - -pid_t child_spawn1_internal (char const *prog, char const *const *argv, char const *const *envp, int *p, int to) -{ - pid_t pid ; - cspawn_fileaction fa[3] = - { - [0] = { .type = CSPAWN_FA_CLOSE, .x = { .fd = p[!(to & 1)]} }, - [1] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = to & 1, [1] = p[to & 1] } } }, - [2] = { .type = CSPAWN_FA_COPY, .x = { .fd2 = { [0] = !(to & 1), [1] = to & 1 } } } - } ; - - pid = cspawn(prog, argv, envp, CSPAWN_FLAGS_SIGBLOCKNONE, fa, 2 + !!(to & 2)) ; - if (!pid) goto err ; - - fd_close(p[to & 1]) ; - return pid ; - - err: - fd_close(p[1]) ; - fd_close(p[0]) ; - return 0 ; -} diff --git a/src/libstddjb/child_spawn1_pipe.c b/src/libstddjb/child_spawn1_pipe.c deleted file mode 100644 index a31e091..0000000 --- a/src/libstddjb/child_spawn1_pipe.c +++ /dev/null @@ -1,17 +0,0 @@ -/* ISC license. */ - -#include <unistd.h> - -#include <skalibs/cspawn.h> -#include "cspawn-internal.h" - -pid_t child_spawn1_pipe (char const *prog, char const *const *argv, char const *const *envp, int *fd, int to) -{ - pid_t pid ; - int p[2] ; - if (pipe(p) < 0) return 0 ; - pid = child_spawn1_internal(prog, argv, envp, p, !!to) ; - if (!pid) return 0 ; - *fd = p[!to] ; - return pid ; -} diff --git a/src/libstddjb/child_spawn1_socket.c b/src/libstddjb/child_spawn1_socket.c deleted file mode 100644 index 684842e..0000000 --- a/src/libstddjb/child_spawn1_socket.c +++ /dev/null @@ -1,16 +0,0 @@ -/* ISC license. */ - -#include <skalibs/socket.h> -#include <skalibs/cspawn.h> -#include "cspawn-internal.h" - -pid_t child_spawn1_socket (char const *prog, char const *const *argv, char const *const *envp, int *fd) -{ - pid_t pid ; - int p[2] ; - if (ipc_pair_b(p) < 0) return 0 ; - pid = child_spawn1_internal(prog, argv, envp, p, 3) ; - if (!pid) return 0 ; - *fd = p[0] ; - return pid ; -} diff --git a/src/libstddjb/child_spawn2.c b/src/libstddjb/child_spawn2.c deleted file mode 100644 index f287c0b..0000000 --- a/src/libstddjb/child_spawn2.c +++ /dev/null @@ -1,39 +0,0 @@ -/* ISC license. */ - -#include <unistd.h> - -#include <skalibs/djbunix.h> -#include <skalibs/cspawn.h> - -pid_t child_spawn2 (char const *prog, char const *const *argv, char const *const *envp, int *fds) -{ - pid_t pid ; - int p[2][2] ; - if (pipe(p[0]) == -1) return 0 ; - if (ndelay_on(p[0][0]) == -1 || coe(p[0][0]) == -1 || pipe(p[1]) == -1) goto errp ; - if (ndelay_on(p[1][1]) == -1 || coe(p[1][1]) == -1) goto err ; - - { - cspawn_fileaction fa[2] = - { - [0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = fds[0], [1] = p[1][0] } } }, - [1] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = fds[1], [1] = p[0][1] } } } - } ; - pid = cspawn(prog, argv, envp, CSPAWN_FLAGS_SIGBLOCKNONE, fa, 2) ; - if (!pid) goto err ; - } - - fd_close(p[0][1]) ; - fd_close(p[1][0]) ; - fds[0] = p[0][0] ; - fds[1] = p[1][1] ; - return pid ; - - err: - fd_close(p[1][1]) ; - fd_close(p[1][0]) ; - errp: - fd_close(p[0][1]) ; - fd_close(p[0][0]) ; - return 0 ; -} diff --git a/src/libstddjb/child_spawn3.c b/src/libstddjb/child_spawn3.c deleted file mode 100644 index 75551d2..0000000 --- a/src/libstddjb/child_spawn3.c +++ /dev/null @@ -1,55 +0,0 @@ -/* ISC license. */ - -#include <unistd.h> - -#include <skalibs/types.h> -#include <skalibs/env.h> -#include <skalibs/djbunix.h> -#include <skalibs/cspawn.h> - -pid_t child_spawn3 (char const *prog, char const *const *argv, char const *const *envp, int *fds) -{ - pid_t pid ; - int p[3][2] ; - - if (pipe(p[0]) == -1) return 0 ; - if (ndelay_on(p[0][0]) == -1 || coe(p[0][0]) == -1 || pipe(p[1]) == -1) goto errp0 ; - if (ndelay_on(p[1][1]) == -1 || coe(p[1][1]) == -1 || pipe(p[2]) == -1) goto errp1 ; - if (ndelay_on(p[2][0]) == -1 || coe(p[2][0]) == -1) goto err ; - - { - cspawn_fileaction fa[2] = - { - [0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = fds[0], [1] = p[1][0] } } }, - [1] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = fds[1], [1] = p[0][1] } } } - } ; - size_t envlen = env_len(envp) ; - size_t m = sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR) ; - char modifs[sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR) + UINT_FMT] = SKALIBS_CHILD_SPAWN_FDS_ENVVAR "=" ; - char const *newenv[envlen + 2] ; - m += uint_fmt(modifs + sizeof(SKALIBS_CHILD_SPAWN_FDS_ENVVAR), p[2][1]) ; - modifs[m++] = 0 ; - env_mergen(newenv, envlen + 2, envp, envlen, modifs, m, 1) ; - pid = cspawn(prog, argv, newenv, CSPAWN_FLAGS_SIGBLOCKNONE, fa, 2) ; - if (!pid) goto err ; - } - - fd_close(p[2][1]) ; - fd_close(p[1][0]) ; - fd_close(p[0][1]) ; - fds[0] = p[0][0] ; - fds[1] = p[1][1] ; - fds[2] = p[2][0] ; - return pid ; - - err: - fd_close(p[2][1]) ; - fd_close(p[2][0]) ; - errp1: - fd_close(p[1][1]) ; - fd_close(p[1][0]) ; - errp0: - fd_close(p[0][1]) ; - fd_close(p[0][0]) ; - return 0 ; -} diff --git a/src/libstddjb/cspawn-internal.h b/src/libstddjb/cspawn-internal.h deleted file mode 100644 index 0e5efc7..0000000 --- a/src/libstddjb/cspawn-internal.h +++ /dev/null @@ -1,10 +0,0 @@ -/* ISC license. */ - -#ifndef CSPAWN_INTERNAL_H -#define CSPAWN_INTERNAL_H - -#include <sys/types.h> - -extern pid_t child_spawn1_internal (char const *, char const *const *, char const *const *, int *, int) ; - -#endif diff --git a/src/libstddjb/cspawn.c b/src/libstddjb/cspawn.c deleted file mode 100644 index 683a0a3..0000000 --- a/src/libstddjb/cspawn.c +++ /dev/null @@ -1,297 +0,0 @@ -/* ISC license. */ - -#include <skalibs/sysdeps.h> - -#ifdef SKALIBS_HASPOSIXSPAWN -#include <skalibs/nonposix.h> -#endif - -#include <errno.h> -#include <unistd.h> - -#include <skalibs/allreadwrite.h> -#include <skalibs/sig.h> -#include <skalibs/djbunix.h> -#include <skalibs/selfpipe.h> -#include <skalibs/exec.h> -#include <skalibs/cspawn.h> - -static inline void cspawn_child_exec (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n) -{ - for (size_t i = 0 ; i < n ; i++) - { - switch (fa[i].type) - { - case CSPAWN_FA_CLOSE : fd_close(fa[i].x.fd) ; break ; - case CSPAWN_FA_COPY : - if (fd_copy(fa[i].x.fd2[0], fa[i].x.fd2[1]) == -1) return ; - break ; - case CSPAWN_FA_MOVE : - if (fd_move(fa[i].x.fd2[0], fa[i].x.fd2[1]) == -1) return ; - if (fa[i].x.fd2[0] == fa[i].x.fd2[1] && uncoe(fa[i].x.fd2[0]) == -1) return ; - break ; - case CSPAWN_FA_OPEN : - { - int fd = open3(fa[i].x.openinfo.file, fa[i].x.openinfo.oflag, fa[i].x.openinfo.mode) ; - if (fd == -1) return ; - if (fd_move(fa[i].x.openinfo.fd, fd) == -1) return ; - break ; - } - case CSPAWN_FA_CHDIR : - if (chdir(fa[i].x.path) == -1) return ; - break ; - case CSPAWN_FA_FCHDIR : - if (fchdir(fa[i].x.fd) == -1) return ; - break ; - default : - errno = EINVAL ; return ; - } - } - - if (flags & CSPAWN_FLAGS_SELFPIPE_FINISH) selfpipe_finish() ; - if (flags & CSPAWN_FLAGS_SIGBLOCKNONE) sig_blocknone() ; - if (flags & CSPAWN_FLAGS_SETSID) setsid() ; - - exec_ae(prog, argv, envp) ; -} - -static inline pid_t cspawn_fork (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n) -{ - pid_t pid ; - int p[2] ; - char c ; - - if (pipecoe(p) == -1) return 0 ; - pid = fork() ; - if (pid == -1) - { - fd_close(p[1]) ; - fd_close(p[0]) ; - return 0 ; - } - if (!pid) - { - cspawn_child_exec(prog, argv, envp, flags, fa, n) ; - c = errno ; - fd_write(p[1], &c, 1) ; - _exit(127) ; - } - - fd_close(p[1]) ; - p[1] = fd_read(p[0], &c, 1) ; - if (p[1] < 0) - { - fd_close(p[0]) ; - return 0 ; - } - fd_close(p[0]) ; - if (p[1]) - { - wait_pid(pid, &p[0]) ; - errno = (unsigned char)c ; - return 0 ; - } - return pid ; -} - - /* - guess who has a buggy posix_spawn() *and* doesn't have waitid() to work around it? - if you guessed OpenBSD, you're right! - */ - -#if defined(SKALIBS_HASPOSIXSPAWN) && (!defined(SKALIBS_HASPOSIXSPAWNEARLYRETURN) || defined(SKALIBS_HASWAITID)) - -#include <signal.h> -#include <stdlib.h> -#include <spawn.h> - -#include <skalibs/config.h> -#include <skalibs/djbunix.h> - -#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN - -#include <sys/wait.h> - -static inline pid_t cspawn_workaround (pid_t pid, int const *p) -{ - siginfo_t si ; - int e ; - ssize_t r ; - char c ; - - fd_close(p[1]) ; - r = fd_read(p[0], &c, 1) ; - fd_close(p[0]) ; - if (r == -1) return 0 ; - if (r) return (errno = EILSEQ, 0) ; /* child wrote, wtf */ - - do e = waitid(P_PID, pid, &si, WEXITED | WNOHANG | WNOWAIT) ; - while (e == -1 && errno == EINTR) ; - if (e == -1) return pid ; /* we're in trouble, but don't leak a child */ - if (!si.si_pid) return pid ; /* child is running */ - if (si.si_code != CLD_EXITED || si.si_status != 127) return pid ; /* child died after execve(), let caller handle it */ - /* - child exited 127, so either execve() failed, which is what we want to catch, - or it raced like a mofo, execve()d and then exited 127 on its own, in which - case, tough luck, it never existed. - */ - wait_pid(pid, 0) ; - return (errno = 0, 0) ; -} - -#endif - -static inline pid_t cspawn_pspawn (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n) -{ - pid_t pid ; - posix_spawnattr_t attr ; - posix_spawn_file_actions_t actions ; - int e ; - int nopath = !getenv("PATH") ; -#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN - int p[2] ; - if (pipecoe(p) == -1) return 0 ; -#endif - - if (flags) - { - short pfff = 0 ; - e = posix_spawnattr_init(&attr) ; - if (e) goto err ; - if (flags & (CSPAWN_FLAGS_SIGBLOCKNONE | CSPAWN_FLAGS_SELFPIPE_FINISH)) - { - sigset_t set ; - sigemptyset(&set) ; - e = posix_spawnattr_setsigmask(&attr, &set) ; - if (e) goto errattr ; - pfff |= POSIX_SPAWN_SETSIGMASK ; - } -#ifdef SKALIBS_HASPOSIXSPAWNSETSID - if (flags & CSPAWN_FLAGS_SETSID) pfff |= POSIX_SPAWN_SETSID ; -#else -#ifdef SKALIBS_HASPOSIXSPAWNSETSIDNP - if (flags & CSPAWN_FLAGS_SETSID) pfff |= POSIX_SPAWN_SETSID_NP ; -#endif -#endif - e = posix_spawnattr_setflags(&attr, pfff) ; - if (e) goto errattr ; - } - - if (n) - { - e = posix_spawn_file_actions_init(&actions) ; - if (e) goto errattr ; - for (size_t i = 0 ; i < n ; i++) - { - switch (fa[i].type) - { - case CSPAWN_FA_CLOSE : - e = posix_spawn_file_actions_addclose(&actions, fa[i].x.fd) ; - if (e) goto erractions ; - break ; - case CSPAWN_FA_COPY : - e = posix_spawn_file_actions_adddup2(&actions, fa[i].x.fd2[1], fa[i].x.fd2[0]) ; - if (e) goto erractions ; - break ; - case CSPAWN_FA_MOVE : - e = posix_spawn_file_actions_adddup2(&actions, fa[i].x.fd2[1], fa[i].x.fd2[0]) ; - if (e) goto erractions ; - if (fa[i].x.fd2[0] != fa[i].x.fd2[1]) - { - e = posix_spawn_file_actions_addclose(&actions, fa[i].x.fd2[1]) ; - if (e) goto erractions ; - } - break ; - case CSPAWN_FA_OPEN : - e = posix_spawn_file_actions_addopen(&actions, fa[i].x.openinfo.fd, fa[i].x.openinfo.file, fa[i].x.openinfo.oflag, fa[i].x.openinfo.mode) ; - if (e) goto erractions ; - break ; -#ifdef SKALIBS_HASPOSIXSPAWNCHDIR - case CSPAWN_FA_CHDIR : - e = posix_spawn_file_actions_addchdir(&actions, fa[i].x.path) ; - if (e) goto erractions ; - break ; - case CSPAWN_FA_FCHDIR : - e = posix_spawn_file_actions_addfchdir(&actions, fa[i].x.fd) ; - if (e) goto erractions ; - break ; -#else -#ifdef SKALIBS_HASPOSIXSPAWNCHDIRNP - case CSPAWN_FA_CHDIR : - e = posix_spawn_file_actions_addchdir_np(&actions, fa[i].x.path) ; - if (e) goto erractions ; - break ; - case CSPAWN_FA_FCHDIR : - e = posix_spawn_file_actions_addfchdir_np(&actions, fa[i].x.fd) ; - if (e) goto erractions ; - break ; -#endif -#endif - default : - e = EINVAL ; - goto erractions ; - } - } - } - - if (nopath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) == -1)) { e = errno ; goto erractions ; } - e = posix_spawnp(&pid, prog, n ? &actions : 0, flags ? &attr : 0, (char *const *)argv, (char *const *)envp) ; - if (nopath) unsetenv("PATH") ; - if (e) goto erractions ; - - if (n) posix_spawn_file_actions_destroy(&actions) ; - if (flags) posix_spawnattr_destroy(&attr) ; -#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN - return cspawn_workaround(pid, p) ; -#else - return pid ; -#endif - - erractions: - if (n) posix_spawn_file_actions_destroy(&actions) ; - errattr: - if (flags) posix_spawnattr_destroy(&attr) ; - err: -#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN - fd_close(p[1]) ; - fd_close(p[0]) ; -#endif - errno = e ; - return 0 ; -} - -#if (defined(SKALIBS_HASPOSIXSPAWNSETSID) || defined(SKALIBS_HASPOSIXSPAWNSETSIDNP)) && (defined(SKALIBS_HASPOSIXSPAWNCHDIR) || defined(SKALIBS_HASPOSIXSPAWNCHDIRNP)) - -pid_t cspawn (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n) -{ - return cspawn_pspawn(prog, argv, envp, flags, fa, n) ; -} - -#else - -pid_t cspawn (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n) -{ -#if !defined(SKALIBS_HASPOSIXSPAWNSETSID) && !defined(SKALIBS_HASPOSIXSPAWNSETSIDNP) - if (flags & CSPAWN_FLAGS_SETSID) goto dofork ; -#endif -#if !defined(SKALIBS_HASPOSIXSPAWNCHDIR) && !defined(SKALIBS_HASPOSIXSPAWNCHDIRNP) - for (size_t i = 0 ; i < n ; i++) - if (fa[i].type == CSPAWN_FA_CHDIR || fa[i].type == CSPAWN_FA_FCHDIR) - goto dofork ; -#endif - return cspawn_pspawn(prog, argv, envp, flags, fa, n) ; - - dofork: - return cspawn_fork(prog, argv, envp, flags, fa, n) ; -} - -#endif - -#else - -pid_t cspawn (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n) -{ - return cspawn_fork(prog, argv, envp, flags, fa, n) ; -} - -#endif diff --git a/src/libstddjb/gcspawn.c b/src/libstddjb/gcspawn.c deleted file mode 100644 index 7e9e602..0000000 --- a/src/libstddjb/gcspawn.c +++ /dev/null @@ -1,48 +0,0 @@ -/* ISC license. */ - -#include <sys/wait.h> -#include <unistd.h> -#include <errno.h> - -#include <skalibs/types.h> -#include <skalibs/allreadwrite.h> -#include <skalibs/djbunix.h> -#include <skalibs/cspawn.h> - -pid_t gcspawn (char const *prog, char const *const *argv, char const *const *envp, uint16_t flags, cspawn_fileaction const *fa, size_t n) -{ - pid_t pid = 0 ; - int wstat ; - int p[2] ; - char pack[PID_PACK] ; - if (pipecoe(p) == -1) return 0 ; - pid = fork() ; - switch (pid) - { - case -1: - { - fd_close(p[1]) ; - fd_close(p[0]) ; - return 0 ; - } - case 0: - { - fd_close(p[0]) ; - pid = cspawn(prog, argv, envp, flags, fa, n) ; - if (!pid) _exit(errno) ; - pid_pack_big(pack, pid) ; - _exit(fd_write(p[1], pack, PID_PACK) < PID_PACK ? errno : 0) ; - } - } - fd_close(p[1]) ; - if (fd_read(p[0], pack, PID_PACK) < PID_PACK) goto err ; - fd_close(p[0]) ; - wait_pid(pid, &wstat) ; - pid_unpack_big(pack, &pid) ; - return pid ; - - err: - fd_close(p[0]) ; - wait_pid(pid, &wstat) ; - return (errno = WIFSIGNALED(wstat) ? EINTR : WEXITSTATUS(wstat), 0) ; -} |