192 lines · 4.0 KB · C++
RawDownload
#include "Utilities.h" #include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>#include <boost/filesystem.hpp>#include <iostream> namespace fs = boost::filesystem;using std::string;using std::vector; int ChildProcess(string program, vector<string> args, int timeout){    std::vector<const char*> argv;    argv.push_back(program.c_str());    for(string& s : args)        argv.push_back(s.c_str());    argv.push_back(NULL);     pid_t pid = fork();    if(pid < 0)    {        perror("unable to fork");        return 1;    }    else if(pid == 0)    {        pid_t worker_pid = timeout ? fork() : 0;        if(worker_pid < 0)        {            perror("unable to fork");            _exit(1);        }        if(worker_pid == 0)        {            execvp(argv[0], const_cast<char* const *> (argv.data()));            perror("exec failed");            std::cerr << "Tried to execute: " << program;            for(auto a : args)                std::cerr << " " << a;            std::cerr << std::endl;            _exit(1);        }         pid_t timeout_pid = fork();        if(timeout_pid < 0)        {            perror("unable to fork");            _exit(1);        }        if(timeout_pid == 0)        {            sleep(timeout);            _exit(0);        }        int wstatus;        pid_t exited_pid = wait(&wstatus);        if(exited_pid == worker_pid)        {            kill(timeout_pid, SIGKILL);            wait(NULL);            if(!WIFEXITED(wstatus))            {                return 1;            }            else            {                int exitcode = WEXITSTATUS(wstatus);                _exit(exitcode);            }        }        else        {            kill(worker_pid, SIGKILL);            wait(NULL);            _exit(1);        }    }    else    {        int wstatus;        int result = 0;        do        {            result = waitpid(pid, &wstatus, 0);        } while(result == -1 && errno == EINTR);         if(!WIFEXITED(wstatus))        {            return 1;        }        else        {            int exitcode = WEXITSTATUS(wstatus);            return exitcode;        }    } }   bool CheckExecutable(std::string program){    if(access(program.c_str(), X_OK) == 0)        return true;    if(program.find("/") != std::string::npos)        return false;    const char *PATH = getenv("PATH");     if(PATH)    {        bool endFound = false;        do        {            const char *end = strchr(PATH, ':');            if(!end)            {                end = strchr(PATH, '\0');                endFound = true;            }            std::string pathElement(PATH, end);             if(pathElement == "")                pathElement = ".";             fs::path f = fs::path(pathElement) / program;             if(access(f.string().c_str(), X_OK) == 0)                return true;             PATH = end + 1;        } while(!endFound);    }     return false;} vector<string> SplitArguments(std::string str){    bool backslash = false;    bool quote = false;    bool begun = false;    vector<string> args;     for(char c : str)    {        if(!backslash && !quote && isspace(c))        {            begun = false;        }        else if(!backslash && c == '"')        {            quote = !quote;            if(quote && !begun)            {                args.emplace_back();                begun = true;            }        }        else if(!backslash && c == '\\')        {            backslash = true;        }        else        {            backslash = false;             if(!begun)            {                args.emplace_back();                begun = true;            }            args.back() += c;        }    }     return args;} vector<string> SplitArguments(vector<string> strs){    vector<string> args;    for(string str : strs)    {        vector<string> args1 = SplitArguments(str);        args.insert(args.end(), args1.begin(), args1.end());    }    return args;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t