/usr/include/x86_64-linux-gnu/zypp/ExternalProgram.h is in libzypp-dev 14.29.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | /*---------------------------------------------------------------------\
| ____ _ __ __ ___ |
| |__ / \ / / . \ . \ |
| / / \ V /| _/ _/ |
| / /__ | | | | | | |
| /_____||_| |_| |_| |
| |
\---------------------------------------------------------------------*/
/** \file zypp/ExternalProgram.h
*/
#ifndef ZYPP_EXTERNALPROGRAM_H
#define ZYPP_EXTERNALPROGRAM_H
#include <unistd.h>
#include <map>
#include <string>
#include <vector>
#include "zypp/base/ExternalDataSource.h"
#include "zypp/Pathname.h"
namespace zypp {
/**
* @short Execute a program and give access to its io
* An object of this class encapsulates the execution of
* an external program. It starts the program using fork
* and some exec.. call, gives you access to the program's
* stdio and closes the program after use.
*
* \code
*
* const char* argv[] =
* {
* "/usr/bin/foo,
* "--option1",
* "--option2",
* NULL
* };
*
* ExternalProgram prog( argv,
* ExternalProgram::Discard_Stderr,
* false, -1, true);
* string line;
* for(line = prog.receiveLine();
* ! line.empty();
* line = prog.receiveLine() )
* {
* stream << line;
* }
* prog.close();
*
* \endcode
*/
class ExternalProgram : public zypp::externalprogram::ExternalDataSource
{
public:
typedef std::vector<std::string> Arguments;
/**
* Define symbols for different policies on the handling
* of stderr
*/
enum Stderr_Disposition {
Normal_Stderr,
Discard_Stderr,
Stderr_To_Stdout,
Stderr_To_FileDesc
};
/**
* For passing additional environment variables to set
*/
typedef std::map<std::string,std::string> Environment;
/**
* Start the external program by using the shell <tt>/bin/sh<tt>
* with the option <tt>-c</tt>. You can use io direction symbols < and >.
* @param commandline a shell commandline that is appended to
* <tt>/bin/sh -c</tt>.
* @param default_locale whether to set LC_ALL=C before starting
* @param root directory to chroot into; or just 'cd' if '/'l; nothing if empty
*/
ExternalProgram (std::string commandline,
Stderr_Disposition stderr_disp = Normal_Stderr,
bool use_pty = false, int stderr_fd = -1, bool default_locale = false,
const Pathname& root = "");
/**
* Start an external program by giving the arguments as an arry of char *pointers.
* If environment is provided, varaiables will be added to the childs environment,
* overwriting existing ones.
*
* Initial args starting with \c # are discarded but some are treated specially:
* #/[path] - chdir to /[path] before executing
*
* Stdin redirection: If the \b 1st argument starts with a \b '<', the remaining
* part is treated as file opened for reading on standard input (or \c /dev/null
* if empty).
* \code
* // cat file /tmp/x
* const char* argv[] = { "</tmp/x", "cat", NULL };
* ExternalProgram prog( argv );
* \endcode
*/
ExternalProgram();
ExternalProgram (const Arguments &argv,
Stderr_Disposition stderr_disp = Normal_Stderr,
bool use_pty = false, int stderr_fd = -1, bool default_locale = false,
const Pathname& root = "");
ExternalProgram (const Arguments &argv, const Environment & environment,
Stderr_Disposition stderr_disp = Normal_Stderr,
bool use_pty = false, int stderr_fd = -1, bool default_locale = false,
const Pathname& root = "");
ExternalProgram (const char *const *argv,
Stderr_Disposition stderr_disp = Normal_Stderr,
bool use_pty = false, int stderr_fd = -1, bool default_locale = false,
const Pathname& root = "");
ExternalProgram (const char *const *argv, const Environment & environment,
Stderr_Disposition stderr_disp = Normal_Stderr,
bool use_pty = false, int stderr_fd = -1, bool default_locale = false,
const Pathname& root = "");
ExternalProgram (const char *binpath, const char *const *argv_1,
bool use_pty = false);
ExternalProgram (const char *binpath, const char *const *argv_1, const Environment & environment,
bool use_pty = false);
~ExternalProgram();
/** Wait for the progamm to complete. */
int close();
/**
* Kill the program
*/
bool kill();
/**
* Return whether program is running
*/
bool running();
/**
* return pid
* */
pid_t getpid() { return pid; }
/** The command we're executing. */
const std::string & command() const
{ return _command; }
/** Some detail telling why the execution failed, if it failed.
* Empty if the command is still running or successfully completed.
*
* \li <tt>Can't open pty (%s).</tt>
* \li <tt>Can't open pipe (%s).</tt>
* \li <tt>Can't fork (%s).</tt>
* \li <tt>Command exited with status %d.</tt>
* \li <tt>Command was killed by signal %d (%s).</tt>
*/
const std::string & execError() const
{ return _execError; }
/**
* origfd will be accessible as newfd and closed (unless they were equal)
*/
static void renumber_fd (int origfd, int newfd);
public:
/**
* Redirect all command output to an \c ostream.
* Returns when the command has completed.
* \code
* std::ostringstream s;
* ExternalProgram("pwd") >> s;
* SEC << s.str() << endl;
* \endcode
* \code
* std::ostringstream s;
* ExternalProgram prog("ls -l wrzl");
* prog >> s;
* if ( prog.close() == 0 )
* MIL << s.str() << endl;
* else
* ERR << prog.execError() << endl;
* \endcode
*/
std::ostream & operator>>( std::ostream & out_r );
protected:
int checkStatus( int );
private:
/**
* Set to true, if a pair of ttys is used for communication
* instead of a pair of pipes.
*/
bool use_pty;
pid_t pid;
int _exitStatus;
/** Store the command we're executing. */
std::string _command;
/** Remember execution errors like failed fork/exec. */
std::string _execError;
void start_program (const char *const *argv, const Environment & environment,
Stderr_Disposition stderr_disp = Normal_Stderr,
int stderr_fd = -1, bool default_locale = false,
const char* root = NULL);
};
namespace _ExternalProgram
{
/** Helper providing pipe FDs for \ref ExternalProgramWithStderr.
* Moved to a basse class because the pipe needs to be initialized
* before the \ref ExternalProgram base class is initialized.
* \see \ref ExternalProgramWithStderr
*/
struct EarlyPipe
{
enum { R=0, W=1 };
EarlyPipe();
~EarlyPipe();
void closeW() { if ( _fds[W] != -1 ) { ::close( _fds[W] ); _fds[W] = -1; } }
FILE * stderr() { return _stderr; }
protected:
FILE * _stderr;
int _fds[2];
};
}
/** ExternalProgram extended to offer reading programs stderr.
* \see \ref ExternalProgram
*/
class ExternalProgramWithStderr : private _ExternalProgram::EarlyPipe, public ExternalProgram
{
public:
ExternalProgramWithStderr( const Arguments & argv_r )
: ExternalProgram( argv_r, Stderr_To_FileDesc, /*use_pty*/false, _fds[W] )
{ _initStdErr(); }
ExternalProgramWithStderr( const Arguments & argv_r, const Environment & environment_r )
: ExternalProgram( argv_r, environment_r, Stderr_To_FileDesc, /*use_pty*/false, _fds[W] )
{ _initStdErr(); }
public:
/** Return \c FILE* to read programms stderr (O_NONBLOCK set). */
using _ExternalProgram::EarlyPipe::stderr;
/** Read data up to \c delim_r from stderr (nonblocking).
* \note If \c delim_r is '\0', we read as much data as possible.
* \return \c false if data are not yet available (\c retval_r remains untouched then).
*/
bool stderrGetUpTo( std::string & retval_r, const char delim_r, bool returnDelim_r = false );
/** Read next complete line from stderr (nonblocking).
* \return \c false if data are not yet available (\c retval_r remains untouched then).
*/
bool stderrGetline( std::string & retval_r, bool returnDelim_r = false )
{ return stderrGetUpTo( retval_r, '\n', returnDelim_r ); }
private:
/** Close write end of the pipe (childs end). */
void _initStdErr()
{ closeW(); }
private:
std::string _buffer;
};
} // namespace zypp
#endif // ZYPP_EXTERNALPROGRAM_H
|