xref: /aosp_15_r20/system/update_engine/common/subprocess.h (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
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