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 // A process in that is running in the os. 43 class Process { 44 public: ~Process()45 virtual ~Process(){}; 46 47 // pid of the process, or -1 if it is invalid pid()48 Pid pid() const { return mPid; }; 49 50 // Name of the process, note this might not be 51 // immediately availabl. 52 virtual std::string exe() const = 0; 53 54 // The exit code of the process, this will block 55 // and wait until the process has finished or is detached. 56 // 57 // This can return INT_MIN in case of failures. 58 ProcessExitCode exitCode() const; 59 60 // Unconditionally cause the process to exit. (Kill -9 ..) 61 // Returns true if the process was terminated, false in case of failure. 62 virtual bool terminate() = 0; 63 64 // True if the pid is alive according to the os. 65 virtual bool isAlive() const = 0; 66 67 // Waits for process completion, returns if it is not finished for the 68 // specified timeout duration wait_for(const std::chrono::milliseconds timeout_duration)69 virtual std::future_status wait_for( 70 const std::chrono::milliseconds timeout_duration) const { 71 return wait_for_kernel(timeout_duration); 72 } 73 74 // Waits for process completion, returns if it is not finished until 75 // specified time point has been reached 76 template <class Clock, class Duration> wait_until(const std::chrono::time_point<Clock,Duration> & timeout_time)77 std::future_status wait_until( 78 const std::chrono::time_point<Clock, Duration>& timeout_time) 79 const { 80 return wait_for(timeout_time - std::chrono::steady_clock::now()); 81 }; 82 83 bool operator==(const Process& rhs) const { return (mPid == rhs.mPid); } 84 bool operator!=(const Process& rhs) const { return !operator==(rhs); } 85 86 // Retrieve the object from the given pid id. 87 static std::unique_ptr<Process> fromPid(Pid pid); 88 89 // Retrieve process with "name" in the process. 90 static std::vector<std::unique_ptr<Process>> fromName(std::string name); 91 92 // Retrieve myself. 93 static std::unique_ptr<Process> me(); 94 95 protected: 96 // Return the exit code of the process, this should not block 97 virtual std::optional<ProcessExitCode> getExitCode() const = 0; 98 99 // Wait until this process is finished, by using an os level 100 // call. 101 virtual std::future_status wait_for_kernel( 102 const std::chrono::milliseconds timeout_duration) const = 0; 103 104 Pid mPid; 105 }; 106 107 // Output of the process. 108 class ProcessOutput { 109 public: 110 virtual ~ProcessOutput() = default; 111 112 // Consumes the whole stream, and returns a string. 113 virtual std::string asString() = 0; 114 115 // Returns a stream, that will block until data 116 // from the child is available. 117 virtual std::istream& asStream() = 0; 118 }; 119 120 // A process overseer is responsible for observering the process: 121 // It is watching writes to std_err & std_out and passes them 122 // on to a RingStreambuf 123 class ProcessOverseer { 124 public: 125 virtual ~ProcessOverseer() = default; 126 127 // Start observering the process. 128 // 129 // The overseer should: 130 // - Write to std_out & std_err when needed. 131 // - Close the RingStreambuf when done with the stream. 132 // - Return when it can no longer read/write from stdout/stderr 133 virtual void start(RingStreambuf* out, RingStreambuf* err) = 0; 134 135 // Cancel the observation of the process if observation is still happening. 136 // Basically this is used to detach from a running process. 137 // 138 // After return: 139 // - no writes to std_out, std_err should happen 140 // - all resource should be cleaned up. 141 // - a call to the start method should return with std::nullopt 142 virtual void stop() = 0; 143 }; 144 145 // A overseer that does nothing. 146 // Use this for detached processes, testing. 147 class NullOverseer : public ProcessOverseer { 148 public: start(RingStreambuf * out,RingStreambuf * err)149 virtual void start(RingStreambuf* out, RingStreambuf* err) override {} stop()150 virtual void stop() override {} 151 }; 152 153 // A running process that you can interact with. 154 // 155 // You obtain a process by running a command. 156 // For example: 157 // 158 // auto p = Command::create({"ls"}).execute(); 159 // if (p->exitCode() == 0) { 160 // auto list = p->out()->asString(); 161 // } 162 class ObservableProcess : public Process { 163 public: 164 // Kills the process.. 165 virtual ~ObservableProcess(); 166 167 // stdout from the child if not detached. out()168 ProcessOutput* out() { return mStdOut.get(); }; 169 170 // stderr from the child if not detached. err()171 ProcessOutput* err() { return mStdErr.get(); }; 172 173 // Detach the process overseer, and stop observing the process 174 // you will: 175 // - Not able to read stdout/stderr 176 // - The process will not be terminated when going out of scope. 177 void detach(); 178 179 std::future_status wait_for( 180 const std::chrono::milliseconds timeout_duration) const override; 181 182 protected: 183 // Subclasses should implement this to actually launch the process, 184 // return std::nullopt in case of failure 185 virtual std::optional<Pid> createProcess(const CommandArguments& args, 186 bool captureOutput) = 0; 187 188 // Create the overseer used to observe the process state. 189 virtual std::unique_ptr<ProcessOverseer> createOverseer() = 0; 190 191 // True if no overseer is needed 192 bool mDeamon{false}; 193 194 // True if we want to inherit all the fds/handles. 195 bool mInherit{false}; 196 197 private: 198 void runOverseer(); 199 200 std::unique_ptr<ProcessOverseer> mOverseer; 201 std::unique_ptr<std::thread> mOverseerThread; GUARDED_BY(mOverseerMutex)202 bool mOverseerActive GUARDED_BY(mOverseerMutex) {false}; 203 mutable std::mutex mOverseerMutex; 204 mutable std::condition_variable mOverseerCv; 205 206 std::unique_ptr<ProcessOutput> mStdOut; 207 std::unique_ptr<ProcessOutput> mStdErr; 208 209 friend Command; 210 }; 211 } // namespace base 212 } // namespace android 213