Loading editor/src/main.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <confplus/exception.h> #include "plugin.h" #include "node_bridge.h" #include "webedit_config.h" #include "webedit_db.h" #include "webedit_server.h" Loading @@ -49,6 +50,10 @@ static void signalHandler(int sig) { } #endif int main(int argc, char *argv[]) { if (argc == 4 && std::string(argv[1]) == "--node-bridge-run") { return blogi::webedit::nodebridge::runNodeRunnerInProcess(argv[2], argv[3]); } cmdplus::CmdController cmdCtl(cmdplus::CmdController::getInstance()); cmdCtl.registerCmd("help", 'h', false, "", "Show this help"); Loading editor/src/node_bridge.h +100 −2 Original line number Diff line number Diff line #pragma once #include <cstdlib> #include <cstring> #include <string> #include <vector> #ifdef _WIN32 #include <windows.h> #else #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #endif #ifndef BLOGI_HAVE_LIBNODE #error "BLOGI_HAVE_LIBNODE must be defined: this build supports only embedded libnode" #endif Loading @@ -20,7 +29,26 @@ inline std::string getEnvOrDefault(const char *key, const char *fallback) { return std::string(fallback); } inline int runNodeRunner(const std::string &reqPath, inline std::string getSelfExecutablePath() { #ifdef _WIN32 char buf[MAX_PATH]; DWORD len = GetModuleFileNameA(nullptr, buf, static_cast<DWORD>(sizeof(buf))); if (len == 0 || len >= sizeof(buf)) { return std::string(); } return std::string(buf, len); #else char buf[4096]; ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); if (len <= 0) { return std::string(); } buf[len] = '\0'; return std::string(buf); #endif } inline int runNodeRunnerInProcess(const std::string &reqPath, const std::string &resPath) { static const std::string bridgeScript = "'use strict';" Loading Loading @@ -86,4 +114,74 @@ inline int runNodeRunner(const std::string &reqPath, return node::Start(static_cast<int>(argv.size()), argv.data()); } inline int runNodeRunner(const std::string &reqPath, const std::string &resPath) { const std::string selfPath = getSelfExecutablePath(); if (selfPath.empty()) { return -1; } #ifdef _WIN32 std::string cmdLine = "\"" + selfPath + "\" --node-bridge-run \"" + reqPath + "\" \"" + resPath + "\""; std::vector<char> mutableCmd(cmdLine.begin(), cmdLine.end()); mutableCmd.push_back('\0'); STARTUPINFOA si; PROCESS_INFORMATION pi; std::memset(&si, 0, sizeof(si)); std::memset(&pi, 0, sizeof(pi)); si.cb = sizeof(si); BOOL ok = CreateProcessA( selfPath.c_str(), mutableCmd.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi); if (!ok) { return -1; } WaitForSingleObject(pi.hProcess, INFINITE); DWORD exitCode = 1; GetExitCodeProcess(pi.hProcess, &exitCode); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return static_cast<int>(exitCode); #else pid_t pid = fork(); if (pid < 0) { return -1; } if (pid == 0) { execl(selfPath.c_str(), selfPath.c_str(), "--node-bridge-run", reqPath.c_str(), resPath.c_str(), static_cast<char *>(nullptr)); _exit(127); } int status = 0; if (waitpid(pid, &status, 0) < 0) { return -1; } if (WIFEXITED(status)) { return WEXITSTATUS(status); } if (WIFSIGNALED(status)) { return 128 + WTERMSIG(status); } return -1; #endif } } // namespace blogi::webedit::nodebridge Loading
editor/src/main.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <confplus/exception.h> #include "plugin.h" #include "node_bridge.h" #include "webedit_config.h" #include "webedit_db.h" #include "webedit_server.h" Loading @@ -49,6 +50,10 @@ static void signalHandler(int sig) { } #endif int main(int argc, char *argv[]) { if (argc == 4 && std::string(argv[1]) == "--node-bridge-run") { return blogi::webedit::nodebridge::runNodeRunnerInProcess(argv[2], argv[3]); } cmdplus::CmdController cmdCtl(cmdplus::CmdController::getInstance()); cmdCtl.registerCmd("help", 'h', false, "", "Show this help"); Loading
editor/src/node_bridge.h +100 −2 Original line number Diff line number Diff line #pragma once #include <cstdlib> #include <cstring> #include <string> #include <vector> #ifdef _WIN32 #include <windows.h> #else #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #endif #ifndef BLOGI_HAVE_LIBNODE #error "BLOGI_HAVE_LIBNODE must be defined: this build supports only embedded libnode" #endif Loading @@ -20,7 +29,26 @@ inline std::string getEnvOrDefault(const char *key, const char *fallback) { return std::string(fallback); } inline int runNodeRunner(const std::string &reqPath, inline std::string getSelfExecutablePath() { #ifdef _WIN32 char buf[MAX_PATH]; DWORD len = GetModuleFileNameA(nullptr, buf, static_cast<DWORD>(sizeof(buf))); if (len == 0 || len >= sizeof(buf)) { return std::string(); } return std::string(buf, len); #else char buf[4096]; ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); if (len <= 0) { return std::string(); } buf[len] = '\0'; return std::string(buf); #endif } inline int runNodeRunnerInProcess(const std::string &reqPath, const std::string &resPath) { static const std::string bridgeScript = "'use strict';" Loading Loading @@ -86,4 +114,74 @@ inline int runNodeRunner(const std::string &reqPath, return node::Start(static_cast<int>(argv.size()), argv.data()); } inline int runNodeRunner(const std::string &reqPath, const std::string &resPath) { const std::string selfPath = getSelfExecutablePath(); if (selfPath.empty()) { return -1; } #ifdef _WIN32 std::string cmdLine = "\"" + selfPath + "\" --node-bridge-run \"" + reqPath + "\" \"" + resPath + "\""; std::vector<char> mutableCmd(cmdLine.begin(), cmdLine.end()); mutableCmd.push_back('\0'); STARTUPINFOA si; PROCESS_INFORMATION pi; std::memset(&si, 0, sizeof(si)); std::memset(&pi, 0, sizeof(pi)); si.cb = sizeof(si); BOOL ok = CreateProcessA( selfPath.c_str(), mutableCmd.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi); if (!ok) { return -1; } WaitForSingleObject(pi.hProcess, INFINITE); DWORD exitCode = 1; GetExitCodeProcess(pi.hProcess, &exitCode); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return static_cast<int>(exitCode); #else pid_t pid = fork(); if (pid < 0) { return -1; } if (pid == 0) { execl(selfPath.c_str(), selfPath.c_str(), "--node-bridge-run", reqPath.c_str(), resPath.c_str(), static_cast<char *>(nullptr)); _exit(127); } int status = 0; if (waitpid(pid, &status, 0) < 0) { return -1; } if (WIFEXITED(status)) { return WEXITSTATUS(status); } if (WIFSIGNALED(status)) { return 128 + WTERMSIG(status); } return -1; #endif } } // namespace blogi::webedit::nodebridge