From f85138a27d1916ad42aedacee5daa48a72e75730 Mon Sep 17 00:00:00 2001 From: Recolic <git@me.recolic.net> Date: Thu, 6 Mar 2025 16:27:31 -0800 Subject: [PATCH 1/5] . --- functional.hpp | 13 ++++++++++++- sys/unix_handy.hpp | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/functional.hpp b/functional.hpp index 891230a..26d4946 100644 --- a/functional.hpp +++ b/functional.hpp @@ -44,7 +44,18 @@ namespace rlib { auto begin = std::chrono::high_resolution_clock::now(); f(std::forward<Args>(args) ...); 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(double 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> diff --git a/sys/unix_handy.hpp b/sys/unix_handy.hpp index c65110b..bcab553 100644 --- a/sys/unix_handy.hpp +++ b/sys/unix_handy.hpp @@ -2,18 +2,17 @@ #define RLIB_UNIX_HANDY_HPP_ #include <unistd.h> - -#include <sys/socket.h> -#include <sys/types.h> -#include <netdb.h> -#include <rlib/scope_guard.hpp> -#include <rlib/string.hpp> +#include <string> +#include <stdexcept> #include <rlib/sys/os.hpp> #if RLIB_OS_ID == OS_WINDOWS #error rlib/sys/unix_handy.hpp is not for Windows. #endif +// For shell_run +#include <sstream> + namespace rlib { // args DOES NOT contain the "$0". inline void execs(std::string path, std::vector<std::string> args) { @@ -28,10 +27,42 @@ namespace rlib { ::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(status) ? WEXITSTATUS(status) : -errno; + + return res; + } } // Deprecated. Use sys/sio.hpp #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 impl { using rlib::literals::operator""_format; -- GitLab From a10a9f4afdd189e9456c281c24fedf83863c3e86 Mon Sep 17 00:00:00 2001 From: Recolic <git@me.recolic.net> Date: Thu, 6 Mar 2025 16:33:38 -0800 Subject: [PATCH 2/5] . --- functional.hpp | 1 + sys/unix_handy.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/functional.hpp b/functional.hpp index 26d4946..138a055 100644 --- a/functional.hpp +++ b/functional.hpp @@ -9,6 +9,7 @@ #include <list> #include <functional> #include <chrono> +#include <future> #include <stdexcept> namespace rlib { diff --git a/sys/unix_handy.hpp b/sys/unix_handy.hpp index bcab553..7ebf7c9 100644 --- a/sys/unix_handy.hpp +++ b/sys/unix_handy.hpp @@ -50,7 +50,7 @@ namespace rlib { } res.status = pclose(pipe); - res.status = WIFEXITED(status) ? WEXITSTATUS(status) : -errno; + res.status = WIFEXITED(res.status) ? WEXITSTATUS(res.status) : -errno; return res; } -- GitLab From e87a5b9eefdec84a70c0a6a8f83e20c714c3abb8 Mon Sep 17 00:00:00 2001 From: Recolic <git@me.recolic.net> Date: Thu, 6 Mar 2025 16:34:56 -0800 Subject: [PATCH 3/5] . --- sys/unix_handy.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/unix_handy.hpp b/sys/unix_handy.hpp index 7ebf7c9..f18b618 100644 --- a/sys/unix_handy.hpp +++ b/sys/unix_handy.hpp @@ -54,6 +54,10 @@ namespace rlib { return res; } + + auto get_shell_name() { + return shell_run("echo $0").stdout_; + } } // Deprecated. Use sys/sio.hpp -- GitLab From baf3471e4dae6fb5a1a965ee6b69c438541be5dd Mon Sep 17 00:00:00 2001 From: Recolic <git@me.recolic.net> Date: Thu, 6 Mar 2025 16:37:00 -0800 Subject: [PATCH 4/5] . --- sys/unix_handy.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/unix_handy.hpp b/sys/unix_handy.hpp index f18b618..faedefd 100644 --- a/sys/unix_handy.hpp +++ b/sys/unix_handy.hpp @@ -4,6 +4,7 @@ #include <unistd.h> #include <string> #include <stdexcept> +#include <vector> #include <rlib/sys/os.hpp> #if RLIB_OS_ID == OS_WINDOWS @@ -56,7 +57,7 @@ namespace rlib { } auto get_shell_name() { - return shell_run("echo $0").stdout_; + return shell_run("echo -n $0").stdout_; } } -- GitLab From 5fb20249909628f96575ee278e1cd9f3bba26a16 Mon Sep 17 00:00:00 2001 From: Recolic <git@me.recolic.net> Date: Thu, 6 Mar 2025 16:38:32 -0800 Subject: [PATCH 5/5] . --- functional.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functional.hpp b/functional.hpp index 138a055..8e60871 100644 --- a/functional.hpp +++ b/functional.hpp @@ -48,7 +48,7 @@ namespace rlib { return std::chrono::duration<double>(end - begin).count(); } template <typename Func, typename... Args> - static inline auto timeout(double timeout_seconds, Func&& func, Args&&... 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)...); -- GitLab