Commit 17ff0819 authored by Yann Garcia's avatar Yann Garcia
Browse files

Add Upper Tester for open5gs

parent 121a6952
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
#include "async_process.hh"

void async_process::start(const std::string& command, const std::vector<std::string>& args, Options opts) {
void async_process::start(const std::string& command, const std::vector<std::string>& args, Options opts, std::chrono::milliseconds timeout) {
    // Sanity check
    if (running_) throw std::runtime_error("Process already running");

@@ -31,6 +31,12 @@ void async_process::start(const std::string& command, const std::vector<std::str
    if (opts_.onOutput) {
        reader_ = std::thread([this] { pumpOutput(); });
    }

    auto deadline = std::chrono::steady_clock::now() + timeout;
    int status = 0;
    while (std::chrono::steady_clock::now() < deadline) {
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }
}

bool async_process::pollExitStatus(int& status) {
@@ -66,10 +72,25 @@ int async_process::wait() {
    return exitStatus_;
}

void async_process::terminate(int signalNo) {
    if (pid_ > 0 && running_) {
int async_process::terminate(int signalNo, std::chrono::milliseconds timeout) {
    if (pid_ <= 0 or !running_) {
        return -1;
    }

    ::kill(pid_, signalNo);

    auto deadline = std::chrono::steady_clock::now() + timeout;
    int status = 0;

    while (std::chrono::steady_clock::now() < deadline) {
        pid_t r = ::waitpid(pid_, &status, WNOHANG);
        if (r == pid_) return 0;   // child exited
        if (r < 0) return -1;     // error
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

    ::kill(pid_, SIGKILL);
    return (::waitpid(pid_, &status, 0) == pid_) ? 0 : -1;
}

void async_process::setNonBlocking(int fd) {
+3 −3
Original line number Diff line number Diff line
@@ -30,13 +30,13 @@ public:

    async_process(const async_process&) = delete;
    async_process& operator=(const async_process&) = delete;
    void start(const std::string& command, const std::vector<std::string>& args, Options opts);
    void start(const std::string& command, const std::vector<std::string>& args, Options opts, std::chrono::milliseconds timeout = std::chrono::milliseconds(2000));
    bool pollExitStatus(int& status);
    int wait();
    void terminate(int signalNo = SIGTERM);
    int terminate(int signalNo = SIGTERM, std::chrono::milliseconds timeout = std::chrono::milliseconds(5000));

    inline bool running() const noexcept { return running_ && !exited_; };
    inline void killForce() { terminate(SIGKILL); };
    inline void killForce() { terminate(SIGTERM); }; // Clean termination of the process, with SIGTERM signal
    inline std::string readStdout() { return drainFd(stdoutPipe_[0]); };
    inline std::string readStderr() { return drainFd(stderrPipe_[0]); };
    inline pid_t pid() const noexcept { return pid_; };