pid() is const
[libasyncio] / asyncio / async_process.hpp
CommitLineData
8c15b8c7
TJ
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
5c8a3d40
RP
20/** @file
21 *
22 * simple process handling based on simple io classes.
23 *
24 * (c) Copyright 2007-2008 by Intra2net AG
5c8a3d40
RP
25 */
26
42b7c46d
RP
27#ifndef __ASYNC_PROCESS_HPP__
28#define __ASYNC_PROCESS_HPP__
5c8a3d40
RP
29
30#include <vector>
31#include <utility>
32
33#include <sys/types.h>
34
ce4ab835
RP
35#include <asyncio_containerfunc.hpp>
36#include <asyncio_signalfunc.hpp>
42b7c46d 37#include "async_io.hpp"
5c8a3d40
RP
38
39
42b7c46d 40namespace AsyncIo
5c8a3d40
RP
41{
42
43using SystemTools::Signal;
44using SystemTools::ScopedSignalBlocker;
45
46
47class ProcessManager;
48
49
50typedef std::pair< pid_t, int > PidStatePair;
51typedef std::vector< PidStatePair > PidStateList;
52
53
54/**
55 * represents process states.
56 */
57struct ProcessState
58{
59 enum _ProcessState
60 {
61 stopped = 0,
62 running,
63 suspended
64 }; // eo enum _ProcessState
65
66 _ProcessState m_state;
67
68 ProcessState(_ProcessState _state = stopped) : m_state(_state) {}
69
70 operator _ProcessState() const { return m_state; }
71}; // eo struct ProcessState
72
73
74/**
75 * specialisation of the io implementation class which fork/exec's a subprocess and
76 * connects with the new child's stdin/stdout.
77 *
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).
80 */
81class ProcessImplementation : public IOImplementation
82{
83 typedef IOImplementation inherited;
84
85 friend class ProcessManager;
86
87 public:
88
89 enum StderrMode
90 {
91 /// "magic" constant to pass to start() when childs stderr should be the same as parents stderr.
92 UseParentsStderr= 0,
93 /// "magic" constant to pass to start() when stderr should be the same as stdout for the new process.
94 StderrOnStdout
95 }; // eo enum StderrMode
96
97 public:
98 ProcessImplementation(
99 const std::string& path,
100 const std::vector<std::string>& args = std::vector<std::string>());
101 virtual ~ProcessImplementation();
102
103 virtual void close(Direction direction = Direction::both);
104
105 virtual bool startProcess( IOImplementation2* stderr );
106 bool startProcess( StderrMode stderr_mode = UseParentsStderr );
107
108 virtual void stopProcess(bool force=false);
109
110 PushBackFiller<std::string, std::vector > getArgAdder();
111
112 bool setCreateNewSession( bool enable= true);
113
114 bool setNice(int nice);
115
116 bool setWorkDir(const std::string& workdir);
117
118 void resetArgs( const std::vector< std::string >& args = std::vector< std::string >() );
119
120 /// returns the current process state
121 ProcessState processState() const { return m_state; }
122
123 ///returns the exit code of the process (if in stopped state)
124 int exitCode() const { return m_exit_code; }
125
811f4e70 126 bool kill(const Signal signal);
5c8a3d40 127
811f4e70 128 /// returns the pid of the child process
2491b8a2 129 pid_t pid() const { return m_pid; }
5c8a3d40 130
811f4e70 131 protected:
5c8a3d40
RP
132
133 void setChildState(pid_t pid, int status);
134
135 protected:
136 /// the path to the binary
137 std::string m_path;
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
141 int m_nice_inc;
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;
146
147 /// the pid of the child process
148 pid_t m_pid;
149 /// the state of the child process
150 ProcessState m_state;
151 /// the exit code of the child (-1 if not available yet)
152 int m_exit_code;
153
154 /// signal which is fired when the child terminated
155 SignalType m_signal_terminated;
156
157
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;
162
163 private:
164
165}; // eo class ProcessImplementation
166
167
168/**
169 * manages overall process related stuff.
170 *
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.
173 */
174class ProcessManager : public TimerBase
175{
176 public:
177
178 static ProcessManager* getInstance();
179
180 protected:
181 ProcessManager();
182 ProcessManager(const ProcessManager&);
183
184 virtual void execute();
185
186 void activateMe();
187
188 public:
189
190 /**
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.
195 */
196 boost::signal<void(pid_t,int)> m_foreign_child_state_changed_signal;
197
198 protected:
199
200 static ProcessManager *the_instance;
201
202 PidStateList m_foreign_pid_states;
203
204 private:
205};
206
207
208bool installChildHandler();
209bool restoreChildHandler();
210
211
42b7c46d 212} // eo namespace AsyncIo
5c8a3d40
RP
213
214#endif