diff options
author | Matthias Maennich <maennich@google.com> | 2021-11-08 20:39:35 +0000 |
---|---|---|
committer | Matthias Maennich <maennich@google.com> | 2021-11-09 18:46:21 +0000 |
commit | 097fc26187cbf9da7ca58183d4cd304f846d5823 (patch) | |
tree | 011c175947f60c8ee83cf4a6b7f9b2a46be00255 | |
parent | 215b405ae638b5d71345d9eba2ef41e7a81fdc90 (diff) | |
download | build-tools-097fc26187cbf9da7ca58183d4cd304f846d5823.tar.gz |
Interceptor: add helper functionality for env and args
Add some convenience argument and environment parsing into standard
containers to make them easier accessible. This might be bad for
performance and needs to be replaced later, but helps during initial
development.
Bug: 205577427
Signed-off-by: Matthias Maennich <maennich@google.com>
Change-Id: I6db40054c58a117dd5b3434bced85001ac037f81
-rw-r--r-- | interceptor/interceptor.cc | 44 | ||||
-rw-r--r-- | interceptor/interceptor.h | 38 |
2 files changed, 82 insertions, 0 deletions
diff --git a/interceptor/interceptor.cc b/interceptor/interceptor.cc index 64cdb76..f078e42 100644 --- a/interceptor/interceptor.cc +++ b/interceptor/interceptor.cc @@ -19,6 +19,13 @@ #include <dlfcn.h> #include <unistd.h> +#include <filesystem> +#include <string> +#include <string_view> +#include <utility> + +namespace fs = std::filesystem; + // OVERLOADS for LD_PRELOAD USE // Intercept execve calls, for that capture the original execve call @@ -29,3 +36,40 @@ int execve(const char* filename, char* const argv[], char* const envp[]) { return old_execve(filename, argv, envp); } } // extern "C" + +// LIBRARY IMPLEMENTATION + +namespace interceptor { + +Command::Command(const char* program, char* const argv[], char* const envp[]) + : program_(program), cwd_(fs::current_path()), argv_(argv), envp_(envp) {} + +const ArgVec& Command::args() const { + if (!args_.has_value()) { + args_ = ArgVec(); + for (auto current_arg = argv_; *current_arg; ++current_arg) { + args_->emplace_back(*current_arg); + } + } + return *args_; +} + +const EnvMap& Command::env() const { + if (!env_.has_value()) { + env_ = EnvMap(); + for (auto current_env = envp_; *current_env; ++current_env) { + const std::string_view s(*current_env); + const auto pos = s.find('='); + if (pos == EnvMap::key_type::npos) { + continue; + } + env_->emplace(s.substr(0, pos), s.substr(pos + 1)); + } + } + return *env_; +} + +const std::string& Command::program() const { + return program_; +} +} // namespace interceptor diff --git a/interceptor/interceptor.h b/interceptor/interceptor.h index 062ed53..f69dae7 100644 --- a/interceptor/interceptor.h +++ b/interceptor/interceptor.h @@ -13,3 +13,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include <optional> +#include <string> +#include <unordered_map> +#include <vector> + +namespace interceptor { + +// Some type definitions to gain some type safety +using ArgVec = std::vector<std::string>; +using EnvMap = std::unordered_map<std::string, std::string>; + +// Command abstraction +// +// This is a utility container to keep program, args and env in an accessible +// fashion. Most data structures are created lazily. +class Command { + public: + Command(const char* program, char* const argv[], char* const envp[]); + + const std::string& program() const; + const ArgVec& args() const; + const EnvMap& env() const; + + char* const* envp() const { return envp_; }; + + private: + std::string program_; + std::string cwd_; + + char* const* argv_; + char* const* envp_; + + mutable std::optional<ArgVec> args_; + mutable std::optional<EnvMap> env_; +}; + +} // namespace interceptor |