summaryrefslogtreecommitdiff
path: root/hscript
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
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')
-rw-r--r--hscript/disk.cc47
-rw-r--r--hscript/util.cc62
-rw-r--r--hscript/util.hh11
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 */