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