mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 19:19:53 +00:00
Add :d switch to os/spawn.
This allows for starting processes that can be turned into zombies.
This commit is contained in:
parent
f11b2c5a0d
commit
202783c67a
@ -1808,14 +1808,16 @@ JanetAsyncStatus ev_machine_write(JanetListenerState *s, JanetAsyncEvent event)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// File handles in IOCP need to specify this if they are writing to the
|
/*
|
||||||
// ends of files, like how this is used here.
|
* File handles in IOCP need to specify this if they are writing to the
|
||||||
// If the underlying resource doesn't support seeking
|
* ends of files, like how this is used here.
|
||||||
// byte offsets, they will be ignored
|
* If the underlying resource doesn't support seeking
|
||||||
// but this otherwise writes to the end of the file in question
|
* byte offsets, they will be ignored
|
||||||
// Right now, os/open streams aren't seekable, so this works.
|
* but this otherwise writes to the end of the file in question
|
||||||
// for more details see the lpOverlapped parameter in
|
* Right now, os/open streams aren't seekable, so this works.
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile
|
* for more details see the lpOverlapped parameter in
|
||||||
|
* https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile
|
||||||
|
*/
|
||||||
state->overlapped.Offset = (DWORD) 0xFFFFFFFF;
|
state->overlapped.Offset = (DWORD) 0xFFFFFFFF;
|
||||||
state->overlapped.OffsetHigh = (DWORD) 0xFFFFFFFF;
|
state->overlapped.OffsetHigh = (DWORD) 0xFFFFFFFF;
|
||||||
status = WriteFile(s->stream->handle, bytes, len, NULL, &state->overlapped);
|
status = WriteFile(s->stream->handle, bytes, len, NULL, &state->overlapped);
|
||||||
|
@ -353,6 +353,7 @@ static const JanetAbstractType ProcAT;
|
|||||||
#define JANET_PROC_OWNS_STDIN 16
|
#define JANET_PROC_OWNS_STDIN 16
|
||||||
#define JANET_PROC_OWNS_STDOUT 32
|
#define JANET_PROC_OWNS_STDOUT 32
|
||||||
#define JANET_PROC_OWNS_STDERR 64
|
#define JANET_PROC_OWNS_STDERR 64
|
||||||
|
#define JANET_PROC_ALLOW_ZOMBIE 128
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int flags;
|
int flags;
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
@ -434,12 +435,14 @@ static int janet_proc_gc(void *p, size_t s) {
|
|||||||
JanetProc *proc = (JanetProc *) p;
|
JanetProc *proc = (JanetProc *) p;
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
if (!(proc->flags & JANET_PROC_CLOSED)) {
|
if (!(proc->flags & JANET_PROC_CLOSED)) {
|
||||||
|
if (!(proc->flags & JANET_PROC_ALLOW_ZOMBIE)) {
|
||||||
TerminateProcess(proc->pHandle, 1);
|
TerminateProcess(proc->pHandle, 1);
|
||||||
|
}
|
||||||
CloseHandle(proc->pHandle);
|
CloseHandle(proc->pHandle);
|
||||||
CloseHandle(proc->tHandle);
|
CloseHandle(proc->tHandle);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!(proc->flags & JANET_PROC_WAITED)) {
|
if (!(proc->flags & (JANET_PROC_WAITED | JANET_PROC_ALLOW_ZOMBIE))) {
|
||||||
/* Kill and wait to prevent zombies */
|
/* Kill and wait to prevent zombies */
|
||||||
kill(proc->pid, SIGKILL);
|
kill(proc->pid, SIGKILL);
|
||||||
int status;
|
int status;
|
||||||
@ -759,7 +762,7 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
|
|||||||
/* Get flags */
|
/* Get flags */
|
||||||
uint64_t flags = 0;
|
uint64_t flags = 0;
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
flags = janet_getflags(argv, 1, "epx");
|
flags = janet_getflags(argv, 1, "epxd");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get environment */
|
/* Get environment */
|
||||||
@ -777,7 +780,7 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
|
|||||||
JanetHandle new_in = JANET_HANDLE_NONE, new_out = JANET_HANDLE_NONE, new_err = JANET_HANDLE_NONE;
|
JanetHandle new_in = JANET_HANDLE_NONE, new_out = JANET_HANDLE_NONE, new_err = JANET_HANDLE_NONE;
|
||||||
JanetHandle pipe_in = JANET_HANDLE_NONE, pipe_out = JANET_HANDLE_NONE, pipe_err = JANET_HANDLE_NONE;
|
JanetHandle pipe_in = JANET_HANDLE_NONE, pipe_out = JANET_HANDLE_NONE, pipe_err = JANET_HANDLE_NONE;
|
||||||
int pipe_errflag = 0; /* Track errors setting up pipes */
|
int pipe_errflag = 0; /* Track errors setting up pipes */
|
||||||
int pipe_owner_flags = 0;
|
int pipe_owner_flags = (is_spawn && (flags & 0x8)) ? JANET_PROC_ALLOW_ZOMBIE : 0;
|
||||||
|
|
||||||
/* Get optional redirections */
|
/* Get optional redirections */
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
@ -1842,6 +1845,7 @@ static Janet os_open(int32_t argc, Janet *argv) {
|
|||||||
case 'W':
|
case 'W':
|
||||||
shareMode |= FILE_SHARE_WRITE;
|
shareMode |= FILE_SHARE_WRITE;
|
||||||
break;
|
break;
|
||||||
|
gg
|
||||||
case 'H':
|
case 'H':
|
||||||
flagsAndAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
flagsAndAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||||
break;
|
break;
|
||||||
@ -2094,12 +2098,13 @@ static const JanetReg os_cfuns[] = {
|
|||||||
"os/execute", os_execute,
|
"os/execute", os_execute,
|
||||||
JDOC("(os/execute args &opt flags env)\n\n"
|
JDOC("(os/execute args &opt flags env)\n\n"
|
||||||
"Execute a program on the system and pass it string arguments. `flags` "
|
"Execute a program on the system and pass it string arguments. `flags` "
|
||||||
"is a keyword that modifies how the program will execute.\n\n"
|
"is a keyword that modifies how the program will execute.\n"
|
||||||
"* :e - enables passing an environment to the program. Without :e, the "
|
"* :e - enables passing an environment to the program. Without :e, the "
|
||||||
"current environment is inherited.\n\n"
|
"current environment is inherited.\n"
|
||||||
"* :p - allows searching the current PATH for the binary to execute. "
|
"* :p - allows searching the current PATH for the binary to execute. "
|
||||||
"Without this flag, binaries must use absolute paths.\n\n"
|
"Without this flag, binaries must use absolute paths.\n"
|
||||||
"* :x - raise error if exit code is non-zero.\n\n"
|
"* :x - raise error if exit code is non-zero.\n"
|
||||||
|
"* :d - Don't try and terminate the process on garbage collection (allow spawning zombies).\n"
|
||||||
"`env` is a table or struct mapping environment variables to values. It can also "
|
"`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. "
|
"contain the keys :in, :out, and :err, which allow redirecting stdio in the subprocess. "
|
||||||
"These arguments should be core/file values. "
|
"These arguments should be core/file values. "
|
||||||
|
Loading…
Reference in New Issue
Block a user