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 <containerfunc.hpp>
36 #include <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; }
129 bool kill(const Signal signal);
131 void setChildState(pid_t pid, int status);
134 /// the path to the binary
136 /// argument list (starting with argv0, usually the name of the binary)
137 std::vector<std::string> m_args;
138 /// increment of the nice level when the new child is started
140 /// determines if the child should start a new session.
141 bool m_create_new_session;
142 /// determines the workdir where the child process should be started with.
143 std::string m_workdir;
145 /// the pid of the child process
147 /// the state of the child process
148 ProcessState m_state;
149 /// the exit code of the child (-1 if not available yet)
152 /// signal which is fired when the child terminated
153 SignalType m_signal_terminated;
156 /// "magic" constant to pass to start() when childs stderr should be the same as parents stderr.
157 static IOImplementation2* _UseParentsStderr;
158 /// "magic" constant to pass to start() when stderr should be the same as stdout for the new process.
159 static IOImplementation2* _StderrOnStdout;
163 }; // eo class ProcessImplementation
167 * manages overall process related stuff.
169 * @note this class is implemented as a singleton.
170 * @note this class uses the io timer interface to be called within the backend loops when necessary.
172 class ProcessManager : public TimerBase
176 static ProcessManager* getInstance();
180 ProcessManager(const ProcessManager&);
182 virtual void execute();
189 * the signal which is fired when waitpid() returns a status for a child process
190 * which is not managed by this process subsystem.
191 * Another module which forks child processes can connect to this signal to receive
192 * the information when these child processes are terminated.
194 boost::signal<void(pid_t,int)> m_foreign_child_state_changed_signal;
198 static ProcessManager *the_instance;
200 PidStateList m_foreign_pid_states;
206 bool installChildHandler();
207 bool restoreChildHandler();
210 } // eo namespace AsyncIo