| Yifan Hong | af766e6 | 2021-06-14 13:24:19 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2021 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #pragma once | 
|  | 18 |  | 
|  | 19 | #include <optional> | 
|  | 20 | #include <ostream> | 
|  | 21 | #include <string> | 
|  | 22 | #include <variant> | 
|  | 23 | #include <vector> | 
|  | 24 |  | 
|  | 25 | #include <android-base/macros.h> | 
|  | 26 | #include <android-base/result.h> | 
|  | 27 | #include <android-base/unique_fd.h> | 
|  | 28 |  | 
|  | 29 | /** | 
|  | 30 | * Log a lot more information about host-device binder communication, when debugging issues. | 
|  | 31 | */ | 
|  | 32 | #define SHOULD_LOG_HOST false | 
|  | 33 |  | 
|  | 34 | #if SHOULD_LOG_HOST | 
|  | 35 | #define LOG_HOST(...) ALOGI(__VA_ARGS__) | 
|  | 36 | #else | 
|  | 37 | #define LOG_HOST(...) ALOGV(__VA_ARGS__) // for type checking | 
|  | 38 | #endif | 
|  | 39 |  | 
|  | 40 | namespace android { | 
|  | 41 |  | 
|  | 42 | struct CommandResult { | 
|  | 43 | std::optional<int32_t> exitCode; | 
|  | 44 | std::optional<int32_t> signal; | 
|  | 45 | std::optional<pid_t> pid; | 
|  | 46 | std::string stdout; | 
|  | 47 | std::string stderr; | 
|  | 48 |  | 
|  | 49 | android::base::unique_fd outPipe; | 
|  | 50 | android::base::unique_fd errPipe; | 
|  | 51 |  | 
|  | 52 | CommandResult() = default; | 
|  | 53 | CommandResult(CommandResult&& other) noexcept { (*this) = std::move(other); } | 
|  | 54 | CommandResult& operator=(CommandResult&& other) noexcept { | 
|  | 55 | std::swap(exitCode, other.exitCode); | 
|  | 56 | std::swap(signal, other.signal); | 
|  | 57 | std::swap(pid, other.pid); | 
|  | 58 | std::swap(stdout, other.stdout); | 
|  | 59 | std::swap(stderr, other.stderr); | 
|  | 60 | return *this; | 
|  | 61 | } | 
|  | 62 | ~CommandResult(); | 
|  | 63 | [[nodiscard]] std::string toString() const; | 
|  | 64 |  | 
|  | 65 | [[nodiscard]] bool stdoutEndsWithNewLine() const { | 
|  | 66 | return !stdout.empty() && stdout.back() == '\n'; | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | private: | 
|  | 70 | DISALLOW_COPY_AND_ASSIGN(CommandResult); | 
|  | 71 | }; | 
|  | 72 |  | 
|  | 73 | std::ostream& operator<<(std::ostream& os, const CommandResult& res); | 
|  | 74 |  | 
|  | 75 | // Execute a command using tokens specified in @a argStringVec. | 
|  | 76 | // | 
|  | 77 | // @a end is a predicate checked periodically when the command emits any output to stdout or | 
|  | 78 | // stderr. When it is evaluated to true, the function returns immediately even though | 
|  | 79 | // the child process has not been terminated. The function also assumes that, after @a end | 
|  | 80 | // is evaluated to true, the child process does not emit any other messages. | 
|  | 81 | // If this is not the case, caller to execute() must handle these I/O in the pipes in the returned | 
|  | 82 | // CommandResult object. Otherwise the child program may hang on I/O. | 
|  | 83 | // | 
|  | 84 | // If @a end is nullptr, it is equivalent to a predicate that always returns false. In this | 
|  | 85 | // case, execute() returns after the child process is terminated. | 
|  | 86 | // | 
|  | 87 | // If @a end is evaluated to true, and execute() returns with the child process running, | 
|  | 88 | // the returned CommandResult has pid, outPipe, and errPipe set. In this case, the caller is | 
|  | 89 | // responsible for holding the returned CommandResult. When the CommandResult object is destroyed, | 
|  | 90 | // the child process is killed. | 
|  | 91 | // | 
|  | 92 | // On the other hand, execute() returns with the child process terminated, either exitCode or signal | 
|  | 93 | // is set. | 
|  | 94 | // | 
|  | 95 | // If the parent process has encountered any errors for system calls, return ExecuteError with | 
|  | 96 | // the proper errno set. | 
|  | 97 | android::base::Result<CommandResult> execute(std::vector<std::string> argStringVec, | 
|  | 98 | const std::function<bool(const CommandResult&)>& end); | 
|  | 99 | } // namespace android |