add `subprocess.active`

This commit is contained in:
ValKmjolnir 2024-06-16 22:41:50 +08:00
parent 1de0874c8d
commit 4d838dc694
5 changed files with 57 additions and 44 deletions

View File

@ -60,6 +60,7 @@ private:
"__chdir", "__environ", "__getcwd", "__getenv",
// subprocess
"__subprocess_create",
"__subprocess_active",
"__subprocess_terminate"
};

View File

@ -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<subprocess>()->pi;
DWORD res;
GetExitCodeProcess(pi->hProcess, &res);
return res==STILL_ACTIVE? one:zero;
#else
auto pid = obj.ghost().get<subprocess>()->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}
};

View File

@ -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[];

View File

@ -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);
}

View File

@ -27,87 +27,68 @@ var usage = func() {
println(
os_time(),
info_hd(),
"\e[1musage: nasal watchdog.nas <filename> [\"argv\"]\e[0m"
"usage: nasal watchdog.nas <filename> [\"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);
}
}