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 <cstdio> 19 #include <functional> 20 #include <future> 21 #include <istream> 22 #include <memory> 23 #include <optional> 24 #include <string> 25 #include <string_view> 26 #include <unordered_map> 27 #include <utility> 28 #include <vector> 29 30 #include "aemu/base/streams/RingStreambuf.h" 31 #include "aemu/base/process/Process.h" 32 33 namespace android { 34 namespace base { 35 36 using android::base::streams::RingStreambuf; 37 using BufferDefinition = std::pair<size_t, std::chrono::milliseconds>; 38 using CommandArguments = std::vector<std::string>; 39 40 // A Command that you can execute and observe. 41 class Command { 42 public: 43 using ProcessFactory = 44 std::function<std::unique_ptr<ObservableProcess>(CommandArguments, bool, bool)>; 45 46 // Run the command with a std out buffer that can hold at most n bytes. 47 // If the buffer is filled, the process will block for at most w ms before 48 // timing out. Timeouts can result in data loss or stream closure. 49 // 50 // The default timeout is a year. 51 Command& withStdoutBuffer( 52 size_t n, 53 std::chrono::milliseconds w = std::chrono::hours(24 * 365)); 54 55 // Run the command with a std err buffer that can hold at most n bytes. 56 // If the buffer is filled, the process will block for at most w ms before 57 // timing out. Timeouts can result in data loss or stream closure. 58 // 59 // The default timeout is a year. 60 Command& withStderrBuffer( 61 size_t n, 62 std::chrono::milliseconds w = std::chrono::hours(24 * 365)); 63 64 // Adds a single argument to the list of arguments. 65 Command& arg(const std::string& arg); 66 67 // Adds a list of arguments to the existing arguments 68 Command& args(const CommandArguments& args); 69 70 // Launch the command as a deamon, you will not be able 71 // to read stderr/stdout, the process will not bet terminated 72 // when the created process goes out of scope. 73 Command& asDeamon(); 74 75 // Call this if you wish to inherit all the file handles 76 Command& inherit(); 77 78 // Launch the process 79 std::unique_ptr<ObservableProcess> execute(); 80 81 // Create a new process 82 static Command create(CommandArguments programWithArgs); 83 84 // You likely only want to use this for testing.. 85 // Implement your own factory that produces an implemented process. 86 // Make sure to set to nullptr when you want to revert to default. 87 static void setTestProcessFactory(ProcessFactory factory); 88 89 protected: 90 Command() = default; Command(CommandArguments args)91 Command(CommandArguments args) : mArgs(args){}; 92 93 private: 94 static ProcessFactory sProcessFactory; 95 static ProcessFactory sTestFactory; 96 97 CommandArguments mArgs; 98 bool mDeamon{false}; 99 bool mCaptureOutput{false}; 100 bool mInherit{false}; 101 BufferDefinition mStdout{0, 0}; 102 BufferDefinition mStderr{0, 0}; 103 }; 104 } // namespace base 105 } // namespace android