From bf9f0d6338e5043a1816ff9995261c6fd032a8fe Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Wed, 12 Jun 2024 01:25:40 +0800 Subject: [PATCH] :sparkles: add subprocess.fork/kill --- src/nasal_codegen.h | 4 +- src/nasal_import.cpp | 9 ++- src/natives/subprocess.cpp | 112 +++++++++++++++++++++++++++++++++++++ src/natives/subprocess.h | 3 + std/dylib.nas | 2 +- std/subprocess.nas | 10 +++- 6 files changed, 136 insertions(+), 4 deletions(-) diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index ab742c9..175fb06 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -62,7 +62,9 @@ private: // subprocess "__subprocess_popen", "__subprocess_pclose", - "__subprocess_read_stdout" + "__subprocess_read_stdout", + "__subprocess_fork", + "__subprocess_kill" }; // file mapper for file -> index diff --git a/src/nasal_import.cpp b/src/nasal_import.cpp index 4093516..77a206e 100644 --- a/src/nasal_import.cpp +++ b/src/nasal_import.cpp @@ -9,8 +9,15 @@ namespace nasal { linker::linker(): show_path_flag(false), this_file("") { + const auto env_get_path = getenv("PATH"); + if (!env_get_path) { + err.warn("link", "cannot get env \"PATH\"."); + envpath = {}; + return; + } + const auto seperator = util::is_windows()? ';':':'; - const auto PATH = std::string(getenv("PATH")); + const auto PATH = std::string(env_get_path); usize last = 0, position = PATH.find(seperator, 0); while(position!=std::string::npos) { std::string dirpath = PATH.substr(last, position-last); diff --git a/src/natives/subprocess.cpp b/src/natives/subprocess.cpp index f6974e0..91a63a5 100644 --- a/src/natives/subprocess.cpp +++ b/src/natives/subprocess.cpp @@ -4,9 +4,17 @@ #ifdef _MSC_VER #define popen _popen #define pclose _pclose +#define perror _perror +#endif + +#ifndef _MSC_VER +#include +#include #endif #include +#include +#include namespace nasal { @@ -59,10 +67,114 @@ var builtin_subprocess_read_stdout(context* ctx, gc* ngc) { return res; } +var builtin_subprocess_fork(context* ctx, gc* ngc) { + auto cmd = ctx->localr[1]; + if (!cmd.is_vec()) { + return nas_err("subprocess::fork", "expect a string as the command"); + } + +#ifdef WIN32 + // STARTUPINFO si; + // PROCESS_INFORMATION pi; + + // // init STARTUPINFO + // ZeroMemory(&si, sizeof(si)); + // si.cb = sizeof(si); + // si.dwFlags = STARTF_USESHOWWINDOW; + // si.wShowWindow = SW_SHOW; + + // // init PROCESS_INFORMATION + // ZeroMemory(&pi, sizeof(pi)); + + // auto len = MultiByteToWideChar(CP_UTF8, 0, cmd.str().c_str(), -1, nullptr, 0); + + // auto res = CreateProcess( + // nullptr, + // cmd.str().c_str(), + // nullptr, + // nullptr, + // false, + // 0, + // nullptr, + // nullptr, + // &si, + // &pi + // ); +#else + // create argv + char** argv = new char*[cmd.vec().elems.size()+1]; + for(const auto& v : cmd.vec().elems) { + if (!v.is_str()) { + return nas_err("subprocess::fork", "non-string arguments"); + } + } + for(usize i = 0; ilocalr[1]; + if (!pid.is_num()) { + return nas_err("subprocess::kill", "need numeral pid"); + } + + int status; + pid_t result = waitpid(pid.num(), &status, WNOHANG); + // child process running + if (result==0) { + kill(pid.num(), SIGTERM); + } +#endif + return nil; +} + nasal_builtin_table subprocess_native[] = { {"__subprocess_popen", builtin_subprocess_popen}, {"__subprocess_pclose", builtin_subprocess_pclose}, {"__subprocess_read_stdout", builtin_subprocess_read_stdout}, + {"__subprocess_fork", builtin_subprocess_fork}, + {"__subprocess_kill", builtin_subprocess_kill}, {nullptr, nullptr} }; diff --git a/src/natives/subprocess.h b/src/natives/subprocess.h index 23029a4..144b63d 100644 --- a/src/natives/subprocess.h +++ b/src/natives/subprocess.h @@ -11,6 +11,9 @@ void subprocess_destructor(void*); var builtin_subprocess_popen(context*, gc*); var builtin_subprocess_pclose(context*, gc*); var builtin_subprocess_read_stdout(context*, gc*); + +var builtin_subprocess_fork(context*, gc*); +var builtin_subprocess_kill(context*, gc*); extern nasal_builtin_table subprocess_native[]; } \ No newline at end of file diff --git a/std/dylib.nas b/std/dylib.nas index a808653..a63b0a0 100644 --- a/std/dylib.nas +++ b/std/dylib.nas @@ -13,7 +13,7 @@ var dlopen = func(libname) { if (io.exists(libname)) return __dlopen(libname); # find dynamic lib through PATH - var envpath = split(os.platform()=="windows"? ";":":",unix.getenv("PATH")); + var envpath = split(os.platform()=="windows"? ";":":", unix.getenv("PATH")); # first find ./module append(envpath, "."); var path = os.platform()=="windows"? "\\module\\":"/module/"; diff --git a/std/subprocess.nas b/std/subprocess.nas index e82cf8b..c8b5abf 100644 --- a/std/subprocess.nas +++ b/std/subprocess.nas @@ -8,4 +8,12 @@ var pclose = func(subproc) { var read = func(subproc) { return __subprocess_read_stdout(subproc); -} \ No newline at end of file +} + +var fork = func(vec) { + return __subprocess_fork(vec); +} + +var kill = func(pid) { + return __subprocess_kill(pid); +}