mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-18 03:25:55 +00:00
subproc: on older linux, fall back to fork()
This commit is contained in:
parent
8971bda0c2
commit
e097723a63
29
src/lib/fd.c
29
src/lib/fd.c
@ -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)){
|
||||
|
Loading…
Reference in New Issue
Block a user