s6_clone_newpid.patch (3003B)
1 diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c 2 index bda8e52..2c3fb2d 100644 3 --- a/src/supervision/s6-supervise.c 4 +++ b/src/supervision/s6-supervise.c 5 @@ -12,6 +12,9 @@ 6 #include <fcntl.h> 7 #include <sys/stat.h> 8 #include <sys/wait.h> 9 +#ifdef WANT_CLONE_NEWPID 10 +# include <sched.h> 11 +#endif 12 13 #include <skalibs/allreadwrite.h> 14 #include <skalibs/bytestr.h> 15 @@ -234,6 +237,64 @@ static void failcoe (int fd) 16 errno = e ; 17 } 18 19 + static void exec_run(int p[2], int notifyp[2], int fd) gccattr_noreturn ; 20 + static void exec_run(int p[2], int notifyp[2], int fd) 21 + { 22 + char const *cargv[2] = { "run", 0 } ; 23 + PROG = "s6-supervise (child)" ; 24 + selfpipe_finish() ; 25 + sig_restore(SIGPIPE) ; 26 + if (notifyp[0] >= 0) close(notifyp[0]) ; 27 + close(p[0]) ; 28 + if (notifyp[1] >= 0 && fd_move(fd, notifyp[1]) < 0) 29 + { 30 + failcoe(p[1]) ; 31 + strerr_diefu1sys(127, "move notification descriptor") ; 32 + } 33 + setsid() ; 34 + execv("./run", (char *const *)cargv) ; 35 + failcoe(p[1]) ; 36 + strerr_dieexec(127, "run") ; 37 +} 38 + 39 +static pid_t spawn_run_fork(int p[2], int notifyp[2], int fd) 40 +{ 41 + pid_t pid = fork() ; 42 + if (!pid) exec_run(p, notifyp, fd) ; 43 + return pid ; 44 +} 45 + 46 +#ifdef WANT_CLONE_NEWPID 47 +typedef struct 48 +{ 49 + int p[2] ; 50 + int notifyp[2] ; 51 + int fd ; 52 +} exec_run_t ; 53 + 54 +static int exec_run_shim(void *ctx) gccattr_noreturn ; 55 +static int exec_run_shim(void *ctx) 56 +{ 57 + exec_run_t *er = (exec_run_t *) ctx ; 58 + exec_run(er->p, er->notifyp, er->fd) ; 59 +} 60 + 61 +static pid_t spawn_run(int p[2], int notifyp[2], int fd) 62 +{ 63 + exec_run_t arg = { { p[0], p[1] }, { notifyp[0], notifyp[1] }, fd } ; 64 + char child_stack[SIGSTKSZ] ; 65 + if (access("clone-newpid", F_OK) < 0 && errno == ENOENT) 66 + return spawn_run_fork(p, notifyp, fd) ; 67 + return (pid_t) clone(&exec_run_shim, child_stack + sizeof(child_stack), 68 + CLONE_NEWPID | SIGCHLD, &arg) ; 69 +} 70 +#else /* if !defined(WANT_CLONE_NEWPID) */ 71 +static pid_t spawn_run(int p[2], int notifyp[2], int fd) 72 +{ 73 + return spawn_run_fork(p, notifyp, fd) ; 74 +} 75 +#endif /* defined(WANT_CLONE_NEWPID) */ 76 + 77 static void trystart (void) 78 { 79 int p[2] ; 80 @@ -253,7 +314,7 @@ static void trystart (void) 81 fd_close(p[1]) ; fd_close(p[0]) ; 82 return ; 83 } 84 - pid = fork() ; 85 + pid = spawn_run(p, notifyp, (int)fd) ; 86 if (pid < 0) 87 { 88 settimeout(60) ; 89 @@ -263,24 +324,6 @@ static void trystart (void) 90 fd_close(p[1]) ; fd_close(p[0]) ; 91 return ; 92 } 93 - else if (!pid) 94 - { 95 - char const *cargv[2] = { "run", 0 } ; 96 - PROG = "s6-supervise (child)" ; 97 - selfpipe_finish() ; 98 - sig_restore(SIGPIPE) ; 99 - if (notifyp[0] >= 0) close(notifyp[0]) ; 100 - close(p[0]) ; 101 - if (notifyp[1] >= 0 && fd_move((int)fd, notifyp[1]) < 0) 102 - { 103 - failcoe(p[1]) ; 104 - strerr_diefu1sys(127, "move notification descriptor") ; 105 - } 106 - setsid() ; 107 - execv("./run", (char *const *)cargv) ; 108 - failcoe(p[1]) ; 109 - strerr_dieexec(127, "run") ; 110 - } 111 if (notifyp[1] >= 0) fd_close(notifyp[1]) ; 112 fd_close(p[1]) ; 113 {