From 4b8c1ac2d2d5c13d7c8592fd6d94b34a6a8b3549 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 8 Oct 2023 11:09:00 -0500 Subject: [PATCH 1/4] Add os/posix-fork Very simple fork function that returns a process object that can be waited on. --- src/core/os.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/core/os.c b/src/core/os.c index 460cb7eb..091a0c6f 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -2340,6 +2340,34 @@ JANET_CORE_FN(os_permission_int, return janet_wrap_integer(os_get_unix_mode(argv, 0)); } +JANET_CORE_FN(os_posix_fork, + "(os/posix-fork)", + "Make a `fork` system call and create a new process. Return nil if in the new process, otherwise a core/proc object (as returned by os/spawn). " + "Not supported on all system (POSIX only).") { + janet_sandbox_assert(JANET_SANDBOX_SUBPROCESS); + janet_fixarity(argc, 0); + (void) argv; +#ifdef JANET_WINDOWS + janet_panic("not supported"); +#else + pid_t result; + do { + result = fork(); + } while (result == -1 && errno == EINTR); + if (result == -1) { + janet_panic(strerror(errno)); + } + if (result) { + JanetProc *proc = janet_abstract(&ProcAT, sizeof(JanetProc)); + memset(proc, 0, sizeof(JanetProc)); + proc->pid = result; + proc->flags = JANET_PROC_ALLOW_ZOMBIE; + return janet_wrap_abstract(proc); + } + return janet_wrap_nil(); +#endif +} + #ifdef JANET_EV /* @@ -2626,6 +2654,7 @@ void janet_lib_os(JanetTable *env) { JANET_CORE_REG("os/execute", os_execute), JANET_CORE_REG("os/spawn", os_spawn), JANET_CORE_REG("os/shell", os_shell), + JANET_CORE_REG("os/posix-fork", os_posix_fork), /* no need to sandbox process management if you can't create processes * (allows for limited functionality if use exposes C-functions to create specific processes) */ JANET_CORE_REG("os/proc-wait", os_proc_wait), From cf4901e71372d0a5553dbdf82a578f892565a6a0 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 8 Oct 2023 11:35:08 -0500 Subject: [PATCH 2/4] Update docstring for os/posix-fork --- src/core/os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/os.c b/src/core/os.c index 091a0c6f..64f6920d 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -2342,8 +2342,8 @@ JANET_CORE_FN(os_permission_int, JANET_CORE_FN(os_posix_fork, "(os/posix-fork)", - "Make a `fork` system call and create a new process. Return nil if in the new process, otherwise a core/proc object (as returned by os/spawn). " - "Not supported on all system (POSIX only).") { + "Make a `fork` system call and create a new process. Return nil if in the new process, otherwise a core/process object (as returned by os/spawn). " + "Not supported on all systems (POSIX only).") { janet_sandbox_assert(JANET_SANDBOX_SUBPROCESS); janet_fixarity(argc, 0); (void) argv; From 5442c8e86df3d21ff903a4e89e46f726160b085e Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 8 Oct 2023 12:34:13 -0500 Subject: [PATCH 3/4] Add EV_EOF and EV_CLEAR to selfpipe for kqueue --- src/core/ev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ev.c b/src/core/ev.c index 057296a7..823a13e3 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -1900,7 +1900,7 @@ void janet_ev_init(void) { janet_vm.timer_enabled = 0; if (janet_vm.kq == -1) goto error; struct kevent event; - EV_SETx(&event, janet_vm.selfpipe[0], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, janet_vm.selfpipe); + EV_SETx(&event, janet_vm.selfpipe[0], EVFILT_READ, EV_ADD | EV_ENABLE | EV_EOF | EV_CLEAR, 0, 0, janet_vm.selfpipe); add_kqueue_events(&event, 1); return; error: From d71c100ca7338270d8e41dbd0bd3385cd2140c7f Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 8 Oct 2023 13:13:58 -0500 Subject: [PATCH 4/4] Revert "Add EV_EOF and EV_CLEAR to selfpipe for kqueue" This reverts commit 5442c8e86df3d21ff903a4e89e46f726160b085e. --- src/core/ev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ev.c b/src/core/ev.c index 823a13e3..057296a7 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -1900,7 +1900,7 @@ void janet_ev_init(void) { janet_vm.timer_enabled = 0; if (janet_vm.kq == -1) goto error; struct kevent event; - EV_SETx(&event, janet_vm.selfpipe[0], EVFILT_READ, EV_ADD | EV_ENABLE | EV_EOF | EV_CLEAR, 0, 0, janet_vm.selfpipe); + EV_SETx(&event, janet_vm.selfpipe[0], EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, janet_vm.selfpipe); add_kqueue_events(&event, 1); return; error: