Skip to content

Commit

Permalink
✨ add subprocess.active
Browse files Browse the repository at this point in the history
  • Loading branch information
ValKmjolnir committed Jun 16, 2024
1 parent 1de0874 commit 4d838dc
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 45 deletions.
1 change: 1 addition & 0 deletions src/nasal_codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class codegen {
"__chdir", "__environ", "__getcwd", "__getenv",
// subprocess
"__subprocess_create",
"__subprocess_active",
"__subprocess_terminate"
};

Expand Down
26 changes: 26 additions & 0 deletions src/natives/subprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())) {
Expand Down Expand Up @@ -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}
};
Expand Down
1 change: 1 addition & 0 deletions src/natives/subprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct subprocess {
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[];

Expand Down
4 changes: 4 additions & 0 deletions std/subprocess.nas
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
71 changes: 26 additions & 45 deletions test/watchdog.nas
Original file line number Diff line number Diff line change
Expand Up @@ -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"
);

var subproc = subprocess.create(["nasal", filename]~args);
println(os_time(), info_hd(), "executing command \"", cmd, "\"");

var subproc = subprocess.create(["nasal", filename] ~ args);

# 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;
}
}

unix.sleep(2);
# 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);
}
}

0 comments on commit 4d838dc

Please sign in to comment.