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