libzypp  17.32.5
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:
20  { }
21 
22  void cleanup() {
23  _stdinFd = -1;
24  _stderrFd = -1;
25  _stdoutFd = -1;
26  }
27 
28  std::unique_ptr<AbstractSpawnEngine> _spawnEngine = AbstractSpawnEngine::createDefaultEngine();
35 
38  };
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 
65  if ( !EventDispatcher::instance() ) {
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 
217  pid_t Process::pid()
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 
237  bool Process::switchPgid() const
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 }
Environment environment() const
Definition: process.cpp:207
int exitStatus() const
Definition: process.cpp:222
zypp::Pathname chroot() const
Definition: process.cpp:187
Namespace intended to collect all environment variables we use.
Definition: Env.h:22
void setEnvironment(const Environment &environment)
Definition: process.cpp:212
const std::vector< int > & fdsToMap() const
Definition: process.cpp:257
SignalProxy< void()> sigStarted()
Definition: process.cpp:282
void setChroot(const zypp::Pathname &chroot)
Definition: process.cpp:192
void closeWriteChannel() override
Definition: process.cpp:170
SignalProxy< void(int)> sigFinished()
Definition: process.cpp:292
static std::unique_ptr< zyppng::AbstractSpawnEngine > createDefaultEngine()
OutputChannelMode outputChannelMode() const
Definition: process.cpp:297
void close() override
Definition: process.cpp:151
Signal< void()> _sigFailedToStart
Definition: process.cpp:34
std::shared_ptr< Process > Ptr
Definition: process.h:37
bool dieWithParent() const
Definition: process.cpp:227
void setWorkingDirectory(const zypp::Pathname &workingDirectory)
Definition: process.cpp:252
bool start(const char *const *argv)
Definition: process.cpp:61
void setSwitchPgid(bool enabled)
Definition: process.cpp:242
AutoDispose<int> calling ::close
Definition: AutoDispose.h:309
SignalProxy< void()> sigFailedToStart()
Definition: process.cpp:287
#define ERR
Definition: Logger.h:98
const std::string & execError() const
Definition: process.cpp:182
zypp::AutoFD _stdoutFd
Definition: process.cpp:31
#define Z_D()
Definition: zyppglobal.h:104
std::unique_ptr< AbstractSpawnEngine > _spawnEngine
Definition: process.cpp:28
std::map< std::string, std::string > Environment
For passing additional environment variables to set.
Definition: process.h:36
Signal< void()> _sigStarted
Definition: process.cpp:32
static Ptr create()
Definition: process.cpp:47
zypp::Pathname workingDirectory() const
Definition: process.cpp:247
bool isRunning()
Definition: process.cpp:145
static std::shared_ptr< EventDispatcher > instance()
void setUseDefaultLocale(bool defaultLocale)
Definition: process.cpp:202
Process::OutputChannelMode _channelMode
Definition: process.cpp:36
Process::OutputChannel _currentChannel
Definition: process.cpp:37
zypp::AutoFD _stdinFd
Definition: process.cpp:29
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:137
~Process() override
Definition: process.cpp:52
ZYPP_IMPL_PRIVATE(UnixSignalSource)
bool useDefaultLocale() const
Definition: process.cpp:197
void waitForExit()
Definition: process.cpp:159
zypp::AutoFD _stderrFd
Definition: process.cpp:30
bool openFds(const std::vector< int > &readFds, int writeFd=-1)
const std::string & executedCommand() const
Definition: process.cpp:177
bool switchPgid() const
Definition: process.cpp:237
Signal< void(int)> _sigFinished
Definition: process.cpp:33
void setOutputChannelMode(const OutputChannelMode &outputChannelMode)
Definition: process.cpp:298
void addFd(int fd)
Definition: process.cpp:262
void setDieWithParent(bool enabled)
Definition: process.cpp:232
#define DBG
Definition: Logger.h:95