Commit f0110058 authored by jan.koester's avatar jan.koester
Browse files

test

parent 84387b48
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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"
@@ -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");
+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
@@ -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';"
@@ -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