summaryrefslogtreecommitdiff
path: root/src/sbearssl/sbearssl_prep_spawn_drop.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-03-22 21:37:30 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-03-22 21:37:30 +0000
commitdddbfab568d42e443f102d35c84432824cc59fee (patch)
tree4983b1f5b44f861a3abc60ba7d47476820fcbb2f /src/sbearssl/sbearssl_prep_spawn_drop.c
parent6278e21405c40df65f8de6a9799576d1eb346164 (diff)
downloads6-networking-dddbfab568d42e443f102d35c84432824cc59fee.tar.xz
Fix case where s6-tls[cd] would sometimes not detect an application and remain there forever with its zombie, both condemned to err in limbo for all eternity, the living and the dead, hand in hand
Diffstat (limited to 'src/sbearssl/sbearssl_prep_spawn_drop.c')
-rw-r--r--src/sbearssl/sbearssl_prep_spawn_drop.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/sbearssl/sbearssl_prep_spawn_drop.c b/src/sbearssl/sbearssl_prep_spawn_drop.c
new file mode 100644
index 0000000..1ca7eb8
--- /dev/null
+++ b/src/sbearssl/sbearssl_prep_spawn_drop.c
@@ -0,0 +1,35 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <signal.h>
+#include <skalibs/env.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/selfpipe.h>
+#include "sbearssl-internal.h"
+
+pid_t sbearssl_prep_spawn_drop (char const *const *argv, char const *const *envp, int *fds, uid_t uid, gid_t gid, uint32_t options)
+{
+ pid_t pid ;
+
+ fds[4] = selfpipe_init() ;
+ if (fds[4] < 0) strerr_diefu1sys(111, "init selfpipe") ;
+ if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "trap SIGCHLD") ;
+
+ if (!(options & 1)) pid = child_spawn2(argv[0], argv, envp, fds) ;
+ else
+ {
+ char const modifs[] = "CADIR\0CAFILE\0KEYFILE\0CERTFILE\0TLS_UID\0TLS_GID" ;
+ size_t modiflen = sizeof(modifs) ;
+ size_t n = env_len(envp) ;
+ char const *newenv[n + 7] ;
+ size_t newenvlen = env_merge(newenv, n+7, envp, n, modifs, modiflen) ;
+ if (!newenvlen) return 0 ;
+ pid = child_spawn2(argv[0], argv, newenv, fds) ;
+ }
+
+ if (!pid) strerr_diefu2sys(111, "spawn ", argv[0]) ;
+ if (gid && setgid(gid) < 0) strerr_diefu1sys(111, "setgid") ;
+ if (uid && setuid(uid) < 0) strerr_diefu1sys(111, "setuid") ;
+ return pid ;
+}