From 4d838dc694600b8287a74931a5cf9bfab1bbbe2c Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sun, 16 Jun 2024 22:41:50 +0800 Subject: [PATCH] :sparkles: add `subprocess.active` --- src/nasal_codegen.h | 1 + src/natives/subprocess.cpp | 26 ++++++++++++++ src/natives/subprocess.h | 1 + std/subprocess.nas | 4 +++ test/watchdog.nas | 69 ++++++++++++++------------------------ 5 files changed, 57 insertions(+), 44 deletions(-) diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 961a105..938cdb8 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -60,6 +60,7 @@ private: "__chdir", "__environ", "__getcwd", "__getenv", // subprocess "__subprocess_create", + "__subprocess_active", "__subprocess_terminate" }; diff --git a/src/natives/subprocess.cpp b/src/natives/subprocess.cpp index 1e5394d..7acbc33 100644 --- a/src/natives/subprocess.cpp +++ b/src/natives/subprocess.cpp @@ -148,6 +148,31 @@ var builtin_subprocess_create(context* ctx, gc* ngc) { return obj; } +var builtin_subprocess_active(context* ctx, gc* ngc) { + auto obj = ctx->localr[1]; + if (!obj.object_check(subprocess::name())) { + return nas_err("subprocess::active", + "need correct subprocess object" + ); + } + +#ifdef WIN32 + auto pi = &obj.ghost().get()->pi; + + DWORD res; + GetExitCodeProcess(pi->hProcess, &res); + + return res==STILL_ACTIVE? one:zero; +#else + auto pid = obj.ghost().get()->pid; + + int status; + pid_t result = waitpid(pid, &status, WNOHANG); + + return result==0? one:zero; +#endif +} + var builtin_subprocess_terminate(context* ctx, gc* ngc) { auto obj = ctx->localr[1]; if (!obj.object_check(subprocess::name())) { @@ -186,6 +211,7 @@ var builtin_subprocess_terminate(context* ctx, gc* ngc) { nasal_builtin_table subprocess_native[] = { {"__subprocess_create", builtin_subprocess_create}, + {"__subprocess_active", builtin_subprocess_active}, {"__subprocess_terminate", builtin_subprocess_terminate}, {nullptr, nullptr} }; diff --git a/src/natives/subprocess.h b/src/natives/subprocess.h index 587527f..58db648 100644 --- a/src/natives/subprocess.h +++ b/src/natives/subprocess.h @@ -31,6 +31,7 @@ public: void subprocess_desc_dtor(void*); var builtin_subprocess_create(context*, gc*); +var builtin_subprocess_active(context*, gc*); var builtin_subprocess_terminate(context*, gc*); extern nasal_builtin_table subprocess_native[]; diff --git a/std/subprocess.nas b/std/subprocess.nas index f256ca8..8cf248a 100644 --- a/std/subprocess.nas +++ b/std/subprocess.nas @@ -3,6 +3,10 @@ var create = func(vec) { return __subprocess_create(vec); } +var active = func(pid) { + return __subprocess_active(pid); +} + var terminate = func(pid) { return __subprocess_terminate(pid); } diff --git a/test/watchdog.nas b/test/watchdog.nas index 6b0658b..3f205e4 100644 --- a/test/watchdog.nas +++ b/test/watchdog.nas @@ -27,87 +27,68 @@ var usage = func() { println( os_time(), info_hd(), - "\e[1musage: nasal watchdog.nas [\"argv\"]\e[0m" + "usage: nasal watchdog.nas [\"argv\"]" ); } var argv = runtime.argv(); if (size(argv)<1) { - println( - os_time(), - err_hd(), - "\e[1mneed correct file path to watch\e[0m" - ); + println(os_time(), err_hd(), "need correct file path to watch"); usage(); exit(-1); } var filename = argv[0]; if (!io.exists(filename)) { - println( - os_time(), - err_hd(), - "\e[1mfile <", - filename, - "> does not exist\e[0m" - ); + println(os_time(), err_hd(), "file <", filename, "> does not exist"); usage(); exit(-1); } var args = []; if (size(argv)==2) { - println( - os_time(), - info_hd(), - "\e[1mwith argument(s) ", - argv[1], - "\e[0m" - ); + println(os_time(), info_hd(), "with argument(s) ", argv[1]); args = split(" ", argv[1]); } var modified_time = io.fstat(filename).st_mtime; -println(os_time(), info_hd(), "\e[1mwatching ", filename, " ..\e[0m"); +println(os_time(), info_hd(), "watching ", filename, " .."); while(1) { unix.sleep(1); if (!io.exists(filename)) { - println( - os_time(), - err_hd(), - "\e[1mfile <", - filename, - "> does not exist\e[0m" - ); + println(os_time(), err_hd(), "file <", filename, "> does not exist"); break; } var latest_modified_time = io.fstat(filename).st_mtime; if (latest_modified_time!=modified_time) { modified_time = latest_modified_time; - println(os_time(), modified_hd(), "\e[1m", filename, "\e[0m"); + println(os_time(), modified_hd(), filename); var cmd = (os.platform()=="windows"?"":"./") ~ "nasal " ~ filename; foreach(var i; args) { cmd ~= " " ~ i; } - println( - os_time(), - info_hd(), - "\e[1mexecuting command \"", - cmd, - "\"\e[0m" - ); + println(os_time(), info_hd(), "executing command \"", cmd, "\""); - var subproc = subprocess.create(["nasal", filename]~args); + var subproc = subprocess.create(["nasal", filename] ~ args); - unix.sleep(2); + # check if active every 0.5s + var exited = false; + for(var t = 0; t<=4; t+=0.1) { + unix.sleep(0.1); + if (!subprocess.active(subproc)) { + exited = true; + break; + } + if (io.fstat(filename).st_mtime!=modified_time) { + println(os_time(), modified_hd(), "file changed, reloading.."); + break; + } + } + + # get return value var ret = subprocess.terminate(subproc); - - println( - os_time(), - ret!=0? err_hd():info_hd(), - "\e[1mprocess returned " ~ ret ~ "\e[0m" - ); + println(os_time(), ret!=0? err_hd():info_hd(), "process returned ", ret); } } \ No newline at end of file