libzypp  17.36.3
abstractspawnengine.cc
Go to the documentation of this file.
5 #include <sys/types.h>
6 #include <sys/wait.h>
7 
9 
10 #undef ZYPP_BASE_LOGGER_LOGGROUP
11 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::exec"
12 
13 namespace zyppng {
14 
15 
16 #if ZYPP_HAS_GLIBSPAWNENGINE
17  namespace {
18 
19  enum class SpawnEngine {
20  GSPAWN,
21  PFORK
22  };
23 
24  SpawnEngine initEngineFromEnv () {
25  const std::string fBackend ( zypp::str::asString( ::getenv("ZYPP_FORK_BACKEND") ) );
26  if ( fBackend.empty() || fBackend == "auto" || fBackend == "pfork" ) {
27  DBG << "Starting processes via posix fork" << std::endl;
28  return SpawnEngine::PFORK;
29  } else if ( fBackend == "gspawn" ) {
30  DBG << "Starting processes via glib spawn" << std::endl;
31  return SpawnEngine::GSPAWN;
32  }
33 
34  DBG << "Falling back to starting process via posix fork" << std::endl;
35  return SpawnEngine::PFORK;
36  }
37 
38  std::unique_ptr<zyppng::AbstractSpawnEngine> engineFromEnv () {
39  static const SpawnEngine eng = initEngineFromEnv();
40  switch ( eng ) {
41  case SpawnEngine::GSPAWN:
42  return std::make_unique<zyppng::GlibSpawnEngine>();
43  case SpawnEngine::PFORK:
44  default:
45  return std::make_unique<zyppng::ForkSpawnEngine>();
46  }
47  }
48  }
49 #else
50 
51  std::unique_ptr<zyppng::AbstractSpawnEngine> engineFromEnv () {
52  return std::make_unique<zyppng::ForkSpawnEngine>();
53  }
54 
55 #endif
56 
58  {
59  }
60 
62  { }
63 
64  std::unique_ptr<AbstractSpawnEngine> AbstractSpawnEngine::createDefaultEngine()
65  {
66  return engineFromEnv();
67  }
68 
70  {
71  return _switchPgid;
72  }
73 
74  void AbstractSpawnEngine::setSwitchPgid(bool switchPgid)
75  {
77  }
78 
80  {
81  return _workingDirectory;
82  }
83 
85  {
87  }
88 
89  const std::vector<int> &AbstractSpawnEngine::fdsToMap() const
90  {
91  return _mapFds;
92  }
93 
95  {
96  _mapFds.push_back( fd );
97  }
98 
100  {
101  _exitStatus = checkStatus( status );
102  _pid = -1;
103  }
104 
106  {
107  return _dieWithParent;
108  }
109 
110  void AbstractSpawnEngine::setDieWithParent( bool dieWithParent )
111  {
113  }
114 
116  {
117  return _exitStatus;
118  }
119 
121  {
122  _exitStatus = state;
123  }
124 
125  const std::string &AbstractSpawnEngine::executedCommand() const
126  {
127  return _executedCommand;
128  }
129 
130  const std::string &AbstractSpawnEngine::execError() const
131  {
132  return _execError;
133  }
134 
135  void AbstractSpawnEngine::setExecError(const std::string &str)
136  {
137  _execError = str;
138  }
139 
141  {
142  return _chroot;
143  }
144 
146  {
147  _chroot = chroot;
148  }
149 
151  {
152  return _useDefaultLocale;
153  }
154 
155  void AbstractSpawnEngine::setUseDefaultLocale( bool defaultLocale )
156  {
157  _useDefaultLocale = defaultLocale;
158  }
159 
161  {
162  return _environment;
163  }
164 
166  {
168  }
169 
171  {
172  return _pid;
173  }
174 
176  {
177  if (WIFEXITED (status))
178  {
179  status = WEXITSTATUS (status);
180  if(status)
181  {
182  WAR << "Pid " << _pid << " exited with status " << status << std::endl;
183  _execError = zypp::str::form( _("Command exited with status %d."), status );
184  }
185  else
186  {
187  // if 'launch' is logged, completion should be logged,
188  // even if successfull.
189  DBG << "Pid " << _pid << " successfully completed" << std::endl;
190  _execError.clear(); // empty if running or successfully completed
191  }
192  }
193  else if (WIFSIGNALED (status))
194  {
195  status = WTERMSIG (status);
196  std::string sigdetail { strsignal(status) };
197  if ( WCOREDUMP(status) ) {
198  sigdetail += "; Core dumped";
199  }
200  if ( status == SIGKILL ) {
201  sigdetail += "; Out of memory?";
202  }
203  WAR << "Pid " << _pid << " was killed by signal " << status << " (" << sigdetail << ")" << std::endl;
204  _execError = zypp::str::form( _("Command was killed by signal %d (%s)."), status, sigdetail.c_str() );
205  status+=128;
206  }
207  else {
208  ERR << "Pid " << _pid << " exited with unknown error" << std::endl;
209  _execError = _("Command exited with unknown error.");
210  }
211  return status;
212  }
213 
214 } // namespace zyppng
zypp::Pathname workingDirectory() const
zypp::Pathname _workingDirectory
Working directory.
#define _(MSG)
Definition: Gettext.h:39
virtual void notifyExited(int status)
static std::unique_ptr< zyppng::AbstractSpawnEngine > createDefaultEngine()
std::string _execError
Remember execution errors like failed fork/exec.
const std::string & execError() const
String related utilities and Regular expression matching.
void setUseDefaultLocale(bool defaultLocale)
bool _dieWithParent
Should the process die with the parent process.
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Definition: String.h:139
void setWorkingDirectory(const zypp::Pathname &workingDirectory)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:37
void setExecError(const std::string &str)
#define ERR
Definition: Logger.h:102
void setEnvironment(const Environment &environment)
void setChroot(const zypp::Pathname &chroot)
zypp::Pathname _chroot
Path to chroot into.
#define WAR
Definition: Logger.h:101
void setDieWithParent(bool dieWithParent)
std::string _executedCommand
Store the command we&#39;re executing.
std::unique_ptr< zyppng::AbstractSpawnEngine > engineFromEnv()
zypp::Pathname chroot() const
void setExitStatus(const int state)
const std::string & executedCommand() const
void setSwitchPgid(bool switchPgid)
std::map< std::string, std::string > Environment
For passing additional environment variables to set.
std::vector< int > _mapFds
Additional file descriptors we want to map to the new process.
const std::vector< int > & fdsToMap() const
#define DBG
Definition: Logger.h:99
Environment _environment
Environment variables to set in the new process.