From 5da56616cccf4e595ec6a556cf1aef40b37746e3 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 28 Aug 2021 18:59:29 +0200 Subject: Move sources to ... well, src ;) --- src/execute.cc | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/execute.cc (limited to 'src/execute.cc') diff --git a/src/execute.cc b/src/execute.cc new file mode 100644 index 0000000..bc4cd5f --- /dev/null +++ b/src/execute.cc @@ -0,0 +1,87 @@ +#include "execute.h" + +#include +#include +#include +#include +#include +#include + +/* +https://blog.famzah.net/2009/11/20/a-much-faster-popen-and-system-implementation-for-linux/ +https://github.com/famzah/popen-noshell/commit/1f9eaf4eeef348d1efe0f3c7fe8ab670653cfbb1 +https://blog.famzah.net/2018/12/19/posix_spawn-performance-benchmarks-and-usage-examples/ +https://stackoverflow.com/questions/4259629/what-is-the-difference-between-fork-and-vfork/5207945#5207945 + */ + + +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& args, + bool verbose) +{ + std::vector 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()); + std::cout << "Could not execute " << command << ": " << + strerror(errno) << "\n"; + _exit(1); // execv only returns if an error occurred + } + 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; +} -- cgit v1.2.3