Skip to content
Snippets Groups Projects
Commit 6b371d2d authored by Recolic's avatar Recolic :house_with_garden:
Browse files

Merge branch 'tmp_shell_run' into 'master'

shell_run

See merge request !2
parents fcd760c4 8910127e
No related branches found
No related tags found
1 merge request!2shell_run
Pipeline #1065 passed with stage
in 1 minute and 19 seconds
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <list> #include <list>
#include <functional> #include <functional>
#include <chrono> #include <chrono>
#include <future>
#include <stdexcept> #include <stdexcept>
namespace rlib { namespace rlib {
...@@ -44,7 +45,18 @@ namespace rlib { ...@@ -44,7 +45,18 @@ namespace rlib {
auto begin = std::chrono::high_resolution_clock::now(); auto begin = std::chrono::high_resolution_clock::now();
f(std::forward<Args>(args) ...); f(std::forward<Args>(args) ...);
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
return ::std::chrono::duration<double>(end - begin).count(); return std::chrono::duration<double>(end - begin).count();
}
template <typename Func, typename... Args>
static inline auto timeout(int timeout_seconds, Func&& func, Args&&... args) {
using ReturnType = decltype(func(args...));
auto future = std::async(std::launch::async, std::forward<Func>(func), std::forward<Args>(args)...);
if (future.wait_for(std::chrono::seconds(timeout_seconds)) == std::future_status::timeout) {
return ReturnType {};
}
return future.get();
} }
template <class Func, typename... Args> template <class Func, typename... Args>
......
...@@ -2,18 +2,18 @@ ...@@ -2,18 +2,18 @@
#define RLIB_UNIX_HANDY_HPP_ #define RLIB_UNIX_HANDY_HPP_
#include <unistd.h> #include <unistd.h>
#include <string>
#include <sys/socket.h> #include <stdexcept>
#include <sys/types.h> #include <vector>
#include <netdb.h>
#include <rlib/scope_guard.hpp>
#include <rlib/string.hpp>
#include <rlib/sys/os.hpp> #include <rlib/sys/os.hpp>
#if RLIB_OS_ID == OS_WINDOWS #if RLIB_OS_ID == OS_WINDOWS
#error rlib/sys/unix_handy.hpp is not for Windows. #error rlib/sys/unix_handy.hpp is not for Windows.
#endif #endif
// For shell_run
#include <sstream>
namespace rlib { namespace rlib {
// args DOES NOT contain the "$0". // args DOES NOT contain the "$0".
inline void execs(std::string path, std::vector<std::string> args) { inline void execs(std::string path, std::vector<std::string> args) {
...@@ -28,10 +28,46 @@ namespace rlib { ...@@ -28,10 +28,46 @@ namespace rlib {
::execv(path.c_str(), arr); ::execv(path.c_str(), arr);
} }
struct shell_result {
int status;
std::string stdout_;
};
// Execute command with shell and capture stdout.
// Note: stderr would be discarded. Use `2>&1` if needed.
shell_result shell_run(const std::string& command) {
char buffer[128];
FILE *pipe = popen(command.c_str(), "r");
if (!pipe) {
return {-errno, ""};
}
shell_result res;
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
res.stdout_ += buffer;
}
res.status = pclose(pipe);
res.status = WIFEXITED(res.status) ? WEXITSTATUS(res.status) : -errno;
return res;
}
auto get_shell_name() {
return shell_run("echo -n $0").stdout_;
}
} }
// Deprecated. Use sys/sio.hpp // Deprecated. Use sys/sio.hpp
#if 1+1 == 4 #if 1+1 == 4
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <rlib/scope_guard.hpp>
#include <rlib/string.hpp>
namespace rlib { namespace rlib {
namespace impl { namespace impl {
using rlib::literals::operator""_format; using rlib::literals::operator""_format;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment