/* This file is part of Ground Control.
Ground Control is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
Ground Control is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
Ground Control. If not, see . */
#include
#include
#include
#include
#include
#include
#include
#include "wren.h"
#include "scheduler.h"
#include "fd.h"
#include "process.h"
int close_range(unsigned int first, unsigned int last, unsigned int flags);
int execvpe(const char *file, char *const argv[], char *const envp[]);
#ifndef __GLIBC__
inline int
close_range(unsigned int first, unsigned int last, unsigned int flags) {
return syscall(SYS_close_range, first, last, flags);
}
#endif
void process_start(WrenVM* vm) {
/* fname */
const char* fname = wrenGetSlotString(vm, 1);
/* argv */
int argc = wrenGetListCount(vm, 2);
const char** argv = alloca(sizeof(*argv) * (argc+1));
for (int i=0; i= 0);
if (pid != 0) {
wrenSetSlotDouble(vm, 0, pid);
return;
}
/* reset signal handlers */
for (int i=1; i < NSIG; i++) {
if (i != SIGKILL && i != SIGSTOP)
signal(i, SIG_DFL);
}
sigset_t set;
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
/* chdir */
chdir(chdir_path);
/* setup open files */
if (files_len > 0) {
for (int i=0; i= 0) {
siginfo_t* siginfo = (void*)cont->buffer;
wrenSetSlotDouble(cont->vm, 1, siginfo->si_status);
return 1;
} else {
return fd_error(cont->vm, "wait", res);
}
}
void process_wait(WrenVM* vm) {
/* get wren parameters */
WrenHandle* fiber = wrenGetSlotHandle(vm, 1);
pid_t pid = wrenGetSlotDouble(vm, 2);
/* setup continuation */
struct continuation* cont =
setup_cont(sizeof(siginfo_t), vm, fiber, process_wait_finish);
/* enqueue */
struct io_uring_sqe* sqe = io_uring_get_sqe(ring);
siginfo_t* siginfo = (void*)cont->buffer;
io_uring_prep_waitid(sqe, P_PID, pid, siginfo, WEXITED, 0);
io_uring_sqe_set_data(sqe, cont);
}