diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/deps-lib/s6tls | 1 | ||||
-rw-r--r-- | src/tls/s6-tlsc.c | 38 | ||||
-rw-r--r-- | src/tls/s6-tlsd.c | 38 | ||||
-rw-r--r-- | src/tls/s6-ucspitlsc.c | 17 | ||||
-rw-r--r-- | src/tls/s6-ucspitlsd.c | 10 | ||||
-rw-r--r-- | src/tls/s6tls-internal.h | 7 | ||||
-rw-r--r-- | src/tls/s6tls_io_spawn.c | 104 | ||||
-rw-r--r-- | src/tls/s6tls_prep_tlscio.c | 10 | ||||
-rw-r--r-- | src/tls/s6tls_prep_tlsdio.c | 10 | ||||
-rw-r--r-- | src/tls/s6tls_sync_and_exec_app.c | 3 |
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") ; |