diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2021-11-16 22:10:57 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-11-16 22:10:57 +0000 |
commit | 2a558bb3189bdbe94b869ea63a0302f39ce6e23e (patch) | |
tree | 176556c040011c9418fadf9f5ebd914151326999 | |
parent | 8f0be9e88f61da123e52b3e081355d9604c5326e (diff) | |
parent | 715a326305e04027093fdd7a980a8ef604dd8794 (diff) | |
download | build-tools-2a558bb3189bdbe94b869ea63a0302f39ce6e23e.tar.gz |
Merge "Replace interceptor starter with C++ binary"
-rw-r--r-- | interceptor/Android.bp | 8 | ||||
-rw-r--r-- | interceptor/interceptor | 66 | ||||
-rw-r--r-- | interceptor/interceptor.cc | 4 | ||||
-rw-r--r-- | interceptor/interceptor.h | 4 | ||||
-rw-r--r-- | interceptor/main.cc | 125 |
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()); +} |