xref: /aosp_15_r20/external/libbrillo/brillo/process_reaper.h (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_PROCESS_REAPER_H_
6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_PROCESS_REAPER_H_
7*1a96fba6SXin Li 
8*1a96fba6SXin Li #include <sys/wait.h>
9*1a96fba6SXin Li 
10*1a96fba6SXin Li #include <map>
11*1a96fba6SXin Li 
12*1a96fba6SXin Li #include <base/callback.h>
13*1a96fba6SXin Li #include <base/location.h>
14*1a96fba6SXin Li #include <base/macros.h>
15*1a96fba6SXin Li #include <brillo/asynchronous_signal_handler.h>
16*1a96fba6SXin Li 
17*1a96fba6SXin Li namespace brillo {
18*1a96fba6SXin Li 
19*1a96fba6SXin Li class BRILLO_EXPORT ProcessReaper final {
20*1a96fba6SXin Li  public:
21*1a96fba6SXin Li   // The callback called when a child exits.
22*1a96fba6SXin Li   using ChildCallback = base::OnceCallback<void(const siginfo_t&)>;
23*1a96fba6SXin Li 
24*1a96fba6SXin Li   ProcessReaper() = default;
25*1a96fba6SXin Li   ~ProcessReaper();
26*1a96fba6SXin Li 
27*1a96fba6SXin Li   // Register the ProcessReaper using either the provided
28*1a96fba6SXin Li   // brillo::AsynchronousSignalHandlerInterface. You can call Unregister() to
29*1a96fba6SXin Li   // remove this ProcessReapper or it will be called during shutdown.
30*1a96fba6SXin Li   // You can only register this ProcessReaper with one signal handler at a time.
31*1a96fba6SXin Li   void Register(AsynchronousSignalHandlerInterface* async_signal_handler);
32*1a96fba6SXin Li 
33*1a96fba6SXin Li   // Unregisters the ProcessReaper from the
34*1a96fba6SXin Li   // brillo::AsynchronousSignalHandlerInterface passed in Register(). It
35*1a96fba6SXin Li   // doesn't do anything if not registered.
36*1a96fba6SXin Li   void Unregister();
37*1a96fba6SXin Li 
38*1a96fba6SXin Li   // Watch for the child process |pid| to finish and call |callback| when the
39*1a96fba6SXin Li   // selected process exits or the process terminates for other reason. The
40*1a96fba6SXin Li   // |callback| receives the exit status and exit code of the terminated process
41*1a96fba6SXin Li   // as a siginfo_t. See wait(2) for details about siginfo_t.
42*1a96fba6SXin Li   bool WatchForChild(const base::Location& from_here,
43*1a96fba6SXin Li                      pid_t pid,
44*1a96fba6SXin Li                      ChildCallback callback);
45*1a96fba6SXin Li 
46*1a96fba6SXin Li   // Stop watching child process |pid|.  This is useful in situations
47*1a96fba6SXin Li   // where the child process may have been reaped outside of the signal
48*1a96fba6SXin Li   // handler, or the caller is no longer interested in being notified about
49*1a96fba6SXin Li   // this child process anymore.  Returns true if a child was removed from
50*1a96fba6SXin Li   // the watchlist.
51*1a96fba6SXin Li   bool ForgetChild(pid_t pid);
52*1a96fba6SXin Li 
53*1a96fba6SXin Li  private:
54*1a96fba6SXin Li   // SIGCHLD handler for the AsynchronousSignalHandler. Always returns false
55*1a96fba6SXin Li   // (meaning that the signal handler should not be unregistered).
56*1a96fba6SXin Li   bool HandleSIGCHLD(const signalfd_siginfo& sigfd_info);
57*1a96fba6SXin Li 
58*1a96fba6SXin Li   struct WatchedProcess {
59*1a96fba6SXin Li     base::Location location;
60*1a96fba6SXin Li     ChildCallback callback;
61*1a96fba6SXin Li   };
62*1a96fba6SXin Li   std::map<pid_t, WatchedProcess> watched_processes_;
63*1a96fba6SXin Li 
64*1a96fba6SXin Li   // The |async_signal_handler_| is owned by the caller and is |nullptr| when
65*1a96fba6SXin Li   // not registered.
66*1a96fba6SXin Li   AsynchronousSignalHandlerInterface* async_signal_handler_{nullptr};
67*1a96fba6SXin Li 
68*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(ProcessReaper);
69*1a96fba6SXin Li };
70*1a96fba6SXin Li 
71*1a96fba6SXin Li }  // namespace brillo
72*1a96fba6SXin Li 
73*1a96fba6SXin Li #endif  // LIBBRILLO_BRILLO_PROCESS_REAPER_H_
74