2 * Copyright © 2013 Canonical Ltd.
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
19 #ifndef CORE_POSIX_CHILD_PROCESS_H_
20 #define CORE_POSIX_CHILD_PROCESS_H_
22 #include <core/posix/process.h>
23 #include <core/posix/standard_stream.h>
24 #include <core/posix/visibility.h>
26 #include <core/signal.h>
36 * @brief The Process class models a child process of this process.
38 * In addition to the functionality offered by the Process class, an instance
39 * of ChildProcess offers functionality to wait for status changes of the child
40 * process and to access the child process's standard streams if they have been
41 * redirected when forking or exec'ing.
43 class CORE_POSIX_DLL_PUBLIC ChildProcess : public Process
47 * @brief The DeathObserver class observes child process' states and emits a signal when a monitored child has died.
49 * Please note that the name of this class is morbid for a reason: Listening
50 * for SIGCHLD is not enough to catch all dying children. Whenever a SIGCHLD is
51 * received, we have to wait for all the children of this process and reap all
52 * monitored ones. We are thus changing state and potentially race with other
53 * wait operations on children.
60 * @brief Creates the unique instance of class DeathObserver.
61 * @throw std::logic_error if the given SignalTrap instance does not trap Signal::sig_chld.
62 * @throw std::runtime_error if there already is an instance of the death observer.
64 static std::unique_ptr<DeathObserver> create_once_with_signal_trap(
65 std::shared_ptr<SignalTrap> trap);
67 DeathObserver(const DeathObserver&) = delete;
68 virtual ~DeathObserver() = default;
70 DeathObserver& operator=(const DeathObserver&) = delete;
71 bool operator==(const DeathObserver&) const = delete;
74 * @brief add adds the specified child to the list of observed child processes.
75 * @param child The child to be observed.
76 * @return true iff the child has been added to the list of observed child processes.
78 virtual bool add(const ChildProcess& child) = 0;
81 * @brief has checks whether the specified child is observed.
82 * @param child The child to check for.
83 * @return true iff the specified child is observed for state changes.
85 virtual bool has(const ChildProcess& child) const = 0;
88 * @brief child_died is emitted whenever an observed child ceases to exist.
90 virtual const core::Signal<ChildProcess>& child_died() const = 0;
93 * @brief Checks and reaps all child processes registered with the observer instance.
95 virtual void on_sig_child() = 0;
98 DeathObserver() = default;
102 * @brief Creates an invalid ChildProcess.
103 * @return An invalid ChildProcess instance.
105 static ChildProcess invalid();
110 * @brief Wait for the child process to change state.
111 * @param [in] flags Alters the behavior of the wait operation.
112 * @return Result of the wait operation, as well as information about the
113 * reasons for a child process's state change.
115 wait::Result wait_for(const wait::Flags& flags);
118 * @brief Mark the child process to not to be killed when the ChildProcess
119 * instance goes away.
121 void dont_kill_on_cleanup();
125 * @brief Access this process's stderr.
127 std::istream& cerr();
130 * @brief Access this process's stdin.
135 * @brief Access this process's stdout.
137 std::istream& cout();
141 friend ChildProcess fork(const std::function<posix::exit::Status()>&, const StandardStream&);
142 friend ChildProcess vfork(const std::function<posix::exit::Status()>&, const StandardStream&);
144 class CORE_POSIX_DLL_LOCAL Pipe
147 static Pipe invalid();
150 Pipe(const Pipe& rhs);
153 Pipe& operator=(const Pipe& rhs);
156 void close_read_fd();
158 int write_fd() const;
159 void close_write_fd();
166 CORE_POSIX_DLL_LOCAL ChildProcess(pid_t pid,
171 struct CORE_POSIX_DLL_LOCAL Private;
172 std::shared_ptr<Private> d;
177 #endif // CORE_POSIX_CHILD_PROCESS_H_