summaryrefslogtreecommitdiff
path: root/execute.cc
diff options
context:
space:
mode:
Diffstat (limited to 'execute.cc')
-rw-r--r--execute.cc76
1 files changed, 76 insertions, 0 deletions
diff --git a/execute.cc b/execute.cc
new file mode 100644
index 0000000..cb96bc5
--- /dev/null
+++ b/execute.cc
@@ -0,0 +1,76 @@
+#include "execute.h"
+
+#include <unistd.h>
+#include <cstring>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <spawn.h>
+#include <iostream>
+
+namespace
+{
+int parent_waitpid(pid_t pid)
+{
+ int status;
+
+ if(waitpid(pid, &status, 0) != pid)
+ {
+ return 1;
+ }
+
+ return status;
+}
+} // namespace ::
+
+int execute(const std::string& command,
+ const std::vector<std::string>& args,
+ bool verbose)
+{
+ std::vector<const char*> argv;
+ argv.push_back(command.data());
+ for(const auto& arg : args)
+ {
+ argv.push_back(arg.data());
+ }
+ argv.push_back(nullptr);
+
+ if(verbose)
+ {
+ std::string cmd;
+ for(const auto& arg : argv)
+ {
+ if(arg == nullptr)
+ {
+ break;
+ }
+ if(!cmd.empty())
+ {
+ cmd += " ";
+ }
+ cmd += arg;
+ }
+
+ std::cout << cmd << "\n";
+ }
+
+#if 1
+ auto pid = vfork();
+ if(pid == 0)
+ {
+ execv(command.data(), (char**)argv.data());
+ }
+ auto ret = parent_waitpid(pid);
+#elif 0
+ pid_t pid;
+ if(posix_spawn(&pid, command.data(), nullptr, nullptr,
+ (char**)argv.data(), nullptr))
+ {
+ return 1;
+ }
+ auto ret = parent_waitpid(pid);
+#else
+ auto ret = system(cmd.data());
+#endif
+
+ return ret;
+}