X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=zypp%2FExternalProgram.h;h=f3e67a0ca5922d8b55033db7cf1772222e811f2b;hb=HEAD;hp=f33a6d601663316dd82c9a0ad391536f46461c40;hpb=a0683490efeff432f52582934dc7f44ef8890240;p=platform%2Fupstream%2Flibzypp.git diff --git a/zypp/ExternalProgram.h b/zypp/ExternalProgram.h index f33a6d6..5f46aa4 100644 --- a/zypp/ExternalProgram.h +++ b/zypp/ExternalProgram.h @@ -13,12 +13,15 @@ #ifndef ZYPP_EXTERNALPROGRAM_H #define ZYPP_EXTERNALPROGRAM_H +#include + #include #include #include -#include "zypp/base/ExternalDataSource.h" -#include "zypp/Pathname.h" +#include +#include +#include namespace zypp { @@ -83,7 +86,7 @@ namespace zypp { * @param commandline a shell commandline that is appended to * /bin/sh -c. * @param default_locale whether to set LC_ALL=C before starting - * @param root directory to chroot into, / or empty to not chroot + * @param root directory to chroot into; or just 'cd' if '/'l; nothing if empty */ ExternalProgram (std::string commandline, Stderr_Disposition stderr_disp = Normal_Stderr, @@ -94,7 +97,22 @@ namespace zypp { * 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. - * \throws ExternalProgramException if fork fails. + * + * 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[] = { "', the remaining + * part is treated as file opened for writing on standard output (or \c /dev/null + * if empty). */ ExternalProgram(); @@ -138,6 +156,11 @@ namespace zypp { bool kill(); /** + * Send a signal to the program + */ + bool kill( int sig ); + + /** * Return whether program is running */ bool running(); @@ -208,12 +231,97 @@ namespace zypp { /** Remember execution errors like failed fork/exec. */ std::string _execError; + protected: + 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); + const char* root = NULL, bool switch_pgid = false, bool die_with_parent = false ); + + }; + + 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 * fStdErr() { return _stderr; } + protected: + FILE * _stderr; + int _fds[2]; }; + } // namespace externalprogram + + /** ExternalProgram extended to offer reading programs stderr. + * \see \ref ExternalProgram + */ + class ExternalProgramWithStderr : private externalprogram::EarlyPipe, public ExternalProgram + { + public: + ExternalProgramWithStderr( const Arguments & argv_r, bool defaultLocale_r = false, const Pathname & root_r = "" ) + : ExternalProgram( argv_r, Stderr_To_FileDesc, /*use_pty*/false, _fds[W], defaultLocale_r, root_r ) + { _initStdErr(); } + /** \overlocad Convenience taking just the \a root_r. */ + ExternalProgramWithStderr( const Arguments & argv_r, const Pathname & root_r ) + : ExternalProgramWithStderr( argv_r, false, root_r ) + {} + + ExternalProgramWithStderr( const Arguments & argv_r, const Environment & environment_r, bool defaultLocale_r = false, const Pathname & root_r = "" ) + : ExternalProgram( argv_r, environment_r, Stderr_To_FileDesc, /*use_pty*/false, _fds[W], defaultLocale_r, root_r ) + { _initStdErr(); } + /** \overlocad Convenience taking just the \a root_r. */ + ExternalProgramWithStderr( const Arguments & argv_r, const Environment & environment_r, const Pathname & root_r ) + : ExternalProgramWithStderr( argv_r, environment_r, false, root_r ) + {} + public: + /** Return \c FILE* to read programms stderr (O_NONBLOCK set). */ + using externalprogram::EarlyPipe::fStdErr; + + /** 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; + }; + + /** ExternalProgram extended to change the progress group ID after forking. + * \see \ref ExternalProgram + */ + class ZYPP_LOCAL ExternalProgramWithSeperatePgid : public ExternalProgram + { + public: + ExternalProgramWithSeperatePgid (const char *const *argv, + Stderr_Disposition stderr_disp = Normal_Stderr, + int stderr_fd = -1, bool default_locale = false, + const Pathname& root = "") : ExternalProgram() + { + start_program( argv, Environment(), stderr_disp, stderr_fd, default_locale, root.c_str(), true ); + } + + }; } // namespace zypp