ncsubproc: decay to fork()/kill() on fbsd #574

pull/592/head
nick black 4 years ago committed by Nick Black
parent 7cb1558d21
commit d339b118f1

@ -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…
Cancel
Save