mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
ncsubproc: decay to fork()/kill() on fbsd #574
This commit is contained in:
parent
7cb1558d21
commit
d339b118f1
25
src/lib/fd.c
25
src/lib/fd.c
@ -1,11 +1,13 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/wait.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <linux/sched.h>
|
||||
#endif
|
||||
#include "internal.h"
|
||||
|
||||
// release the memory and fd, but don't join the thread (since we might be
|
||||
@ -141,22 +143,25 @@ int ncfdplane_destroy(ncfdplane* n){
|
||||
// ncfdplane around the read end, involving creation of a new thread. the
|
||||
// parent then returns.
|
||||
|
||||
// FIXME introduced in linux 5.5
|
||||
#ifndef CLONE_CLEAR_SIGHAND
|
||||
#define CLONE_CLEAR_SIGHAND 0x100000000ULL
|
||||
#endif
|
||||
|
||||
static pid_t
|
||||
launch_pipe_process(int* pipe, int* pidfd){
|
||||
int pipes[2];
|
||||
if(pipe2(pipes, O_CLOEXEC)){ // can't use O_NBLOCK here (affects client)
|
||||
return -1;
|
||||
}
|
||||
#ifdef __linux__
|
||||
// FIXME introduced in linux 5.5
|
||||
#ifndef CLONE_CLEAR_SIGHAND
|
||||
#define CLONE_CLEAR_SIGHAND 0x100000000ULL
|
||||
#endif
|
||||
struct clone_args clargs;
|
||||
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));
|
||||
#else
|
||||
pid_t p = fork();
|
||||
#endif
|
||||
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));
|
||||
@ -175,10 +180,14 @@ 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){
|
||||
#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
|
||||
kill(pid, SIGKILL);
|
||||
#endif
|
||||
// process ought be available immediately following waitid(), so supply
|
||||
// WNOHANG to avoid possible lockups due to weirdness
|
||||
if(pid != waitpid(pid, status, WNOHANG)){
|
||||
@ -317,7 +326,11 @@ int ncsubproc_destroy(ncsubproc* n){
|
||||
int ret = 0;
|
||||
if(n){
|
||||
void* vret = NULL;
|
||||
#ifdef __linux__
|
||||
syscall(__NR_pidfd_send_signal, n->pidfd, SIGKILL, NULL, 0);
|
||||
#else
|
||||
kill(n->pid, SIGKILL);
|
||||
#endif
|
||||
// the thread waits on the subprocess via pidfd, and then exits. don't try
|
||||
// to cancel the thread; rely on killing the subprocess.
|
||||
pthread_join(n->nfp->tid, &vret);
|
||||
|
Loading…
x
Reference in New Issue
Block a user