summaryrefslogtreecommitdiff
path: root/hscript/util.cc
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2019-11-02 17:50:11 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2019-11-02 17:50:11 -0500
commit8871308c48dd59046c0e1e318486be04ff20c278 (patch)
tree3238a311c2df00b7e6aae235dfd89fc31669c0d2 /hscript/util.cc
parentff2044f3ce53f7c2bb7b34588adad0490bd3a808 (diff)
downloadhorizon-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.cc62
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 */
+}