2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
22 * simple process handling based on simple io classes.
24 * (c) Copyright 2007-2008 by Intra2net AG
27 #ifndef __ASYNC_PROCESS_HPP__
28 #define __ASYNC_PROCESS_HPP__
33 #include <sys/types.h>
35 #include <asyncio_containerfunc.hpp>
36 #include <asyncio_signalfunc.hpp>
37 #include "async_io.hpp"
43 using SystemTools::Signal;
44 using SystemTools::ScopedSignalBlocker;
50 typedef std::pair< pid_t, int > PidStatePair;
51 typedef std::vector< PidStatePair > PidStateList;
55 * represents process states.
64 }; // eo enum _ProcessState
66 _ProcessState m_state;
68 ProcessState(_ProcessState _state = stopped) : m_state(_state) {}
70 operator _ProcessState() const { return m_state; }
71 }; // eo struct ProcessState
75 * specialisation of the io implementation class which fork/exec's a subprocess and
76 * connects with the new child's stdin/stdout.
78 * @note the signal @a IOImplementation::m_signal_eof of the base class can be used to detect when the
79 * new child closes it's stdout (which usually means that the child ended).
81 class ProcessImplementation : public IOImplementation
83 typedef IOImplementation inherited;
85 friend class ProcessManager;
91 /// "magic" constant to pass to start() when childs stderr should be the same as parents stderr.
93 /// "magic" constant to pass to start() when stderr should be the same as stdout for the new process.
95 }; // eo enum StderrMode
98 ProcessImplementation(
99 const std::string& path,
100 const std::vector<std::string>& args = std::vector<std::string>());
101 virtual ~ProcessImplementation();
103 virtual void close(Direction direction = Direction::both);
105 virtual bool startProcess( IOImplementation2* stderr );
106 bool startProcess( StderrMode stderr_mode = UseParentsStderr );
108 virtual void stopProcess(bool force=false);
110 PushBackFiller<std::string, std::vector > getArgAdder();
112 bool setCreateNewSession( bool enable= true);
114 bool setNice(int nice);
116 bool setWorkDir(const std::string& workdir);
118 void resetArgs( const std::vector< std::string >& args = std::vector< std::string >() );
120 /// returns the current process state
121 ProcessState processState() const { return m_state; }
123 ///returns the exit code of the process (if in stopped state)
124 int exitCode() const { return m_exit_code; }
126 bool kill(const Signal signal);
128 /// returns the pid of the child process
129 pid_t pid() const { return m_pid; }
133 void setChildState(pid_t pid, int status);
136 /// the path to the binary
138 /// argument list (starting with argv0, usually the name of the binary)
139 std::vector<std::string> m_args;
140 /// increment of the nice level when the new child is started
142 /// determines if the child should start a new session.
143 bool m_create_new_session;
144 /// determines the workdir where the child process should be started with.
145 std::string m_workdir;
147 /// the pid of the child process
149 /// the state of the child process
150 ProcessState m_state;
151 /// the exit code of the child (-1 if not available yet)
154 /// signal which is fired when the child terminated
155 SignalType m_signal_terminated;
158 /// "magic" constant to pass to start() when childs stderr should be the same as parents stderr.
159 static IOImplementation2* _UseParentsStderr;
160 /// "magic" constant to pass to start() when stderr should be the same as stdout for the new process.
161 static IOImplementation2* _StderrOnStdout;
165 }; // eo class ProcessImplementation
169 * manages overall process related stuff.
171 * @note this class is implemented as a singleton.
172 * @note this class uses the io timer interface to be called within the backend loops when necessary.
174 class ProcessManager : public TimerBase
178 static ProcessManager* getInstance();
182 ProcessManager(const ProcessManager&);
184 virtual void execute();
191 * the signal which is fired when waitpid() returns a status for a child process
192 * which is not managed by this process subsystem.
193 * Another module which forks child processes can connect to this signal to receive
194 * the information when these child processes are terminated.
196 boost::signals2::signal<void(pid_t,int)> m_foreign_child_state_changed_signal;
200 static ProcessManager *the_instance;
202 PidStateList m_foreign_pid_states;
208 bool installChildHandler();
209 bool restoreChildHandler();
212 } // eo namespace AsyncIo