libzypp 17.34.1
process.cpp
Go to the documentation of this file.
1#include "process.h"
3#include <zypp-core/zyppng/base/EventDispatcher>
5#include <zypp-core/zyppng/io/AsyncDataSource>
7#include <fcntl.h>
8
9namespace zyppng {
10
39
41
43 {
44
45 }
46
48 {
49 return std::shared_ptr<Process>( new Process() );
50 }
51
53 {
54 Z_D();
55 if ( d->_spawnEngine->pid() >= 0 ) {
56 EventDispatcher::instance()->untrackChildProcess( d->_spawnEngine->pid() );
57 DBG << "Process destroyed while still running removing from EventLoop." << std::endl;
58 }
59 }
60
61 bool Process::start( const char *const *argv )
62 {
63 Z_D();
64
66 ERR << "A valid EventDispatcher needs to be registered before starting a Process" << std::endl;
67 return false;
68 }
69
70 if ( isRunning() )
71 return false;
72
73 // clean up the previous run
75 d->cleanup();
76
77 // create the pipes we need
78 auto stdinPipe = Pipe::create( );
79 if ( !stdinPipe ) {
80 d->_sigFailedToStart.emit();
81 return false;
82 }
83
84 auto stdoutPipe = Pipe::create( );
85 if ( !stdoutPipe ) {
86 d->_sigFailedToStart.emit();
87 return false;
88 }
89
90 int stderr_fd = -1;
91 std::optional<Pipe> stderrPipe;
92 if ( d->_channelMode == Seperate ) {
93 stderrPipe = Pipe::create( );
94 if ( !stderrPipe ) {
95 d->_sigFailedToStart.emit();
96 return false;
97 }
98 stderr_fd = stderrPipe->writeFd;
99 } else {
100 stderr_fd = stdoutPipe->writeFd;
101 }
102
103 if ( d->_spawnEngine->start( argv, stdinPipe->readFd, stdoutPipe->writeFd, stderr_fd ) ) {
104
105 // if we reach this point the engine guarantees that exec() was successful
106 const auto pid = d->_spawnEngine->pid( );
107
108 // register to the eventloop right away
109 EventDispatcher::instance()->trackChildProcess( pid, [this]( int, int status ){
110 Z_D();
111 d->_spawnEngine->notifyExited( status );
112 d->_sigFinished.emit( d->_spawnEngine->exitStatus() );
113 });
114
115 // make sure the fds we need are kept open
116 d->_stdinFd = std::move( stdinPipe->writeFd );
117 d->_stdoutFd = std::move( stdoutPipe->readFd );
118
119 std::vector<int> rFds { d->_stdoutFd };
120 if ( stderrPipe ) {
121 d->_stderrFd = std::move( stderrPipe->readFd );
122 rFds.push_back( d->_stderrFd.value() );
123 }
124
125 if ( !openFds( rFds, d->_stdinFd ) ) {
126 stop( SIGKILL );
127 return false;
128 }
129
130 d->_sigStarted.emit();
131 return true;
132 }
133 d->_sigFailedToStart.emit();
134 return false;
135 }
136
137 void Process::stop( int signal )
138 {
139 Z_D();
140 if ( isRunning() ) {
141 ::kill( d->_spawnEngine->pid(), signal );
142 }
143 }
144
146 {
147 Z_D();
148 return ( d->_spawnEngine->pid() > -1 );
149 }
150
152 {
153 flush();
154 stop(SIGKILL);
155 d_func()->cleanup();
157 }
158
160 {
161 Z_D();
162 if ( d->_spawnEngine->isRunning() ) {
163 // we will manually track the exit status
164 EventDispatcher::instance()->untrackChildProcess( d->_spawnEngine->pid() );
165 // wait for the process to exit
166 d->_spawnEngine->isRunning( true );
167 }
168 }
169
171 {
172 Z_D();
173 d->_stdinFd = -1;
175 }
176
177 const std::string &Process::executedCommand() const
178 {
179 return d_func()->_spawnEngine->executedCommand();
180 }
181
182 const std::string &Process::execError() const
183 {
184 return d_func()->_spawnEngine->execError();
185 }
186
188 {
189 return d_func()->_spawnEngine->chroot();
190 }
191
193 {
194 return d_func()->_spawnEngine->setChroot( chroot );
195 }
196
198 {
199 return d_func()->_spawnEngine->useDefaultLocale();
200 }
201
202 void Process::setUseDefaultLocale( bool defaultLocale )
203 {
204 return d_func()->_spawnEngine->setUseDefaultLocale( defaultLocale );
205 }
206
208 {
209 return d_func()->_spawnEngine->environment();
210 }
211
213 {
214 return d_func()->_spawnEngine->setEnvironment( env );
215 }
216
218 {
219 return d_func()->_spawnEngine->pid();
220 }
221
223 {
224 return d_func()->_spawnEngine->exitStatus();
225 }
226
228 {
229 return d_func()->_spawnEngine->dieWithParent();
230 }
231
232 void Process::setDieWithParent( bool enabled )
233 {
234 return d_func()->_spawnEngine->setDieWithParent( enabled );
235 }
236
238 {
239 return d_func()->_spawnEngine->switchPgid();
240 }
241
242 void Process::setSwitchPgid(bool enabled)
243 {
244 return d_func()->_spawnEngine->setSwitchPgid( enabled );
245 }
246
248 {
249 return d_func()->_spawnEngine->workingDirectory();
250 }
251
253 {
254 return d_func()->_spawnEngine->setWorkingDirectory( wd );
255 }
256
257 const std::vector<int> &Process::fdsToMap() const
258 {
259 return d_func()->_spawnEngine->fdsToMap();
260 }
261
262 void Process::addFd(int fd)
263 {
264 return d_func()->_spawnEngine->addFd( fd );
265 }
266
268 {
269 return d_func()->_stdinFd;
270 }
271
273 {
274 return d_func()->_stdoutFd;
275 }
276
278 {
279 return d_func()->_stderrFd;
280 }
281
283 {
284 return d_func()->_sigStarted;
285 }
286
288 {
289 return d_func()->_sigFailedToStart;
290 }
291
293 {
294 return d_func()->_sigFinished;
295 }
296
297 Process::OutputChannelMode Process::outputChannelMode() const { return d_func()->_channelMode; }
298 void Process::setOutputChannelMode(const OutputChannelMode &outputChannelMode) { d_func()->_channelMode = outputChannelMode; }
299
300}
static std::unique_ptr< zyppng::AbstractSpawnEngine > createDefaultEngine()
bool openFds(const std::vector< int > &readFds, int writeFd=-1)
static std::shared_ptr< EventDispatcher > instance()
std::unique_ptr< AbstractSpawnEngine > _spawnEngine
Definition process.cpp:28
zypp::AutoFD _stdinFd
Definition process.cpp:29
Signal< void()> _sigFailedToStart
Definition process.cpp:34
zypp::AutoFD _stderrFd
Definition process.cpp:30
Signal< void(int)> _sigFinished
Definition process.cpp:33
ProcessPrivate(Process &p)
Definition process.cpp:19
Process::OutputChannel _currentChannel
Definition process.cpp:37
Process::OutputChannelMode _channelMode
Definition process.cpp:36
zypp::AutoFD _stdoutFd
Definition process.cpp:31
Signal< void()> _sigStarted
Definition process.cpp:32
bool switchPgid() const
Definition process.cpp:237
OutputChannelMode outputChannelMode() const
Definition process.cpp:297
std::map< std::string, std::string > Environment
For passing additional environment variables to set.
Definition process.h:36
zypp::Pathname chroot() const
Definition process.cpp:187
std::shared_ptr< Process > Ptr
Definition process.h:37
~Process() override
Definition process.cpp:52
bool dieWithParent() const
Definition process.cpp:227
void close() override
Definition process.cpp:151
int exitStatus() const
Definition process.cpp:222
void setEnvironment(const Environment &environment)
Definition process.cpp:212
void stop(int signal=SIGTERM)
Definition process.cpp:137
void closeWriteChannel() override
Definition process.cpp:170
const std::string & executedCommand() const
Definition process.cpp:177
void addFd(int fd)
Definition process.cpp:262
static Ptr create()
Definition process.cpp:47
bool start(const char *const *argv)
Definition process.cpp:61
bool useDefaultLocale() const
Definition process.cpp:197
void waitForExit()
Definition process.cpp:159
void setWorkingDirectory(const zypp::Pathname &workingDirectory)
Definition process.cpp:252
SignalProxy< void()> sigStarted()
Definition process.cpp:282
const std::vector< int > & fdsToMap() const
Definition process.cpp:257
void setUseDefaultLocale(bool defaultLocale)
Definition process.cpp:202
void setSwitchPgid(bool enabled)
Definition process.cpp:242
void setChroot(const zypp::Pathname &chroot)
Definition process.cpp:192
void setOutputChannelMode(const OutputChannelMode &outputChannelMode)
Definition process.cpp:298
zypp::Pathname workingDirectory() const
Definition process.cpp:247
void setDieWithParent(bool enabled)
Definition process.cpp:232
SignalProxy< void()> sigFailedToStart()
Definition process.cpp:287
SignalProxy< void(int)> sigFinished()
Definition process.cpp:292
Environment environment() const
Definition process.cpp:207
const std::string & execError() const
Definition process.cpp:182
Namespace intended to collect all environment variables we use.
Definition Env.h:23
AutoDispose<int> calling close
static std::optional< Pipe > create(int flags=0)
#define DBG
Definition Logger.h:97
#define ERR
Definition Logger.h:100
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:91
#define Z_D()
Definition zyppglobal.h:104