summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Maennich <maennich@google.com>2021-11-08 20:39:35 +0000
committerMatthias Maennich <maennich@google.com>2021-11-09 18:46:21 +0000
commit097fc26187cbf9da7ca58183d4cd304f846d5823 (patch)
tree011c175947f60c8ee83cf4a6b7f9b2a46be00255
parent215b405ae638b5d71345d9eba2ef41e7a81fdc90 (diff)
downloadbuild-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.cc44
-rw-r--r--interceptor/interceptor.h38
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