diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-11-02 17:50:11 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-11-02 17:50:11 -0500 |
commit | 8871308c48dd59046c0e1e318486be04ff20c278 (patch) | |
tree | 3238a311c2df00b7e6aae235dfd89fc31669c0d2 /hscript/util.cc | |
parent | ff2044f3ce53f7c2bb7b34588adad0490bd3a808 (diff) | |
download | horizon-8871308c48dd59046c0e1e318486be04ff20c278.tar.gz horizon-8871308c48dd59046c0e1e318486be04ff20c278.tar.bz2 horizon-8871308c48dd59046c0e1e318486be04ff20c278.tar.xz horizon-8871308c48dd59046c0e1e318486be04ff20c278.zip |
hscript: Factor out FS exec stuff to run_command function
Diffstat (limited to 'hscript/util.cc')
-rw-r--r-- | hscript/util.cc | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/hscript/util.cc b/hscript/util.cc index 4a991c5..21d2356 100644 --- a/hscript/util.cc +++ b/hscript/util.cc @@ -11,12 +11,18 @@ */ #include <string> +#include <vector> #ifdef HAVE_LIBCURL -# include <cstdio> /* fopen */ -# include <cstring> /* strerror */ -# include <curl/curl.h> /* curl_* */ -# include <errno.h> /* errno */ +# include <cstdio> /* fopen */ +# include <cstring> /* strerror */ +# include <curl/curl.h> /* curl_* */ +# include <errno.h> /* errno */ #endif /* HAVE_LIBCURL */ +#ifdef HAS_INSTALL_ENV +# include <spawn.h> /* posix_spawnp */ +# include <sys/wait.h> /* waitpid, W* */ +# include <unistd.h> /* environ */ +#endif #include "util/output.hh" #ifdef HAVE_LIBCURL @@ -59,3 +65,51 @@ bool download_file(const std::string &url, const std::string &path) { return false; } #endif /* HAVE_LIBCURL */ + +int run_command(const std::string &cmd, const std::vector<std::string> &args) { +#ifdef HAS_INSTALL_ENV + const char **argv = new const char*[args.size() + 2]; + pid_t child; + int status; + + argv[0] = cmd.c_str(); + for(unsigned long index = 0; index < args.size(); index++) { + argv[index + 1] = args.at(index).c_str(); + } + argv[args.size() + 1] = nullptr; + + status = posix_spawnp(&child, cmd.c_str(), nullptr, nullptr, + const_cast<char * const *>(argv), environ); + if(status != 0) { + /* extremely unlikely failure case */ + output_error(cmd, "cannot fork", strerror(status)); + delete[] argv; + return -1; + } + + delete[] argv; + + if(waitpid(child, &status, 0) == -1) { + /* unlikely failure case */ + output_error(cmd, "waitpid", strerror(errno)); + return -1; + } + + if(!WIFEXITED(status)) { + output_error(cmd, "received fatal signal " + + std::to_string(WTERMSIG(status))); + return -1; + } + + if(WEXITSTATUS(status) != 0) { + output_error(cmd, "exited abnormally with status " + + std::to_string(WEXITSTATUS(status))); + return false; + } + + return WEXITSTATUS(status); +#else /* !HAS_INSTALL_ENV */ + output_error(cmd, "can't spawn processes in runtine environment"); + return -1; +#endif /* HAS_INSTALL_ENV */ +} |