summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tls/deps-lib/s6tls1
-rw-r--r--src/tls/s6-tlsc.c38
-rw-r--r--src/tls/s6-tlsd.c38
-rw-r--r--src/tls/s6-ucspitlsc.c17
-rw-r--r--src/tls/s6-ucspitlsd.c10
-rw-r--r--src/tls/s6tls-internal.h7
-rw-r--r--src/tls/s6tls_io_spawn.c104
-rw-r--r--src/tls/s6tls_prep_tlscio.c10
-rw-r--r--src/tls/s6tls_prep_tlsdio.c10
-rw-r--r--src/tls/s6tls_sync_and_exec_app.c3
10 files changed, 153 insertions, 85 deletions
diff --git a/src/tls/deps-lib/s6tls b/src/tls/deps-lib/s6tls
index 07ad2f2..0ad4767 100644
--- a/src/tls/deps-lib/s6tls
+++ b/src/tls/deps-lib/s6tls
@@ -1,4 +1,5 @@
s6tls_clean_and_exec.o
+s6tls_io_spawn.o
s6tls_prep_tlscio.o
s6tls_prep_tlsdio.o
s6tls_sync_and_exec_app.o
diff --git a/src/tls/s6-tlsc.c b/src/tls/s6-tlsc.c
index 26703ba..dddb093 100644
--- a/src/tls/s6-tlsc.c
+++ b/src/tls/s6-tlsc.c
@@ -4,44 +4,27 @@
#include <unistd.h>
#include <fcntl.h>
-#include <skalibs/gccattributes.h>
#include <skalibs/types.h>
#include <skalibs/sgetopt.h>
#include <skalibs/strerr.h>
-#include <skalibs/env.h>
#include <skalibs/djbunix.h>
-#include <skalibs/exec.h>
#include "s6tls-internal.h"
#define USAGE "s6-tlsc [ -S | -s ] [ -Y | -y ] [ -v verbosity ] [ -K timeout ] [ -k servername ] [ -Z | -z ] [ -6 fdr ] [ -7 fdw ] prog..."
#define dieusage() strerr_dieusage(100, USAGE)
-static void child (int const [4][2], uint32_t, unsigned int, unsigned int, char const *) gccattr_noreturn ;
-static void child (int const p[4][2], uint32_t options, unsigned int verbosity, unsigned int kimeout, char const *servername)
-{
- char const *newargv[S6TLS_PREP_IO_ARGC] ;
- char buf[S6TLS_PREP_IO_BUFLEN] ;
- PROG = "s6-tlsc (child)" ;
- close(p[2][0]) ;
- close(p[0][1]) ;
- close(p[1][0]) ;
- if (fd_move(0, p[3][0]) == -1 || fd_move(1, p[3][1]) == -1)
- strerr_diefu1sys(111, "move network fds to stdin/stdout") ;
- s6tls_prep_tlscio(newargv, buf, p[0][0], p[1][1], p[2][1], options, verbosity, kimeout, servername) ;
- xexec(newargv) ;
-}
-
int main (int argc, char const *const *argv)
{
unsigned int verbosity = 1 ;
unsigned int kimeout = 0 ;
- int p[4][2] = { [3] = { 6, 7 } } ;
+ int p[4][2] = { [3] = { [0] = 6, [1] = 7 } } ;
uint32_t coptions = 0 ;
uint32_t poptions = 1 ;
pid_t pid ;
char const *servername = 0 ;
-
+ char const *newargv[S6TLS_PREP_IO_ARGC] ;
+ char buf[S6TLS_PREP_IO_BUFLEN] ;
PROG = "s6-tlsc" ;
{
subgetopt l = SUBGETOPT_ZERO ;
@@ -80,18 +63,15 @@ int main (int argc, char const *const *argv)
argc -= l.ind ; argv += l.ind ;
}
if (!argc) dieusage() ;
+
fd_sanitize() ;
- if (fcntl(p[3][0], F_GETFD) < 0 || fcntl(p[3][1], F_GETFD) < 0)
+ if (fcntl(p[3][0], F_GETFD) == -1 || fcntl(p[3][1], F_GETFD) == -1)
strerr_diefu1sys(111, "check network fds") ;
- if (pipe(p[0]) < 0 || pipe(p[1]) < 0 || pipe(p[2]) < 0)
+ if (pipe(p[0]) == -1 || pipe(p[1]) == -1 || pipe(p[2]) == -1)
strerr_diefu1sys(111, "pipe") ;
- pid = fork() ;
- switch (pid)
- {
- case -1 : strerr_diefu1sys(111, "fork") ;
- case 0 : child(p, coptions, verbosity, kimeout, servername) ;
- default : break ;
- }
+ s6tls_prep_tlscio(newargv, buf, p, coptions, verbosity, kimeout, servername) ;
+ pid = s6tls_io_spawn(newargv, p) ;
+ if (!pid) strerr_diefu2sys(111, "spawn ", newargv[0]) ;
s6tls_sync_and_exec_app(argv, p, pid, poptions) ;
}
diff --git a/src/tls/s6-tlsd.c b/src/tls/s6-tlsd.c
index c9ef5d2..07716ea 100644
--- a/src/tls/s6-tlsd.c
+++ b/src/tls/s6-tlsd.c
@@ -3,43 +3,27 @@
#include <stdint.h>
#include <unistd.h>
-#include <skalibs/gccattributes.h>
#include <skalibs/types.h>
#include <skalibs/sgetopt.h>
#include <skalibs/strerr.h>
-#include <skalibs/env.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/exec.h>
#include "s6tls-internal.h"
#define USAGE "s6-tlsd [ -S | -s ] [ -Y | -y ] [ -k snilevel ] [ -v verbosity ] [ -K timeout ] [ -Z | -z ] prog..."
#define dieusage() strerr_dieusage(100, USAGE)
-static void child (int const [4][2], uint32_t, unsigned int, unsigned int, unsigned int) gccattr_noreturn ;
-static void child (int const p[4][2], uint32_t options, unsigned int verbosity, unsigned int kimeout, unsigned int snilevel)
-{
- char const *newargv[S6TLS_PREP_IO_ARGC] ;
- char buf[S6TLS_PREP_IO_BUFLEN] ;
- PROG = "s6-tlsd (child)" ;
- close(p[2][0]) ;
- close(p[0][1]) ;
- close(p[1][0]) ;
- s6tls_prep_tlsdio(newargv, buf, p[0][0], p[1][1], p[2][1], options, verbosity, kimeout, snilevel) ;
- xexec(newargv) ;
-}
-
int main (int argc, char const *const *argv)
{
unsigned int verbosity = 1 ;
unsigned int kimeout = 0 ;
unsigned int snilevel = 0 ;
- int p[4][2] = { [3] = { 0, 1 } } ;
+ int p[4][2] = { [3] = { [0] = -1, [1] = -1 } } ;
uint32_t coptions = 0 ;
uint32_t poptions = 1 ;
pid_t pid ;
-
- PROG = "s6-tlsd (parent)" ;
+ char const *newargv[S6TLS_PREP_IO_ARGC] ;
+ char buf[S6TLS_PREP_IO_BUFLEN] ;
+ PROG = "s6-tlsd" ;
{
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
@@ -64,14 +48,10 @@ int main (int argc, char const *const *argv)
}
if (!argc) dieusage() ;
- if (pipe(p[0]) < 0 || pipe(p[1]) < 0 || pipe(p[2]) < 0)
- strerr_diefu1sys(111, "pipe") ;
- pid = fork() ;
- switch (pid)
- {
- case -1 : strerr_diefu1sys(111, "fork") ;
- case 0 : child(p, coptions, verbosity, kimeout, snilevel) ;
- default : break ;
- }
+ if (pipe(p[0]) == -1 || pipe(p[1]) == -1 || pipe(p[2]) == -1)
+ strerr_diefu1sys(111, "create pipe") ;
+ s6tls_prep_tlsdio(newargv, buf, p, coptions, verbosity, kimeout, snilevel) ;
+ pid = s6tls_io_spawn(newargv, p) ;
+ if (!pid) strerr_diefu2sys(111, "spawn ", newargv[0]) ;
s6tls_sync_and_exec_app(argv, p, pid, poptions) ;
}
diff --git a/src/tls/s6-ucspitlsc.c b/src/tls/s6-ucspitlsc.c
index 2d728b5..4f284b7 100644
--- a/src/tls/s6-ucspitlsc.c
+++ b/src/tls/s6-ucspitlsc.c
@@ -21,17 +21,16 @@
static inline void child (int [4][2], uint32_t, unsigned int, unsigned int, char const *, pid_t) gccattr_noreturn ;
static inline void child (int p[4][2], uint32_t options, unsigned int verbosity, unsigned int kimeout, char const *servername, pid_t pid)
{
+ ssize_t r ;
char const *newargv[S6TLS_PREP_IO_ARGC] ;
char buf[S6TLS_PREP_IO_BUFLEN] ;
- ssize_t r ;
char c ;
PROG = "s6-ucspitlsc" ;
close(p[2][0]) ;
- close(p[0][1]) ;
close(p[1][0]) ;
+ close(p[0][1]) ;
if (fd_move(0, p[3][0]) == -1 || fd_move(1, p[3][1]) == -1)
strerr_diefu1sys(111, "move network fds to stdin/stdout") ;
- s6tls_prep_tlscio(newargv, buf, p[0][0], p[1][1], p[2][1], options, verbosity, kimeout, servername) ;
r = read(p[2][1], &c, 1) ;
if (r < 0) strerr_diefu1sys(111, "read from control socket") ;
if (!r)
@@ -48,7 +47,7 @@ static inline void child (int p[4][2], uint32_t options, unsigned int verbosity,
{
case 'y' :
close(p[2][1]) ;
- p[2][1] = 0 ; /* we know 0 is open so it's a correct invalid value */
+ p[2][1] = 0 ; /* we know 0 is open so it's a suitable invalid value */
break ;
case 'Y' :
fd_shutdown(p[2][1], 0) ;
@@ -56,6 +55,7 @@ static inline void child (int p[4][2], uint32_t options, unsigned int verbosity,
default :
strerr_dief1x(100, "unrecognized command on control socket") ;
}
+ s6tls_prep_tlscio(newargv, buf, p, options, verbosity, kimeout, servername) ;
if (verbosity >= 2)
{
char fmt[PID_FMT] ;
@@ -69,7 +69,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
{
unsigned int verbosity = 1 ;
unsigned int kimeout = 0 ;
- int p[4][2] = { [3] = { 6, 7 } } ;
+ int p[4][2] = { [3] = { [0] = 6, [1] = 7 } } ;
uint32_t coptions = 0 ;
uint32_t poptions = 1 ;
char const *servername = 0 ;
@@ -114,12 +114,13 @@ int main (int argc, char const *const *argv, char const *const *envp)
}
if (!argc) dieusage() ;
fd_sanitize() ;
- if (fcntl(p[3][0], F_GETFD) < 0 || fcntl(p[3][1], F_GETFD) < 0)
+ if (fcntl(p[3][0], F_GETFD) == -1 || fcntl(p[3][1], F_GETFD) == -1)
strerr_diefu1sys(111, "check network fds") ;
- if (ipc_pair_b(p[2]) < 0) strerr_diefu1sys(111, "ipc_pair") ;
- if (pipe(p[0]) < 0 || pipe(p[1]) < 0) strerr_diefu1sys(111, "pipe") ;
+ if (ipc_pair_b(p[2]) == -1) strerr_diefu1sys(111, "ipc_pair") ;
+ if (pipe(p[0]) == -1 || pipe(p[1]) == -1) strerr_diefu1sys(111, "pipe") ;
pid = getpid() ;
+
switch (fork())
{
case -1 : strerr_diefu1sys(111, "fork") ;
diff --git a/src/tls/s6-ucspitlsd.c b/src/tls/s6-ucspitlsd.c
index ecce9d5..92450e3 100644
--- a/src/tls/s6-ucspitlsd.c
+++ b/src/tls/s6-ucspitlsd.c
@@ -20,15 +20,14 @@
static inline void child (int [4][2], uint32_t, unsigned int, unsigned int, unsigned int, pid_t) gccattr_noreturn ;
static inline void child (int p[4][2], uint32_t options, unsigned int verbosity, unsigned int kimeout, unsigned int snilevel, pid_t pid)
{
+ ssize_t r ;
char const *newargv[S6TLS_PREP_IO_ARGC] ;
char buf[S6TLS_PREP_IO_BUFLEN] ;
- ssize_t r ;
char c ;
PROG = "s6-ucspitlsd" ;
close(p[2][0]) ;
close(p[0][1]) ;
close(p[1][0]) ;
- s6tls_prep_tlsdio(newargv, buf, p[0][0], p[1][1], p[2][1], options, verbosity, kimeout, snilevel) ;
r = read(p[2][1], &c, 1) ;
if (r < 0) strerr_diefu1sys(111, "read from control socket") ;
if (!r)
@@ -53,6 +52,7 @@ static inline void child (int p[4][2], uint32_t options, unsigned int verbosity,
default :
strerr_dief1x(100, "unrecognized command on control socket") ;
}
+ s6tls_prep_tlsdio(newargv, buf, p, options, verbosity, kimeout, snilevel) ;
if (verbosity >= 2)
{
char fmt[PID_FMT] ;
@@ -67,7 +67,7 @@ int main (int argc, char const *const *argv)
unsigned int verbosity = 1 ;
unsigned int kimeout = 0 ;
unsigned int snilevel = 0 ;
- int p[4][2] = { [3] = { 0, 1 } } ;
+ int p[4][2] = { [3] = { [0] = -1, [1] = -1 } } ;
uint32_t coptions = 0 ;
uint32_t poptions = 1 ;
pid_t pid ;
@@ -97,8 +97,8 @@ int main (int argc, char const *const *argv)
}
if (!argc) dieusage() ;
- if (ipc_pair_b(p[2]) < 0) strerr_diefu1sys(111, "ipc_pair") ;
- if (pipe(p[0]) < 0 || pipe(p[1]) < 0) strerr_diefu1sys(111, "pipe") ;
+ if (ipc_pair_b(p[2]) == -1) strerr_diefu1sys(111, "ipc_pair") ;
+ if (pipe(p[0]) == -1 || pipe(p[1]) == -1) strerr_diefu1sys(111, "pipe") ;
pid = getpid() ;
switch (fork())
diff --git a/src/tls/s6tls-internal.h b/src/tls/s6tls-internal.h
index cd96e87..2870744 100644
--- a/src/tls/s6tls-internal.h
+++ b/src/tls/s6tls-internal.h
@@ -3,7 +3,7 @@
#ifndef S6TLS_INTERNAL_H
#define S6TLS_INTERNAL_H
-#include <stddef.h>
+#include <sys/types.h>
#include <stdint.h>
#include <skalibs/gccattributes.h>
@@ -12,8 +12,9 @@
#define S6TLS_PREP_IO_ARGC 15
#define S6TLS_PREP_IO_BUFLEN (5 * UINT_FMT)
-extern void s6tls_prep_tlscio (char const **, char *, int, int, int, uint32_t, unsigned int, unsigned int, char const *) ;
-extern void s6tls_prep_tlsdio (char const **, char *, int, int, int, uint32_t, unsigned int, unsigned int, unsigned int) ;
+extern pid_t s6tls_io_spawn (char const *const *argv, int const [4][2]) ;
+extern void s6tls_prep_tlscio (char const **, char *, int const [4][2], uint32_t, unsigned int, unsigned int, char const *) ;
+extern void s6tls_prep_tlsdio (char const **, char *, int const [4][2], uint32_t, unsigned int, unsigned int, unsigned int) ;
extern void s6tls_sync_and_exec_app (char const *const *, int const [4][2], pid_t, uint32_t) gccattr_noreturn ;
extern void s6tls_ucspi_exec_app (char const *const *, int const [4][2], uint32_t) gccattr_noreturn ;
extern void s6tls_clean_and_exec (char const *const *, uint32_t, char const *, size_t) gccattr_noreturn ;
diff --git a/src/tls/s6tls_io_spawn.c b/src/tls/s6tls_io_spawn.c
new file mode 100644
index 0000000..e2d589a
--- /dev/null
+++ b/src/tls/s6tls_io_spawn.c
@@ -0,0 +1,104 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+
+#include <skalibs/djbunix.h>
+
+#include "s6tls-internal.h"
+
+#ifdef SKALIBS_HASPOSIXSPAWN
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <spawn.h>
+
+#include <skalibs/config.h>
+#include <skalibs/posixplz.h>
+
+pid_t s6tls_io_spawn (char const *const *argv, int const p[4][2])
+{
+ pid_t pid ;
+ posix_spawn_file_actions_t actions ;
+ int e ;
+ int nopath = !getenv("PATH") ;
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+ int eep[2] ;
+ if (pipecoe(eep) == -1) return 0 ;
+#endif
+ e = posix_spawn_file_actions_init(&actions) ;
+ if (e) goto err ;
+ e = posix_spawn_file_actions_addclose(&actions, p[0][1]) ;
+ if (e) goto erractions ;
+ e = posix_spawn_file_actions_addclose(&actions, p[1][0]) ;
+ if (e) goto erractions ;
+ e = posix_spawn_file_actions_addclose(&actions, p[2][0]) ;
+ if (e) goto erractions ;
+ if (p[3][0] >= 0)
+ {
+ e = posix_spawn_file_actions_adddup2(&actions, p[3][0], 0) ;
+ if (e) goto erractions ;
+ e = posix_spawn_file_actions_addclose(&actions, p[3][0]) ;
+ if (e) goto erractions ;
+ }
+ if (p[3][1] >= 0)
+ {
+ e = posix_spawn_file_actions_adddup2(&actions, p[3][1], 1) ;
+ if (e) goto erractions ;
+ e = posix_spawn_file_actions_addclose(&actions, p[3][1]) ;
+ if (e) goto erractions ;
+ }
+
+ if (nopath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)) { e = errno ; goto erractions ; }
+ e = posix_spawnp(&pid, argv[0], &actions, 0, (char *const *)argv, environ) ;
+ if (nopath) unsetenv("PATH") ;
+ if (e) goto erractions ;
+
+ posix_spawn_file_actions_destroy(&actions) ;
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+ return child_spawn_workaround(pid, eep) ;
+#else
+ return pid ;
+#endif
+
+ erractions:
+ posix_spawn_file_actions_destroy(&actions) ;
+ err:
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+ fd_close(eep[1]) ;
+ fd_close(eep[0]) ;
+#endif
+ errno = e ;
+ return 0 ;
+}
+
+#else
+
+#include <string.h>
+
+#include <skalibs/strerr.h>
+#include <skalibs/exec.h>
+
+pid_t s6tls_io_spawn (char const *const *argv, int const p[4][2])
+{
+ pid_t pid = fork() ;
+ if (pid == -1) return 0 ;
+ if (!pid)
+ {
+ size_t proglen = strlen(PROG) ;
+ char newprog[proglen + 9] ;
+ memcpy(newprog, PROG, proglen) ;
+ memcpy(newprog, " (child)", 9) ;
+ PROG = newprog ;
+ fd_close(p[0][1]) ;
+ fd_close(p[1][0]) ;
+ fd_close(p[2][0]) ;
+ if ((p[3][0] >= 0 && fd_move(0, p[3][0]) == -1)
+ || (p[3][1] >= 0 && fd_move(1, p[3][1]) == -1))
+ strerr_diefu1sys(111, "move network fds to stdin/stdout") ;
+ xexec(argv) ;
+ }
+ return pid ;
+}
+
+#endif
diff --git a/src/tls/s6tls_prep_tlscio.c b/src/tls/s6tls_prep_tlscio.c
index cf44511..1d25f65 100644
--- a/src/tls/s6tls_prep_tlscio.c
+++ b/src/tls/s6tls_prep_tlscio.c
@@ -5,7 +5,7 @@
#include <s6-networking/config.h>
#include "s6tls-internal.h"
-void s6tls_prep_tlscio (char const **argv, char *buf, int fdr, int fdw, int fdnotif, uint32_t options, unsigned int verbosity, unsigned int kimeout, char const *servername)
+void s6tls_prep_tlscio (char const **argv, char *buf, int const p[4][2], uint32_t options, unsigned int verbosity, unsigned int kimeout, char const *servername)
{
size_t m = 0 ;
size_t n = 0 ;
@@ -18,11 +18,11 @@ void s6tls_prep_tlscio (char const **argv, char *buf, int fdr, int fdw, int fdno
n += uint_fmt(buf + n, verbosity) ;
buf[n++] = 0 ;
}
- if (fdnotif)
+ if (p[2][1])
{
argv[m++] = "-d" ;
argv[m++] = buf + n ;
- n += uint_fmt(buf + n, fdnotif) ;
+ n += uint_fmt(buf + n, p[2][1]) ;
buf[n++] = 0 ;
}
argv[m++] = options & 4 ? "-S" : "-s" ;
@@ -41,10 +41,10 @@ void s6tls_prep_tlscio (char const **argv, char *buf, int fdr, int fdw, int fdno
}
argv[m++] = "--" ;
argv[m++] = buf + n ;
- n += uint_fmt(buf + n, fdr) ;
+ n += uint_fmt(buf + n, p[0][0]) ;
buf[n++] = 0 ;
argv[m++] = buf + n ;
- n += uint_fmt(buf + n, fdw) ;
+ n += uint_fmt(buf + n, p[1][1]) ;
buf[n++] = 0 ;
argv[m++] = 0 ;
}
diff --git a/src/tls/s6tls_prep_tlsdio.c b/src/tls/s6tls_prep_tlsdio.c
index 942425b..947cf70 100644
--- a/src/tls/s6tls_prep_tlsdio.c
+++ b/src/tls/s6tls_prep_tlsdio.c
@@ -5,7 +5,7 @@
#include <s6-networking/config.h>
#include "s6tls-internal.h"
-void s6tls_prep_tlsdio (char const **argv, char *buf, int fdr, int fdw, int fdnotif, uint32_t options, unsigned int verbosity, unsigned int kimeout, unsigned int snilevel)
+void s6tls_prep_tlsdio (char const **argv, char *buf, int const p[4][2], uint32_t options, unsigned int verbosity, unsigned int kimeout, unsigned int snilevel)
{
size_t m = 0 ;
size_t n = 0 ;
@@ -18,11 +18,11 @@ void s6tls_prep_tlsdio (char const **argv, char *buf, int fdr, int fdw, int fdno
n += uint_fmt(buf + n, verbosity) ;
buf[n++] = 0 ;
}
- if (fdnotif)
+ if (p[2][1])
{
argv[m++] = "-d" ;
argv[m++] = buf + n ;
- n += uint_fmt(buf + n, fdnotif) ;
+ n += uint_fmt(buf + n, p[2][1]) ;
buf[n++] = 0 ;
}
argv[m++] = options & 4 ? "-S" : "-s" ;
@@ -44,10 +44,10 @@ void s6tls_prep_tlsdio (char const **argv, char *buf, int fdr, int fdw, int fdno
}
argv[m++] = "--" ;
argv[m++] = buf + n ;
- n += uint_fmt(buf + n, fdr) ;
+ n += uint_fmt(buf + n, p[0][0]) ;
buf[n++] = 0 ;
argv[m++] = buf + n ;
- n += uint_fmt(buf + n, fdw) ;
+ n += uint_fmt(buf + n, p[1][1]) ;
buf[n++] = 0 ;
argv[m++] = 0 ;
}
diff --git a/src/tls/s6tls_sync_and_exec_app.c b/src/tls/s6tls_sync_and_exec_app.c
index dc16e9d..3fdd21c 100644
--- a/src/tls/s6tls_sync_and_exec_app.c
+++ b/src/tls/s6tls_sync_and_exec_app.c
@@ -16,7 +16,8 @@ void s6tls_sync_and_exec_app (char const *const *argv, int const p[4][2], pid_t
close(p[2][1]) ;
close(p[1][1]) ;
close(p[0][0]) ;
- if (fd_move(p[3][0], p[1][0]) < 0 || fd_move(p[3][1], p[0][1]) < 0)
+ if ((p[3][0] >= 0 && fd_move(p[3][0], p[1][0]) == -1)
+ || (p[3][1] >= 0 && fd_move(p[3][1], p[0][1]) == -1))
strerr_diefu1sys(111, "move file descriptors") ;
r = read(p[2][0], buf, MAXENVSIZE) ;
if (r < 0) strerr_diefu1sys(111, "read from handshake notification pipe") ;