libzypp  17.35.8
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 
9 namespace zyppng {
10 
17  {
18  public:
21  , _sigFinished(p)
22  { }
23 
24  void cleanup() {
25  _stdinFd = -1;
26  _stderrFd = -1;
27  _stdoutFd = -1;
28  }
29 
30  std::unique_ptr<AbstractSpawnEngine> _spawnEngine = AbstractSpawnEngine::createDefaultEngine();
37 
40  };
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 
67  if ( !EventDispatcher::instance() ) {
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 
219  pid_t Process::pid()
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 
239  bool Process::switchPgid() const
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; }
300  void Process::setOutputChannelMode(const OutputChannelMode &outputChannelMode) { d_func()->_channelMode = outputChannelMode; }
301 
302 }
Environment environment() const
Definition: process.cpp:209
int exitStatus() const
Definition: process.cpp:224
zypp::Pathname chroot() const
Definition: process.cpp:189
Namespace intended to collect all environment variables we use.
Definition: Env.h:22
void setEnvironment(const Environment &environment)
Definition: process.cpp:214
const std::vector< int > & fdsToMap() const
Definition: process.cpp:259
SignalProxy< void()> sigStarted()
Definition: process.cpp:284
void setChroot(const zypp::Pathname &chroot)
Definition: process.cpp:194
void closeWriteChannel() override
Definition: process.cpp:172
SignalProxy< void(int)> sigFinished()
Definition: process.cpp:294
static std::unique_ptr< zyppng::AbstractSpawnEngine > createDefaultEngine()
OutputChannelMode outputChannelMode() const
Definition: process.cpp:299
void close() override
Definition: process.cpp:153
Signal< void()> _sigFailedToStart
Definition: process.cpp:36
bool dieWithParent() const
Definition: process.cpp:229
void setWorkingDirectory(const zypp::Pathname &workingDirectory)
Definition: process.cpp:254
bool start(const char *const *argv)
Definition: process.cpp:63
void setSwitchPgid(bool enabled)
Definition: process.cpp:244
AutoDispose<int> calling ::close
Definition: AutoDispose.h:309
SignalProxy< void()> sigFailedToStart()
Definition: process.cpp:289
#define ERR
Definition: Logger.h:100
const std::string & execError() const
Definition: process.cpp:184
zypp::AutoFD _stdoutFd
Definition: process.cpp:33
#define Z_D()
Definition: zyppglobal.h:105
std::unique_ptr< AbstractSpawnEngine > _spawnEngine
Definition: process.cpp:30
std::map< std::string, std::string > Environment
For passing additional environment variables to set.
Definition: process.h:38
Signal< void()> _sigStarted
Definition: process.cpp:34
static Ptr create()
Definition: process.cpp:49
zypp::Pathname workingDirectory() const
Definition: process.cpp:249
bool isRunning()
Definition: process.cpp:147
static std::shared_ptr< EventDispatcher > instance()
MemSignal< Process, void(int)> _sigFinished
Definition: process.cpp:35
ProcessRef Ptr
Definition: process.h:39
void setUseDefaultLocale(bool defaultLocale)
Definition: process.cpp:204
Process::OutputChannelMode _channelMode
Definition: process.cpp:38
Process::OutputChannel _currentChannel
Definition: process.cpp:39
zypp::AutoFD _stdinFd
Definition: process.cpp:31
virtual void closeWriteChannel()
ProcessPrivate(Process &p)
Definition: process.cpp:19
static std::optional< Pipe > create(int flags=0)
Definition: linuxhelpers.cc:71
void stop(int signal=SIGTERM)
Definition: process.cpp:139
~Process() override
Definition: process.cpp:54
ZYPP_IMPL_PRIVATE(UnixSignalSource)
bool useDefaultLocale() const
Definition: process.cpp:199
void waitForExit()
Definition: process.cpp:161
zypp::AutoFD _stderrFd
Definition: process.cpp:32
bool openFds(const std::vector< int > &readFds, int writeFd=-1)
const std::string & executedCommand() const
Definition: process.cpp:179
bool switchPgid() const
Definition: process.cpp:239
void setOutputChannelMode(const OutputChannelMode &outputChannelMode)
Definition: process.cpp:300
void addFd(int fd)
Definition: process.cpp:264
void setDieWithParent(bool enabled)
Definition: process.cpp:234
#define DBG
Definition: Logger.h:97