3 * simple process handling based on simple io classes.
5 * (c) Copyright 2007-2008 by Intra2net AG
10 #ifndef __ASYNC_PROCESS_HPP__
11 #define __ASYNC_PROCESS_HPP__
16 #include <sys/types.h>
18 #include <containerfunc.hpp>
19 #include <signalfunc.hpp>
20 #include "async_io.hpp"
26 using SystemTools::Signal;
27 using SystemTools::ScopedSignalBlocker;
33 typedef std::pair< pid_t, int > PidStatePair;
34 typedef std::vector< PidStatePair > PidStateList;
38 * represents process states.
47 }; // eo enum _ProcessState
49 _ProcessState m_state;
51 ProcessState(_ProcessState _state = stopped) : m_state(_state) {}
53 operator _ProcessState() const { return m_state; }
54 }; // eo struct ProcessState
58 * specialisation of the io implementation class which fork/exec's a subprocess and
59 * connects with the new child's stdin/stdout.
61 * @note the signal @a IOImplementation::m_signal_eof of the base class can be used to detect when the
62 * new child closes it's stdout (which usually means that the child ended).
64 class ProcessImplementation : public IOImplementation
66 typedef IOImplementation inherited;
68 friend class ProcessManager;
74 /// "magic" constant to pass to start() when childs stderr should be the same as parents stderr.
76 /// "magic" constant to pass to start() when stderr should be the same as stdout for the new process.
78 }; // eo enum StderrMode
81 ProcessImplementation(
82 const std::string& path,
83 const std::vector<std::string>& args = std::vector<std::string>());
84 virtual ~ProcessImplementation();
86 virtual void close(Direction direction = Direction::both);
88 virtual bool startProcess( IOImplementation2* stderr );
89 bool startProcess( StderrMode stderr_mode = UseParentsStderr );
91 virtual void stopProcess(bool force=false);
93 PushBackFiller<std::string, std::vector > getArgAdder();
95 bool setCreateNewSession( bool enable= true);
97 bool setNice(int nice);
99 bool setWorkDir(const std::string& workdir);
101 void resetArgs( const std::vector< std::string >& args = std::vector< std::string >() );
103 /// returns the current process state
104 ProcessState processState() const { return m_state; }
106 ///returns the exit code of the process (if in stopped state)
107 int exitCode() const { return m_exit_code; }
112 bool kill(const Signal signal);
114 void setChildState(pid_t pid, int status);
117 /// the path to the binary
119 /// argument list (starting with argv0, usually the name of the binary)
120 std::vector<std::string> m_args;
121 /// increment of the nice level when the new child is started
123 /// determines if the child should start a new session.
124 bool m_create_new_session;
125 /// determines the workdir where the child process should be started with.
126 std::string m_workdir;
128 /// the pid of the child process
130 /// the state of the child process
131 ProcessState m_state;
132 /// the exit code of the child (-1 if not available yet)
135 /// signal which is fired when the child terminated
136 SignalType m_signal_terminated;
139 /// "magic" constant to pass to start() when childs stderr should be the same as parents stderr.
140 static IOImplementation2* _UseParentsStderr;
141 /// "magic" constant to pass to start() when stderr should be the same as stdout for the new process.
142 static IOImplementation2* _StderrOnStdout;
146 }; // eo class ProcessImplementation
150 * manages overall process related stuff.
152 * @note this class is implemented as a singleton.
153 * @note this class uses the io timer interface to be called within the backend loops when necessary.
155 class ProcessManager : public TimerBase
159 static ProcessManager* getInstance();
163 ProcessManager(const ProcessManager&);
165 virtual void execute();
172 * the signal which is fired when waitpid() returns a status for a child process
173 * which is not managed by this process subsystem.
174 * Another module which forks child processes can connect to this signal to receive
175 * the information when these child processes are terminated.
177 boost::signal<void(pid_t,int)> m_foreign_child_state_changed_signal;
181 static ProcessManager *the_instance;
183 PidStateList m_foreign_pid_states;
189 bool installChildHandler();
190 bool restoreChildHandler();
193 } // eo namespace AsyncIo