|
|
|
@ -1,7 +1,9 @@
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <asm/unistd.h>
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
#include <linux/sched.h>
|
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
|
|
// release the memory and fd, but don't join the thread (since we might be
|
|
|
|
@ -90,12 +92,24 @@ int ncfdplane_destroy(ncfdplane* n){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static pid_t
|
|
|
|
|
launch_pipe_process(int* pipe){
|
|
|
|
|
launch_pipe_process(int* pipe, int* pidfd){
|
|
|
|
|
int pipes[2];
|
|
|
|
|
if(pipe2(pipes, O_CLOEXEC)){
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
pid_t p = fork();
|
|
|
|
|
struct clone_args clargs = {
|
|
|
|
|
.flags = CLONE_CLEAR_SIGHAND | CLONE_FS | CLONE_PIDFD,
|
|
|
|
|
.pidfd = (uintptr_t)pidfd,
|
|
|
|
|
.child_tid = 0, // FIXME
|
|
|
|
|
.parent_tid = 0, // FIXME
|
|
|
|
|
.exit_signal = SIGCHLD, // FIXME maybe switch it up for doctest?
|
|
|
|
|
.stack = 0, // automatically created by clone3()
|
|
|
|
|
.stack_size = 0, // automatically set by clone3()
|
|
|
|
|
.tls = 0, // FIXME
|
|
|
|
|
.set_tid = 0, // FIXME
|
|
|
|
|
.set_tid_size = 0, // FIXME
|
|
|
|
|
};
|
|
|
|
|
pid_t p = syscall(__NR_clone3, &clargs, sizeof(clargs));
|
|
|
|
|
if(p == 0){
|
|
|
|
|
if(dup2(pipes[1], STDOUT_FILENO) < 0 || dup2(pipes[1], STDERR_FILENO) < 0){
|
|
|
|
|
return -1;
|
|
|
|
@ -143,7 +157,6 @@ ncsubproc_thread(void* vncsp){
|
|
|
|
|
static ncfdplane*
|
|
|
|
|
ncsubproc_launch(ncplane* n, ncsubproc* ret, const ncsubproc_options* opts, int fd,
|
|
|
|
|
ncfdplane_callback cbfxn, ncfdplane_done_cb donecbfxn){
|
|
|
|
|
// FIXME need to pick up pidfd via clone() earlier in launch_pipe_process
|
|
|
|
|
ret->nfp = ncfdplane_create_internal(n, &opts->popts, fd, cbfxn, donecbfxn, false);
|
|
|
|
|
if(ret->nfp == NULL){
|
|
|
|
|
return NULL;
|
|
|
|
@ -166,7 +179,7 @@ ncsubproc* ncsubproc_createv(ncplane* n, const ncsubproc_options* opts,
|
|
|
|
|
if(ret == NULL){
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
ret->pid = launch_pipe_process(&fd);
|
|
|
|
|
ret->pid = launch_pipe_process(&fd, &ret->pidfd);
|
|
|
|
|
if(ret->pid == 0){
|
|
|
|
|
execv(bin, arg);
|
|
|
|
|
fprintf(stderr, "Error execv()ing %s\n", bin);
|
|
|
|
@ -194,7 +207,7 @@ ncsubproc* ncsubproc_createvp(ncplane* n, const ncsubproc_options* opts,
|
|
|
|
|
if(ret == NULL){
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
ret->pid = launch_pipe_process(&fd);
|
|
|
|
|
ret->pid = launch_pipe_process(&fd, &ret->pidfd);
|
|
|
|
|
if(ret->pid == 0){
|
|
|
|
|
execvp(bin, arg);
|
|
|
|
|
fprintf(stderr, "Error execv()ing %s\n", bin);
|
|
|
|
@ -222,7 +235,7 @@ ncsubproc* ncsubproc_createvpe(ncplane* n, const ncsubproc_options* opts,
|
|
|
|
|
if(ret == NULL){
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
ret->pid = launch_pipe_process(&fd);
|
|
|
|
|
ret->pid = launch_pipe_process(&fd, &ret->pidfd);
|
|
|
|
|
if(ret->pid == 0){
|
|
|
|
|
#ifdef __FreeBSD__
|
|
|
|
|
exect(bin, arg, env);
|
|
|
|
|