diff options
author | 2022-07-05 16:09:05 +0100 | |
---|---|---|
committer | 2022-07-11 12:23:56 +0000 | |
commit | 42adb66b843a6fdb23979f53ee9eaf28723be518 (patch) | |
tree | 6331002e218015f4d83c68aa2e4ea6bb23d8b5f2 /runtime/exec_utils.h | |
parent | a9f772730fb493c5c3fa412fc0b91f2e9b8dbe17 (diff) |
Fix ExecUtils.WaitChildWithTimeoutFallback by adding a fallback.
`WaitChildWithTimeout` didn't work with old Linux kernels because it
uses a syscall `pidfd_open`, which was added in Linux 5.4.
This change adds a fallback implementation of `WaitChildWithTimeout`
that creates a thread to wait instead of relying on `pidfd_open`.
Also:
- Use android::base::unique_fd to hold pidfd so that the fd is
guaranteed to be closed.
- Allow timeout_sec to be negative, in which case it blocks until the
subprocess exits.
Bug: 229268202
Test: m test-art-host-gtest-art_runtime_tests
Change-Id: Iec3f21db135d9a8a3a915372253f1ff3e285e5cf
Merged-In: Iec3f21db135d9a8a3a915372253f1ff3e285e5cf
(cherry picked from commit 99bd8dd2bf8eac1a60bf65e442462753ed7f2147)
Diffstat (limited to 'runtime/exec_utils.h')
-rw-r--r-- | runtime/exec_utils.h | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/runtime/exec_utils.h b/runtime/exec_utils.h index ff90ebdfb3..79a12d770a 100644 --- a/runtime/exec_utils.h +++ b/runtime/exec_utils.h @@ -22,46 +22,46 @@ #include <string> #include <vector> +#include "android-base/unique_fd.h" + namespace art { // Wrapper on fork/execv to run a command in a subprocess. // These spawn child processes using the environment as it was set when the single instance // of the runtime (Runtime::Current()) was started. If no instance of the runtime was started, it // will use the current environment settings. - -bool Exec(const std::vector<std::string>& arg_vector, /*out*/ std::string* error_msg); -int ExecAndReturnCode(const std::vector<std::string>& arg_vector, /*out*/ std::string* error_msg); - -// Execute the command specified in `argv_vector` in a subprocess with a timeout. -// Returns the process exit code on success, -1 otherwise. -int ExecAndReturnCode(const std::vector<std::string>& arg_vector, - int timeout_sec, - /*out*/ bool* timed_out, - /*out*/ std::string* error_msg); - -// A wrapper class to make the functions above mockable. class ExecUtils { public: virtual ~ExecUtils() = default; virtual bool Exec(const std::vector<std::string>& arg_vector, - /*out*/ std::string* error_msg) const { - return art::Exec(arg_vector, error_msg); - } + /*out*/ std::string* error_msg) const; virtual int ExecAndReturnCode(const std::vector<std::string>& arg_vector, - /*out*/ std::string* error_msg) const { - return art::ExecAndReturnCode(arg_vector, error_msg); - } + /*out*/ std::string* error_msg) const; + // Executes the command specified in `arg_vector` in a subprocess with a timeout. + // If `timeout_sec` is negative, blocks until the subprocess exits. + // Returns the process exit code on success, -1 otherwise. + // Sets `timed_out` to true if the process times out, or false otherwise. virtual int ExecAndReturnCode(const std::vector<std::string>& arg_vector, int timeout_sec, /*out*/ bool* timed_out, - /*out*/ std::string* error_msg) const { - return art::ExecAndReturnCode(arg_vector, timeout_sec, timed_out, error_msg); - } + /*out*/ std::string* error_msg) const; + + protected: + virtual android::base::unique_fd PidfdOpen(pid_t pid) const; }; +inline bool Exec(const std::vector<std::string>& arg_vector, /*out*/ std::string* error_msg) { + return ExecUtils().Exec(arg_vector, error_msg); +} + +inline int ExecAndReturnCode(const std::vector<std::string>& arg_vector, + /*out*/ std::string* error_msg) { + return ExecUtils().ExecAndReturnCode(arg_vector, error_msg); +} + } // namespace art #endif // ART_RUNTIME_EXEC_UTILS_H_ |