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