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 | |
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')
-rw-r--r-- | hscript/disk.cc | 47 | ||||
-rw-r--r-- | hscript/util.cc | 62 | ||||
-rw-r--r-- | 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 <libudev.h> /* udev_* */ # include <parted/parted.h> /* ped_* */ -# include <spawn.h> /* posix_spawnp */ # include <sys/mount.h> /* mount */ # include <sys/stat.h> /* stat */ # include <sys/types.h> /* S_* */ -# include <sys/wait.h> /* waitpid, W* */ # include <unistd.h> /* 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<char * const *>(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 <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 */ +} 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 <string> +#include <vector> /*! 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<std::string> &args); + #endif /* !HSCRIPT_UTIL_HH */ |