#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"
+#include <zypp/APIConfig.h>
+#include <zypp/base/ExternalDataSource.h>
+#include <zypp/Pathname.h>
namespace zypp {
* @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 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,
* 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).
* const char* argv[] = { "</tmp/x", "cat", NULL };
* ExternalProgram prog( argv );
* \endcode
+ *
+ * Stdout redirection: If the \b 1st argument starts with a \b '>', the remaining
+ * part is treated as file opened for writing on standard output (or \c /dev/null
+ * if empty).
*/
ExternalProgram();
bool kill();
/**
+ * Send a signal to the program
+ */
+ bool kill( int sig );
+
+ /**
* Return whether program is running
*/
bool running();
/** 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
+ namespace externalprogram
{
/** Helper providing pipe FDs for \ref ExternalProgramWithStderr.
* Moved to a basse class because the pipe needs to be initialized
EarlyPipe();
~EarlyPipe();
void closeW() { if ( _fds[W] != -1 ) { ::close( _fds[W] ); _fds[W] = -1; } }
- FILE * stderr() { return _stderr; }
+ 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
+ class ExternalProgramWithStderr : private externalprogram::EarlyPipe, public ExternalProgram
{
public:
- ExternalProgramWithStderr( const Arguments & argv_r )
- : ExternalProgram( argv_r, Stderr_To_FileDesc, /*use_pty*/false, _fds[W] )
+ 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 )
- : ExternalProgram( argv_r, environment_r, Stderr_To_FileDesc, /*use_pty*/false, _fds[W] )
+ 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(); }
-
- public:
+ /** \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::stderr;
+ 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.
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
#endif // ZYPP_EXTERNALPROGRAM_H