summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-11-16 22:10:57 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-11-16 22:10:57 +0000
commit2a558bb3189bdbe94b869ea63a0302f39ce6e23e (patch)
tree176556c040011c9418fadf9f5ebd914151326999
parent8f0be9e88f61da123e52b3e081355d9604c5326e (diff)
parent715a326305e04027093fdd7a980a8ef604dd8794 (diff)
downloadbuild-tools-2a558bb3189bdbe94b869ea63a0302f39ce6e23e.tar.gz
Merge "Replace interceptor starter with C++ binary"
-rw-r--r--interceptor/Android.bp8
-rw-r--r--interceptor/interceptor66
-rw-r--r--interceptor/interceptor.cc4
-rw-r--r--interceptor/interceptor.h4
-rw-r--r--interceptor/main.cc125
5 files changed, 134 insertions, 73 deletions
diff --git a/interceptor/Android.bp b/interceptor/Android.bp
index eaf0dab..49d249b 100644
--- a/interceptor/Android.bp
+++ b/interceptor/Android.bp
@@ -7,8 +7,10 @@ cc_library_host_shared {
],
}
-sh_binary_host {
+cc_binary_host {
name: "interceptor",
- src: "interceptor",
+ srcs: ["main.cc",],
+ static_libs: [
+ "libc++fs",
+ ],
}
-
diff --git a/interceptor/interceptor b/interceptor/interceptor
deleted file mode 100644
index 54ab449..0000000
--- a/interceptor/interceptor
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh
-#
-# Copyright (C) 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-set -e
-
-while [ $# -gt 0 ]; do
- case $1 in
- --)
- shift
- break
- ;;
- -l|--command-log)
- COMMAND_LOG=$2
- shift # past argument
- shift # past value
- ;;
- *)
- break
- ;;
- esac
-done
-
-# Handle the command log
-#
-# Due to the interceptor being active from any working directory, we need to
-# capture the current working directory and make the command log path absolute.
-if [ -n "$COMMAND_LOG" ]; then
- export INTERCEPTOR_command_log=$(realpath $COMMAND_LOG)
- echo "[" > "$INTERCEPTOR_command_log"
-fi
-
-# If ROOT_DIR is not set, assume the current working directory is it
-if [ -z "$ROOT_DIR" ]; then
- export INTERCEPTOR_root_dir=$(pwd)
-else
- export INTERCEPTOR_root_dir=$ROOT_DIR
-fi
-
-# Discover the interceptor preload library
-export LD_PRELOAD=$(realpath $(dirname $(readlink -f $0))/../lib64/libinterceptor.so)
-if [ ! -x "$LD_PRELOAD" ]; then
- echo "Interceptor library can't be found at: $LD_PRELOAD" >&2
- exit 1
-fi
-
-# Spawn the actual command in a subshell to capture possibly set environment
-# variables, e.g. `interceptor MY_ENV=123 command_to_execute`
-sh -c "$*"
-
-if [ -n "$COMMAND_LOG" ]; then
- echo "]" >> "$INTERCEPTOR_command_log"
-fi
diff --git a/interceptor/interceptor.cc b/interceptor/interceptor.cc
index 801b8ec..caadfa0 100644
--- a/interceptor/interceptor.cc
+++ b/interceptor/interceptor.cc
@@ -38,10 +38,6 @@
namespace fs = std::filesystem;
-// Options passed via environment variables from the interceptor starter
-constexpr static auto ENV_command_log = "INTERCEPTOR_command_log";
-constexpr static auto ENV_root_dir = "INTERCEPTOR_root_dir";
-
// UTILITY function declarations
// process applicable calls (i.e. programs that we might be able to handle)
diff --git a/interceptor/interceptor.h b/interceptor/interceptor.h
index 3f738b2..d7a38a9 100644
--- a/interceptor/interceptor.h
+++ b/interceptor/interceptor.h
@@ -20,6 +20,10 @@
#include <unordered_map>
#include <vector>
+// Options passed via environment variables from the interceptor starter
+constexpr static auto ENV_command_log = "INTERCEPTOR_command_log";
+constexpr static auto ENV_root_dir = "INTERCEPTOR_root_dir";
+
namespace interceptor {
// Some type definitions to gain some type safety
diff --git a/interceptor/main.cc b/interceptor/main.cc
new file mode 100644
index 0000000..ae3d623
--- /dev/null
+++ b/interceptor/main.cc
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <cstdlib>
+#include <filesystem>
+#include <fstream>
+#include <iostream>
+#include <optional>
+#include <sstream>
+
+#include "interceptor.h"
+
+namespace fs = std::filesystem;
+
+struct Options {
+ std::string command_line;
+ std::optional<fs::path> command_log;
+};
+
+static Options parse_args(int argc, char* argv[]) {
+ Options result;
+
+ while (1) {
+ static struct option long_options[] = {{"command-log", required_argument, 0, 'l'},
+ {0, 0, 0, 0}};
+ /* getopt_long stores the option index here. */
+ int option_index = 0;
+
+ auto c = getopt_long(argc, argv, "l:", long_options, &option_index);
+
+ /* Detect the end of the options. */
+ if (c == -1) break;
+
+ switch (c) {
+ case 'l':
+ result.command_log = fs::absolute(optarg);
+ break;
+
+ case '?':
+ /* getopt_long already printed an error message. */
+ break;
+
+ default:
+ abort();
+ }
+ }
+
+ std::stringstream ss;
+ if (optind < argc) {
+ while (optind < argc) {
+ ss << argv[optind++];
+ ss << ' ';
+ }
+ }
+ result.command_line = ss.str();
+
+ return result;
+}
+
+static void setup_interceptor_library_path() {
+ auto interceptor_library = fs::read_symlink("/proc/self/exe").parent_path().parent_path() /
+ "lib64" / "libinterceptor.so";
+ while (fs::is_symlink(interceptor_library))
+ interceptor_library = fs::read_symlink(interceptor_library);
+ if (!fs::is_regular_file(interceptor_library)) {
+ std::cerr << "Interceptor library could not be found!\n";
+ exit(1);
+ }
+ setenv("LD_PRELOAD", interceptor_library.c_str(), 1);
+}
+
+static void setup_root_dir() {
+ const auto root_dir = getenv("ROOT_DIR");
+ if (root_dir != nullptr)
+ setenv(ENV_root_dir, root_dir, 1);
+ else
+ setenv(ENV_root_dir, fs::current_path().c_str(), 1);
+}
+
+class CommandLog {
+ const decltype(Options::command_log) command_log_file_;
+
+ public:
+ CommandLog(decltype(command_log_file_) command_log_file)
+ : command_log_file_(std::move(command_log_file)) {
+ if (command_log_file_) {
+ setenv(ENV_command_log, command_log_file_->c_str(), 1);
+ std::ofstream command_log(command_log_file_->c_str(), std::ios_base::trunc);
+ command_log << "[\n";
+ }
+ }
+
+ ~CommandLog() {
+ if (command_log_file_) {
+ std::ofstream command_log(command_log_file_->c_str(), std::ios_base::app);
+ command_log << "]\n";
+ }
+ }
+};
+
+int main(int argc, char* argv[]) {
+ const auto& options = parse_args(argc, argv);
+
+ setup_interceptor_library_path();
+ setup_root_dir();
+
+ CommandLog command_log(options.command_log);
+
+ return std::system(options.command_line.c_str());
+}