subproc: on older linux, fall back to fork()

This commit is contained in:
nick black 2020-05-24 03:55:46 -04:00
parent 8971bda0c2
commit e097723a63
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

View File

@ -150,6 +150,9 @@ launch_pipe_process(int* pipe, int* pidfd){
if(pipe2(pipes, O_CLOEXEC)){ // can't use O_NBLOCK here (affects client)
return -1;
}
pid_t p = -1;
// on linux, we try to use the brand-new pidfd capability via clone3(). if
// that fails, fall through to fork(), which is all we try to use on freebsd.
#ifdef __linux__
// FIXME introduced in linux 5.5
#ifndef CLONE_CLEAR_SIGHAND
@ -159,11 +162,12 @@ launch_pipe_process(int* pipe, int* pidfd){
memset(&clargs, 0, sizeof(clargs));
clargs.pidfd = (uintptr_t)pidfd;
clargs.flags = CLONE_CLEAR_SIGHAND | CLONE_FS | CLONE_PIDFD;
pid_t p = syscall(__NR_clone3, &clargs, sizeof(clargs));
p = syscall(__NR_clone3, &clargs, sizeof(clargs));
#else
(void)pidfd;
pid_t p = fork();
#endif
if(p < 0){
p = fork();
}
if(p == 0){ // child
if(dup2(pipes[1], STDOUT_FILENO) < 0 || dup2(pipes[1], STDERR_FILENO) < 0){
fprintf(stderr, "Couldn't dup() %d (%s)\n", pipes[1], strerror(errno));
@ -181,15 +185,20 @@ launch_pipe_process(int* pipe, int* pidfd){
// FIXME rigourize and port this
static int
kill_and_wait_subproc(pid_t pid, int pidfd, int* status){
int ret = -1;
// on linux, we try pidfd_send_signal, if the pidfd has been defined.
// otherwise, we fall back to regular old kill();
if(pidfd >= 0){
#ifdef __linux__
syscall(__NR_pidfd_send_signal, pidfd, SIGKILL, NULL, 0);
siginfo_t info;
memset(&info, 0, sizeof(info));
waitid(P_PIDFD, pidfd, &info, 0);
#else
(void)pidfd;
kill(pid, SIGKILL);
ret = syscall(__NR_pidfd_send_signal, pidfd, SIGKILL, NULL, 0);
siginfo_t info;
memset(&info, 0, sizeof(info));
waitid(P_PIDFD, pidfd, &info, 0);
#endif
}
if(ret < 0){
kill(pid, SIGKILL);
}
// process ought be available immediately following waitid(), so supply
// WNOHANG to avoid possible lockups due to weirdness
if(pid != waitpid(pid, status, WNOHANG)){