From 8871308c48dd59046c0e1e318486be04ff20c278 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 2 Nov 2019 17:50:11 -0500 Subject: hscript: Factor out FS exec stuff to run_command function --- hscript/disk.cc | 47 ++++--------------------------------------- hscript/util.cc | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- hscript/util.hh | 11 ++++++++++ 3 files changed, 73 insertions(+), 47 deletions(-) diff --git a/hscript/disk.cc b/hscript/disk.cc index 35936ac..a814761 100644 --- a/hscript/disk.cc +++ b/hscript/disk.cc @@ -22,14 +22,13 @@ # include "util/filesystem.hh" # include /* udev_* */ # include /* ped_* */ -# include /* posix_spawnp */ # include /* mount */ # include /* stat */ # include /* S_* */ -# include /* waitpid, W* */ # include /* access */ #endif /* HAS_INSTALL_ENV */ #include "disk.hh" +#include "util.hh" #include "util/output.hh" using namespace Horizon::Keys; @@ -877,47 +876,9 @@ bool Filesystem::execute(ScriptOptions opts) const { } #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(argv), environ); - if(status != 0) { - /* extremely unlikely failure case */ - output_error("installfile:" + std::to_string(this->lineno()), - "fs: cannot fork", strerror(status)); - delete[] argv; - return false; - } - - delete[] argv; - - if(waitpid(child, &status, 0) == -1) { - /* unlikely failure case */ - output_error("installfile:" + std::to_string(this->lineno()), - "fs: waitpid", strerror(errno)); - return false; - } - - if(!WIFEXITED(status)) { - output_error("installfile:" + std::to_string(this->lineno()), - "fs: received fatal signal " + - std::to_string(WTERMSIG(status)) + " while running " + - cmd); - return false; - } - - if(WEXITSTATUS(status) != 0) { - output_error("installfile:" + std::to_string(this->lineno()), - "fs: " + cmd + " exited with status " + - std::to_string(WEXITSTATUS(status))); + if(run_command(cmd, args) != 0) { + output_error("installfile:" + std::to_string(line), + "fs: failed to create filesystem"); return false; } #endif /* HAS_INSTALL_ENV */ 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 +#include #ifdef HAVE_LIBCURL -# include /* fopen */ -# include /* strerror */ -# include /* curl_* */ -# include /* errno */ +# include /* fopen */ +# include /* strerror */ +# include /* curl_* */ +# include /* errno */ #endif /* HAVE_LIBCURL */ +#ifdef HAS_INSTALL_ENV +# include /* posix_spawnp */ +# include /* waitpid, W* */ +# include /* 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 &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(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 */ +} diff --git a/hscript/util.hh b/hscript/util.hh index d350cd3..47da022 100644 --- a/hscript/util.hh +++ b/hscript/util.hh @@ -14,6 +14,7 @@ #define HSCRIPT_UTIL_HH #include +#include /*! Download the contents of a URL to a path. * @param url The URL to download. @@ -22,4 +23,14 @@ */ bool download_file(const std::string &url, const std::string &path); +/*! Run a command. + * @param cmd The command to run. + * @param args Arguments to pass to the command. + * @returns 0 if the command exited normally with status 0, + * the exit code if the command exited abnormally, + * -1 if the command signalled. + * @note Status of the command is output using +output_error+. + */ +int run_command(const std::string &cmd, const std::vector &args); + #endif /* !HSCRIPT_UTIL_HH */ -- cgit v1.2.3-70-g09d2