mirror of
https://github.com/janet-lang/janet
synced 2024-12-01 04:19:55 +00:00
Make some improvements and add os/proc-kill as well.
This commit is contained in:
parent
e7fca0051e
commit
7079cc43c9
@ -2,7 +2,11 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## Unreleased - ???
|
## Unreleased - ???
|
||||||
|
- Add `os/proc-wait` and `os/proc-kill` for interacting with processes.
|
||||||
- Add `janet_getjfile` to C API.
|
- Add `janet_getjfile` to C API.
|
||||||
|
- Allow redirection of stdin, stdout, and stderr by passing keywords in the env table.
|
||||||
|
- Add `:a` flag to `os/execute` to get a core/process back instead of an exit code.
|
||||||
|
When called like this, `os/execute` returns immediately.
|
||||||
- Add `:x` flag to os/execute to raise error when exit code is non-zero.
|
- Add `:x` flag to os/execute to raise error when exit code is non-zero.
|
||||||
- Don't run `main` when flychecking.
|
- Don't run `main` when flychecking.
|
||||||
- Add `:n` flag to `file/open` to raise an error if file cannot be opened.
|
- Add `:n` flag to `file/open` to raise an error if file cannot be opened.
|
||||||
|
@ -315,7 +315,10 @@ static JanetBuffer *os_exec_escape(JanetView args) {
|
|||||||
|
|
||||||
/* Process type for when running a subprocess and not immediately waiting */
|
/* Process type for when running a subprocess and not immediately waiting */
|
||||||
static const JanetAbstractType ProcAT;
|
static const JanetAbstractType ProcAT;
|
||||||
|
#define JANET_PROC_CLOSED 1
|
||||||
|
#define JANET_PROC_WAITED 2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int flags;
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
HANDLE pid;
|
HANDLE pid;
|
||||||
#else
|
#else
|
||||||
@ -336,20 +339,54 @@ static int janet_proc_mark(void *p, size_t s) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Janet os_proc_wait(int32_t argc, Janet *argv) {
|
static Janet os_proc_wait_impl(JanetProc *proc) {
|
||||||
janet_fixarity(argc, 1);
|
if (proc->flags & JANET_PROC_WAITED) {
|
||||||
JanetProc *proc = janet_getabstract(argv, 0, &ProcAT);
|
janet_panicf("cannot wait on process that has already finished");
|
||||||
if (proc->return_code != -1) {
|
|
||||||
janet_panicf("can't wait on process that has already finished");
|
|
||||||
}
|
}
|
||||||
|
proc->flags |= JANET_PROC_WAITED;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
#ifdef JANET_WINDOWS
|
||||||
|
WaitForSingleObject(proc->pid, INFINITE);
|
||||||
|
GetExitCodeProcess(proc->pid, &status);
|
||||||
|
#else
|
||||||
waitpid(proc->pid, &status, 0);
|
waitpid(proc->pid, &status, 0);
|
||||||
|
#endif
|
||||||
proc->return_code = (int32_t) status;
|
proc->return_code = (int32_t) status;
|
||||||
return janet_wrap_integer(proc->return_code);
|
return janet_wrap_integer(proc->return_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Janet os_proc_wait(int32_t argc, Janet *argv) {
|
||||||
|
janet_fixarity(argc, 1);
|
||||||
|
JanetProc *proc = janet_getabstract(argv, 0, &ProcAT);
|
||||||
|
return os_proc_wait_impl(proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Janet os_proc_kill(int32_t argc, Janet *argv) {
|
||||||
|
janet_arity(argc, 1, 2);
|
||||||
|
JanetProc *proc = janet_getabstract(argv, 0, &ProcAT);
|
||||||
|
#ifdef JANET_WINDOWS
|
||||||
|
if (proc->flags & JANET_PROC_CLOSED) {
|
||||||
|
janet_panicf("cannot close process handle that is already closed");
|
||||||
|
}
|
||||||
|
proc->flags |= JANET_PROC_CLOSED;
|
||||||
|
int status = CloseHandle(proc->pid);
|
||||||
|
#else
|
||||||
|
int status = kill(proc->pid, SIGKILL);
|
||||||
|
#endif
|
||||||
|
if (status) {
|
||||||
|
janet_panic(strerror(errno));
|
||||||
|
}
|
||||||
|
/* After killing process we wait on it. */
|
||||||
|
if (argc > 1 && janet_truthy(argv[1])) {
|
||||||
|
return os_proc_wait_impl(proc);
|
||||||
|
} else {
|
||||||
|
return argv[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const JanetMethod proc_methods[] = {
|
static const JanetMethod proc_methods[] = {
|
||||||
{"wait", os_proc_wait},
|
{"wait", os_proc_wait},
|
||||||
|
{"kill", os_proc_kill},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -538,6 +575,7 @@ static Janet os_execute(int32_t argc, Janet *argv) {
|
|||||||
proc->in = new_in;
|
proc->in = new_in;
|
||||||
proc->out = new_out;
|
proc->out = new_out;
|
||||||
proc->err = new_err;
|
proc->err = new_err;
|
||||||
|
proc->flags = 0;
|
||||||
return janet_wrap_abstract(proc);
|
return janet_wrap_abstract(proc);
|
||||||
} else if (janet_flag_at(flags, 2) && status) {
|
} else if (janet_flag_at(flags, 2) && status) {
|
||||||
janet_panicf("command failed with non-zero exit code %d", status);
|
janet_panicf("command failed with non-zero exit code %d", status);
|
||||||
@ -1459,9 +1497,12 @@ static const JanetReg os_cfuns[] = {
|
|||||||
"current environment is inherited.\n"
|
"current environment is inherited.\n"
|
||||||
"\t:p - allows searching the current PATH for the binary to execute. "
|
"\t:p - allows searching the current PATH for the binary to execute. "
|
||||||
"Without this flag, binaries must use absolute paths.\n"
|
"Without this flag, binaries must use absolute paths.\n"
|
||||||
"\t:x - raise error if exit code is non-zero.\n\n"
|
"\t:x - raise error if exit code is non-zero.\n"
|
||||||
"env is a table or struct mapping environment variables to values. "
|
"\t:a - Runs the process asynchronously and returns a core/process.\n\n"
|
||||||
"Returns the exit status of the program.")
|
"env is a table or struct mapping environment variables to values. It can also "
|
||||||
|
"contain the keys :in, :out, and :err, which allow redirecting stdio in the subprocess. "
|
||||||
|
"These arguments should be core/file values. "
|
||||||
|
"Returns the exit status of the program, or a core/process object if the :a flag is given.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"os/shell", os_shell,
|
"os/shell", os_shell,
|
||||||
@ -1558,6 +1599,13 @@ static const JanetReg os_cfuns[] = {
|
|||||||
JDOC("(os/proc-wait proc)\n\n"
|
JDOC("(os/proc-wait proc)\n\n"
|
||||||
"Block until the subprocess completes. Returns the subprocess return code.")
|
"Block until the subprocess completes. Returns the subprocess return code.")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"os/proc-kill", os_proc_kill,
|
||||||
|
JDOC("(os/proc-kill proc &opt wait)\n\n"
|
||||||
|
"Kill a subprocess by sending SIGKILL to it on posix systems, or by closing the process "
|
||||||
|
"handle on windows. If wait is truthy, will wait for the process to finsih and "
|
||||||
|
"returns the exit code. Otherwise, returns proc.")
|
||||||
|
},
|
||||||
#endif
|
#endif
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user