✨ add `subprocess.active`
This commit is contained in:
parent
1de0874c8d
commit
4d838dc694
|
@ -60,6 +60,7 @@ private:
|
||||||
"__chdir", "__environ", "__getcwd", "__getenv",
|
"__chdir", "__environ", "__getcwd", "__getenv",
|
||||||
// subprocess
|
// subprocess
|
||||||
"__subprocess_create",
|
"__subprocess_create",
|
||||||
|
"__subprocess_active",
|
||||||
"__subprocess_terminate"
|
"__subprocess_terminate"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,31 @@ var builtin_subprocess_create(context* ctx, gc* ngc) {
|
||||||
return obj;
|
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) {
|
var builtin_subprocess_terminate(context* ctx, gc* ngc) {
|
||||||
auto obj = ctx->localr[1];
|
auto obj = ctx->localr[1];
|
||||||
if (!obj.object_check(subprocess::name())) {
|
if (!obj.object_check(subprocess::name())) {
|
||||||
|
@ -186,6 +211,7 @@ var builtin_subprocess_terminate(context* ctx, gc* ngc) {
|
||||||
|
|
||||||
nasal_builtin_table subprocess_native[] = {
|
nasal_builtin_table subprocess_native[] = {
|
||||||
{"__subprocess_create", builtin_subprocess_create},
|
{"__subprocess_create", builtin_subprocess_create},
|
||||||
|
{"__subprocess_active", builtin_subprocess_active},
|
||||||
{"__subprocess_terminate", builtin_subprocess_terminate},
|
{"__subprocess_terminate", builtin_subprocess_terminate},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
void subprocess_desc_dtor(void*);
|
void subprocess_desc_dtor(void*);
|
||||||
|
|
||||||
var builtin_subprocess_create(context*, gc*);
|
var builtin_subprocess_create(context*, gc*);
|
||||||
|
var builtin_subprocess_active(context*, gc*);
|
||||||
var builtin_subprocess_terminate(context*, gc*);
|
var builtin_subprocess_terminate(context*, gc*);
|
||||||
extern nasal_builtin_table subprocess_native[];
|
extern nasal_builtin_table subprocess_native[];
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@ var create = func(vec) {
|
||||||
return __subprocess_create(vec);
|
return __subprocess_create(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var active = func(pid) {
|
||||||
|
return __subprocess_active(pid);
|
||||||
|
}
|
||||||
|
|
||||||
var terminate = func(pid) {
|
var terminate = func(pid) {
|
||||||
return __subprocess_terminate(pid);
|
return __subprocess_terminate(pid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,87 +27,68 @@ var usage = func() {
|
||||||
println(
|
println(
|
||||||
os_time(),
|
os_time(),
|
||||||
info_hd(),
|
info_hd(),
|
||||||
"\e[1musage: nasal watchdog.nas <filename> [\"argv\"]\e[0m"
|
"usage: nasal watchdog.nas <filename> [\"argv\"]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var argv = runtime.argv();
|
var argv = runtime.argv();
|
||||||
if (size(argv)<1) {
|
if (size(argv)<1) {
|
||||||
println(
|
println(os_time(), err_hd(), "need correct file path to watch");
|
||||||
os_time(),
|
|
||||||
err_hd(),
|
|
||||||
"\e[1mneed correct file path to watch\e[0m"
|
|
||||||
);
|
|
||||||
usage();
|
usage();
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var filename = argv[0];
|
var filename = argv[0];
|
||||||
if (!io.exists(filename)) {
|
if (!io.exists(filename)) {
|
||||||
println(
|
println(os_time(), err_hd(), "file <", filename, "> does not exist");
|
||||||
os_time(),
|
|
||||||
err_hd(),
|
|
||||||
"\e[1mfile <",
|
|
||||||
filename,
|
|
||||||
"> does not exist\e[0m"
|
|
||||||
);
|
|
||||||
usage();
|
usage();
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = [];
|
var args = [];
|
||||||
if (size(argv)==2) {
|
if (size(argv)==2) {
|
||||||
println(
|
println(os_time(), info_hd(), "with argument(s) ", argv[1]);
|
||||||
os_time(),
|
|
||||||
info_hd(),
|
|
||||||
"\e[1mwith argument(s) ",
|
|
||||||
argv[1],
|
|
||||||
"\e[0m"
|
|
||||||
);
|
|
||||||
args = split(" ", argv[1]);
|
args = split(" ", argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var modified_time = io.fstat(filename).st_mtime;
|
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) {
|
while(1) {
|
||||||
unix.sleep(1);
|
unix.sleep(1);
|
||||||
if (!io.exists(filename)) {
|
if (!io.exists(filename)) {
|
||||||
println(
|
println(os_time(), err_hd(), "file <", filename, "> does not exist");
|
||||||
os_time(),
|
|
||||||
err_hd(),
|
|
||||||
"\e[1mfile <",
|
|
||||||
filename,
|
|
||||||
"> does not exist\e[0m"
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var latest_modified_time = io.fstat(filename).st_mtime;
|
var latest_modified_time = io.fstat(filename).st_mtime;
|
||||||
if (latest_modified_time!=modified_time) {
|
if (latest_modified_time!=modified_time) {
|
||||||
modified_time = latest_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;
|
var cmd = (os.platform()=="windows"?"":"./") ~ "nasal " ~ filename;
|
||||||
foreach(var i; args) {
|
foreach(var i; args) {
|
||||||
cmd ~= " " ~ i;
|
cmd ~= " " ~ i;
|
||||||
}
|
}
|
||||||
println(
|
println(os_time(), info_hd(), "executing command \"", cmd, "\"");
|
||||||
os_time(),
|
|
||||||
info_hd(),
|
|
||||||
"\e[1mexecuting command \"",
|
|
||||||
cmd,
|
|
||||||
"\"\e[0m"
|
|
||||||
);
|
|
||||||
|
|
||||||
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);
|
var ret = subprocess.terminate(subproc);
|
||||||
|
println(os_time(), ret!=0? err_hd():info_hd(), "process returned ", ret);
|
||||||
println(
|
|
||||||
os_time(),
|
|
||||||
ret!=0? err_hd():info_hd(),
|
|
||||||
"\e[1mprocess returned " ~ ret ~ "\e[0m"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue