1*5a923131SAndroid Build Coastguard Worker // 2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2011 The Android Open Source Project 3*5a923131SAndroid Build Coastguard Worker // 4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at 7*5a923131SAndroid Build Coastguard Worker // 8*5a923131SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 9*5a923131SAndroid Build Coastguard Worker // 10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 14*5a923131SAndroid Build Coastguard Worker // limitations under the License. 15*5a923131SAndroid Build Coastguard Worker // 16*5a923131SAndroid Build Coastguard Worker 17*5a923131SAndroid Build Coastguard Worker #ifndef UPDATE_ENGINE_COMMON_SUBPROCESS_H_ 18*5a923131SAndroid Build Coastguard Worker #define UPDATE_ENGINE_COMMON_SUBPROCESS_H_ 19*5a923131SAndroid Build Coastguard Worker 20*5a923131SAndroid Build Coastguard Worker #include <unistd.h> 21*5a923131SAndroid Build Coastguard Worker 22*5a923131SAndroid Build Coastguard Worker #include <map> 23*5a923131SAndroid Build Coastguard Worker #include <memory> 24*5a923131SAndroid Build Coastguard Worker #include <string> 25*5a923131SAndroid Build Coastguard Worker #include <vector> 26*5a923131SAndroid Build Coastguard Worker 27*5a923131SAndroid Build Coastguard Worker #include <base/callback.h> 28*5a923131SAndroid Build Coastguard Worker #include <base/files/file_descriptor_watcher_posix.h> 29*5a923131SAndroid Build Coastguard Worker #include <base/logging.h> 30*5a923131SAndroid Build Coastguard Worker #include <android-base/macros.h> 31*5a923131SAndroid Build Coastguard Worker #include <brillo/asynchronous_signal_handler_interface.h> 32*5a923131SAndroid Build Coastguard Worker #include <brillo/message_loops/message_loop.h> 33*5a923131SAndroid Build Coastguard Worker #ifdef __CHROMEOS__ 34*5a923131SAndroid Build Coastguard Worker #include <brillo/process/process.h> 35*5a923131SAndroid Build Coastguard Worker #include <brillo/process/process_reaper.h> 36*5a923131SAndroid Build Coastguard Worker #else 37*5a923131SAndroid Build Coastguard Worker #include <brillo/process.h> 38*5a923131SAndroid Build Coastguard Worker #include <brillo/process_reaper.h> 39*5a923131SAndroid Build Coastguard Worker #endif // __CHROMEOS__ 40*5a923131SAndroid Build Coastguard Worker #include <gtest/gtest_prod.h> 41*5a923131SAndroid Build Coastguard Worker 42*5a923131SAndroid Build Coastguard Worker // The Subprocess class is a singleton. It's used to spawn off a subprocess 43*5a923131SAndroid Build Coastguard Worker // and get notified when the subprocess exits. The result of Exec() can 44*5a923131SAndroid Build Coastguard Worker // be saved and used to cancel the callback request and kill your process. If 45*5a923131SAndroid Build Coastguard Worker // you know you won't call KillExec(), you may safely lose the return value 46*5a923131SAndroid Build Coastguard Worker // from Exec(). 47*5a923131SAndroid Build Coastguard Worker 48*5a923131SAndroid Build Coastguard Worker // To create the Subprocess singleton just instantiate it with and call Init(). 49*5a923131SAndroid Build Coastguard Worker // You can't have two Subprocess instances initialized at the same time. 50*5a923131SAndroid Build Coastguard Worker 51*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine { 52*5a923131SAndroid Build Coastguard Worker 53*5a923131SAndroid Build Coastguard Worker class Subprocess { 54*5a923131SAndroid Build Coastguard Worker public: 55*5a923131SAndroid Build Coastguard Worker enum Flags { 56*5a923131SAndroid Build Coastguard Worker kSearchPath = 1 << 0, 57*5a923131SAndroid Build Coastguard Worker kRedirectStderrToStdout = 1 << 1, 58*5a923131SAndroid Build Coastguard Worker }; 59*5a923131SAndroid Build Coastguard Worker 60*5a923131SAndroid Build Coastguard Worker // Callback type used when an async process terminates. It receives the exit 61*5a923131SAndroid Build Coastguard Worker // code and the stdout output (and stderr if redirected). 62*5a923131SAndroid Build Coastguard Worker using ExecCallback = base::Callback<void(int, const std::string&)>; 63*5a923131SAndroid Build Coastguard Worker 64*5a923131SAndroid Build Coastguard Worker Subprocess() = default; 65*5a923131SAndroid Build Coastguard Worker 66*5a923131SAndroid Build Coastguard Worker // Destroy and unregister the Subprocess singleton. 67*5a923131SAndroid Build Coastguard Worker ~Subprocess(); 68*5a923131SAndroid Build Coastguard Worker 69*5a923131SAndroid Build Coastguard Worker // Initialize and register the Subprocess singleton. 70*5a923131SAndroid Build Coastguard Worker void Init(brillo::AsynchronousSignalHandlerInterface* async_signal_handler); 71*5a923131SAndroid Build Coastguard Worker 72*5a923131SAndroid Build Coastguard Worker // Launches a process in the background and calls the passed |callback| when 73*5a923131SAndroid Build Coastguard Worker // the process exits. The file descriptors specified in |output_pipes| will 74*5a923131SAndroid Build Coastguard Worker // be available in the child as the writer end of a pipe. Use GetPipeFd() to 75*5a923131SAndroid Build Coastguard Worker // know the reader end in the parent. Only stdin, stdout, stderr and the file 76*5a923131SAndroid Build Coastguard Worker // descriptors in |output_pipes| will be open in the child. 77*5a923131SAndroid Build Coastguard Worker // Returns the process id of the new launched process or 0 in case of failure. 78*5a923131SAndroid Build Coastguard Worker pid_t Exec(const std::vector<std::string>& cmd, const ExecCallback& callback); 79*5a923131SAndroid Build Coastguard Worker pid_t ExecFlags(const std::vector<std::string>& cmd, 80*5a923131SAndroid Build Coastguard Worker uint32_t flags, 81*5a923131SAndroid Build Coastguard Worker const std::vector<int>& output_pipes, 82*5a923131SAndroid Build Coastguard Worker const ExecCallback& callback); 83*5a923131SAndroid Build Coastguard Worker 84*5a923131SAndroid Build Coastguard Worker // Kills the running process with SIGTERM and ignores the callback. 85*5a923131SAndroid Build Coastguard Worker void KillExec(pid_t pid); 86*5a923131SAndroid Build Coastguard Worker 87*5a923131SAndroid Build Coastguard Worker // Return the parent end of the pipe mapped onto |fd| in the child |pid|. This 88*5a923131SAndroid Build Coastguard Worker // file descriptor is available until the callback for the child |pid| 89*5a923131SAndroid Build Coastguard Worker // returns. After that the file descriptor will be closed. The passed |fd| 90*5a923131SAndroid Build Coastguard Worker // must be one of the file descriptors passed to ExecFlags() in 91*5a923131SAndroid Build Coastguard Worker // |output_pipes|, otherwise returns -1. 92*5a923131SAndroid Build Coastguard Worker int GetPipeFd(pid_t pid, int fd) const; 93*5a923131SAndroid Build Coastguard Worker 94*5a923131SAndroid Build Coastguard Worker // Executes a command synchronously. Returns true on success. If |stdout_str| 95*5a923131SAndroid Build Coastguard Worker // is non-null, the process output is stored in it, otherwise the output is 96*5a923131SAndroid Build Coastguard Worker // logged. 97*5a923131SAndroid Build Coastguard Worker static bool SynchronousExec(const std::vector<std::string>& cmd, 98*5a923131SAndroid Build Coastguard Worker int* return_code, 99*5a923131SAndroid Build Coastguard Worker std::string* stdout_str, 100*5a923131SAndroid Build Coastguard Worker std::string* stderr_str); 101*5a923131SAndroid Build Coastguard Worker static bool SynchronousExecFlags(const std::vector<std::string>& cmd, 102*5a923131SAndroid Build Coastguard Worker uint32_t flags, 103*5a923131SAndroid Build Coastguard Worker int* return_code, 104*5a923131SAndroid Build Coastguard Worker std::string* stdout_str, 105*5a923131SAndroid Build Coastguard Worker std::string* stderr_str); 106*5a923131SAndroid Build Coastguard Worker 107*5a923131SAndroid Build Coastguard Worker // Gets the one instance. Get()108*5a923131SAndroid Build Coastguard Worker static Subprocess& Get() { return *subprocess_singleton_; } 109*5a923131SAndroid Build Coastguard Worker 110*5a923131SAndroid Build Coastguard Worker // Tries to log all in flight processes's output. It is used right before 111*5a923131SAndroid Build Coastguard Worker // exiting the update_engine, probably when the subprocess caused a system 112*5a923131SAndroid Build Coastguard Worker // shutdown. 113*5a923131SAndroid Build Coastguard Worker void FlushBufferedLogsAtExit(); 114*5a923131SAndroid Build Coastguard Worker 115*5a923131SAndroid Build Coastguard Worker private: 116*5a923131SAndroid Build Coastguard Worker FRIEND_TEST(SubprocessTest, CancelTest); 117*5a923131SAndroid Build Coastguard Worker 118*5a923131SAndroid Build Coastguard Worker struct SubprocessRecord { SubprocessRecordSubprocessRecord119*5a923131SAndroid Build Coastguard Worker explicit SubprocessRecord(const ExecCallback& callback) 120*5a923131SAndroid Build Coastguard Worker : callback(callback) {} 121*5a923131SAndroid Build Coastguard Worker 122*5a923131SAndroid Build Coastguard Worker // The callback supplied by the caller. 123*5a923131SAndroid Build Coastguard Worker ExecCallback callback; 124*5a923131SAndroid Build Coastguard Worker 125*5a923131SAndroid Build Coastguard Worker // The ProcessImpl instance managing the child process. Destroying this 126*5a923131SAndroid Build Coastguard Worker // will close our end of the pipes we have open. 127*5a923131SAndroid Build Coastguard Worker brillo::ProcessImpl proc; 128*5a923131SAndroid Build Coastguard Worker 129*5a923131SAndroid Build Coastguard Worker // These are used to monitor the stdout of the running process, including 130*5a923131SAndroid Build Coastguard Worker // the stderr if it was redirected. 131*5a923131SAndroid Build Coastguard Worker std::unique_ptr<base::FileDescriptorWatcher::Controller> stdout_controller; 132*5a923131SAndroid Build Coastguard Worker 133*5a923131SAndroid Build Coastguard Worker int stdout_fd{-1}; 134*5a923131SAndroid Build Coastguard Worker std::string stdout_str; 135*5a923131SAndroid Build Coastguard Worker }; 136*5a923131SAndroid Build Coastguard Worker 137*5a923131SAndroid Build Coastguard Worker // Callback which runs whenever there is input available on the subprocess 138*5a923131SAndroid Build Coastguard Worker // stdout pipe. 139*5a923131SAndroid Build Coastguard Worker static void OnStdoutReady(SubprocessRecord* record); 140*5a923131SAndroid Build Coastguard Worker 141*5a923131SAndroid Build Coastguard Worker // Callback for when any subprocess terminates. This calls the user 142*5a923131SAndroid Build Coastguard Worker // requested callback. 143*5a923131SAndroid Build Coastguard Worker void ChildExitedCallback(const siginfo_t& info); 144*5a923131SAndroid Build Coastguard Worker 145*5a923131SAndroid Build Coastguard Worker // The global instance. 146*5a923131SAndroid Build Coastguard Worker static Subprocess* subprocess_singleton_; 147*5a923131SAndroid Build Coastguard Worker 148*5a923131SAndroid Build Coastguard Worker // A map from the asynchronous subprocess tag (see Exec) to the subprocess 149*5a923131SAndroid Build Coastguard Worker // record structure for all active asynchronous subprocesses. 150*5a923131SAndroid Build Coastguard Worker std::map<pid_t, std::unique_ptr<SubprocessRecord>> subprocess_records_; 151*5a923131SAndroid Build Coastguard Worker 152*5a923131SAndroid Build Coastguard Worker // Used to watch for child processes. 153*5a923131SAndroid Build Coastguard Worker brillo::ProcessReaper process_reaper_; 154*5a923131SAndroid Build Coastguard Worker 155*5a923131SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Subprocess); 156*5a923131SAndroid Build Coastguard Worker }; 157*5a923131SAndroid Build Coastguard Worker 158*5a923131SAndroid Build Coastguard Worker } // namespace chromeos_update_engine 159*5a923131SAndroid Build Coastguard Worker 160*5a923131SAndroid Build Coastguard Worker #endif // UPDATE_ENGINE_COMMON_SUBPROCESS_H_ 161