1 // Copyright (C) 2022 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #pragma once 15 16 #include <atomic> 17 #include <chrono> 18 #include <condition_variable> 19 #include <cstdio> 20 #include <functional> 21 #include <future> 22 #include <istream> 23 #include <memory> 24 #include <mutex> 25 #include <optional> 26 #include <string> 27 #include <vector> 28 29 #include "aemu/base/streams/RingStreambuf.h" 30 #include "aemu/base/ThreadAnnotations.h" 31 32 namespace android { 33 namespace base { 34 35 class Command; 36 37 using android::base::streams::RingStreambuf; 38 using CommandArguments = std::vector<std::string>; 39 using Pid = int; 40 using ProcessExitCode = int; 41 42 /** 43 * Represents a process running within the operating system. 44 */ 45 class Process { 46 public: 47 virtual ~Process() = default; 48 49 /** 50 * @return The process ID (PID) of the process, or -1 if invalid. 51 */ pid()52 Pid pid() const { return mPid; }; 53 54 /** 55 * @return The name of the process executable. Note that this information 56 * might not be immediately available, especially shortly after 57 * the process has been started. 58 */ 59 virtual std::string exe() const = 0; 60 61 /** 62 * Retrieves the exit code of the process. This method will block until 63 * the process has finished or is detached. 64 * 65 * @return The process exit code. This can return INT_MIN in case of 66 * failures retrieving the exit code. 67 */ 68 ProcessExitCode exitCode() const; 69 70 /** 71 * Forcibly terminates the process (similar to sending SIGKILL). 72 * 73 * @return True if the process was successfully terminated, false otherwise. 74 */ 75 virtual bool terminate() = 0; 76 77 /** 78 * Checks if the process is currently alive according to the operating 79 * system. 80 * 81 * @return True if the process is alive, false otherwise. 82 */ 83 virtual bool isAlive() const = 0; 84 85 /** 86 * Waits for the process to complete, or until the specified timeout 87 * duration has elapsed. 88 * 89 * @param timeout_duration The maximum duration to wait for process 90 * completion. 91 * @return A std::future_status value indicating whether the wait 92 * completed due to process termination or timeout. 93 */ wait_for(const std::chrono::milliseconds timeout_duration)94 virtual std::future_status wait_for( 95 const std::chrono::milliseconds timeout_duration) const { 96 return wait_for_kernel(timeout_duration); 97 } 98 99 /** 100 * Waits for the process to complete, or until the specified time point 101 * has been reached. 102 * 103 * @tparam Clock The clock type used for the timeout. 104 * @tparam Duration The duration type used for the timeout. 105 * @param timeout_time The time point at which the wait should timeout. 106 * @return A std::future_status value indicating whether the wait 107 * completed due to process termination or timeout. 108 */ 109 template <class Clock, class Duration> wait_until(const std::chrono::time_point<Clock,Duration> & timeout_time)110 std::future_status wait_until( 111 const std::chrono::time_point<Clock, Duration>& timeout_time) 112 const { 113 return wait_for(timeout_time - std::chrono::steady_clock::now()); 114 }; 115 116 bool operator==(const Process& rhs) const { return (mPid == rhs.mPid); } 117 bool operator!=(const Process& rhs) const { return !operator==(rhs); } 118 119 /** 120 * Retrieves a Process object representing the process with the given PID. 121 * 122 * @param pid The process ID (PID) to search for. 123 * @return A unique pointer to a Process object representing the process, 124 * or nullptr if no such process exists. 125 */ 126 static std::unique_ptr<Process> fromPid(Pid pid); 127 128 /** 129 * Retrieves a list of Process objects representing processes whose 130 * executable name contains the specified name substring. 131 * 132 * Note: There might be a delay between the creation of a process and its 133 * appearance in the process list. This delay can vary depending on the 134 * operating system and system load. 135 * 136 * @param name The name substring to search for in process names. 137 * @return A vector of unique pointers to Process objects representing the 138 * matching processes. If no matching processes are found, the 139 * vector will be empty. 140 */ 141 static std::vector<std::unique_ptr<Process>> fromName(std::string name); 142 143 /** 144 * @return A unique pointer to a Process object representing the current 145 * process. 146 */ 147 static std::unique_ptr<Process> me(); 148 149 protected: 150 /** 151 * Retrieves the exit code of the process without blocking. 152 * 153 * @return An optional containing the process exit code if available, 154 * or std::nullopt if the process is still running or the exit 155 * code cannot be retrieved. 156 */ 157 virtual std::optional<ProcessExitCode> getExitCode() const = 0; 158 159 /** 160 * Waits for the process to complete using an operating system-level call, 161 * without using any additional polling mechanisms. 162 * 163 * @param timeout_duration The maximum duration to wait for process 164 * completion. 165 * @return A std::future_status value indicating whether the wait 166 * completed due to process termination or timeout. 167 */ 168 virtual std::future_status wait_for_kernel( 169 const std::chrono::milliseconds timeout_duration) const = 0; 170 171 Pid mPid; 172 }; 173 174 /** 175 * Represents the output (stdout and stderr) of a process. 176 */ 177 class ProcessOutput { 178 public: 179 virtual ~ProcessOutput() = default; 180 181 /** 182 * Consumes the entire output stream and returns it as a string. 183 * 184 * @return The entire process output as a string. 185 */ 186 virtual std::string asString() = 0; 187 188 /** 189 * Provides access to the output stream, which can be used to read the 190 * process output incrementally. This method may block until data is 191 * available from the child process. 192 * 193 * @return A reference to the output stream. 194 */ 195 virtual std::istream& asStream() = 0; 196 }; 197 198 /** 199 * The ProcessOverseer class is responsible for monitoring a child process 200 * and capturing its output (stdout and stderr). 201 */ 202 class ProcessOverseer { 203 public: 204 virtual ~ProcessOverseer() = default; 205 206 /** 207 * Starts monitoring the child process and capturing its output. 208 * 209 * The overseer should: 210 * - Write captured output to the provided `out` and `err` 211 * RingStreambuf objects. 212 * - Close the RingStreambuf objects when the corresponding output streams 213 * are closed by the child process. 214 * - Return from this method when it can no longer read or write from the 215 * child process's stdout and stderr. 216 * 217 * @param out The RingStreambuf object to write captured stdout output to. 218 * @param err The RingStreambuf object to write captured stderr output to. 219 */ 220 virtual void start(RingStreambuf* out, RingStreambuf* err) = 0; 221 222 /** 223 * Stops monitoring the child process and releases any resources held by 224 * the overseer. 225 * 226 * After this method returns: 227 * - No further writes should be made to the `out` and `err` 228 * RingStreambuf objects. 229 * - All resources associated with the overseer should be released. 230 * - Calling the `start` method again should result in an error or return 231 * immediately. 232 */ 233 virtual void stop() = 0; 234 }; 235 236 /** 237 * A ProcessOverseer implementation that does nothing. This can be used for 238 * detached processes or in testing scenarios where process output monitoring 239 * is not required. 240 */ 241 class NullOverseer : public ProcessOverseer { 242 public: start(RingStreambuf * out,RingStreambuf * err)243 virtual void start(RingStreambuf* out, RingStreambuf* err) override {} stop()244 virtual void stop() override {} 245 }; 246 247 /** 248 * Represents a running process that can be interacted with, such as reading 249 * its output or terminating it. 250 * 251 * You typically obtain an ObservableProcess object by executing a Command. 252 * 253 * Example: 254 * ```cpp 255 * auto p = Command::create({"ls"}).execute(); 256 * if (p->exitCode() == 0) { 257 * auto list = p->out()->asString(); 258 * } 259 * ``` 260 */ 261 class ObservableProcess : public Process { 262 public: 263 // Kills the process.. 264 virtual ~ObservableProcess(); 265 266 /** 267 * @return A pointer to the ProcessOutput object representing the child 268 * process's standard output (stdout), or nullptr if the process 269 * was started in detached mode. 270 */ out()271 ProcessOutput* out() { return mStdOut.get(); }; 272 273 /** 274 * @return A pointer to the ProcessOutput object representing the child 275 * process's standard error (stderr), or nullptr if the process 276 * was started in detached mode. 277 */ err()278 ProcessOutput* err() { return mStdErr.get(); }; 279 280 /** 281 * Detaches the process overseer, stopping the monitoring of the child 282 * process's output and preventing the process from being automatically 283 * terminated when the ObservableProcess object goes out of scope. 284 * 285 * After calling this method: 286 * - You will no longer be able to read the child process's stdout and 287 * stderr. 288 * - The child process will continue running even after the 289 * ObservableProcess object is destroyed. 290 */ 291 void detach(); 292 293 std::future_status wait_for( 294 const std::chrono::milliseconds timeout_duration) const override; 295 296 protected: 297 /** 298 * Subclasses should implement this method to handle the actual process 299 * creation and launch. 300 * 301 * @param args The command line arguments to pass to the child process. 302 * @param captureOutput Whether to capture the child process's output 303 * (stdout and stderr). 304 * @return An optional containing the PID of the newly created process if 305 * successful, or std::nullopt if process creation failed. 306 */ 307 virtual std::optional<Pid> createProcess(const CommandArguments& args, 308 bool captureOutput, 309 bool replace) = 0; 310 311 /** 312 * Creates the ProcessOverseer object responsible for monitoring the child 313 * process and capturing its output. 314 * 315 * @return A unique pointer to the created ProcessOverseer object. 316 */ 317 virtual std::unique_ptr<ProcessOverseer> createOverseer() = 0; 318 319 // True if no overseer is needed 320 bool mDeamon{false}; 321 322 // True if we want to inherit all the fds/handles. 323 bool mInherit{false}; 324 325 private: 326 void runOverseer(); 327 328 std::unique_ptr<ProcessOverseer> mOverseer; 329 std::unique_ptr<std::thread> mOverseerThread; GUARDED_BY(mOverseerMutex)330 bool mOverseerActive GUARDED_BY(mOverseerMutex) {false}; 331 mutable std::mutex mOverseerMutex; 332 mutable std::condition_variable mOverseerCv; 333 334 std::unique_ptr<ProcessOutput> mStdOut; 335 std::unique_ptr<ProcessOutput> mStdErr; 336 337 friend Command; 338 }; 339 } // namespace base 340 } // namespace android 341