22#include <zypp-core/base/DefaultIntegral>
33#undef ZYPP_BASE_LOGGER_LOGGROUP
34#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::plugin"
42 const char * PLUGIN_DEBUG = getenv(
"ZYPP_PLUGIN_DEBUG" );
47 struct PluginDebugBuffer
49 PluginDebugBuffer(
const std::string &buffer_r) :
_buffer(buffer_r) {}
50 PluginDebugBuffer(
const PluginDebugBuffer &) =
delete;
51 PluginDebugBuffer(PluginDebugBuffer &&) =
delete;
52 PluginDebugBuffer &operator=(
const PluginDebugBuffer &) =
delete;
53 PluginDebugBuffer &operator=(PluginDebugBuffer &&) =
delete;
60 L_DBG(
"PLUGIN") <<
"< (empty)" << endl;
64 std::istringstream datas(
_buffer );
75 struct PluginDumpStderr
77 PluginDumpStderr(ExternalProgramWithStderr &prog_r) :
_prog(prog_r) {}
78 PluginDumpStderr(
const PluginDumpStderr &) =
delete;
79 PluginDumpStderr(PluginDumpStderr &&) =
delete;
80 PluginDumpStderr &operator=(
const PluginDumpStderr &) =
delete;
81 PluginDumpStderr &operator=(PluginDumpStderr &&) =
delete;
85 while (
_prog.stderrGetline( line ) )
86 L_WAR(
"PLUGIN") <<
"! " << line << endl;
88 ExternalProgramWithStderr &
_prog;
91 inline void setBlocking( FILE * file_r,
bool yesno_r =
true )
94 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
96 int fd = ::fileno( file_r );
98 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
100 int flags = ::fcntl( fd, F_GETFL );
102 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
106 else if ( flags & O_NONBLOCK )
109 flags = ::fcntl( fd, F_SETFL, flags );
111 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
114 inline void setNonBlocking( FILE * file_r,
bool yesno_r =
true )
115 { setBlocking( file_r, !yesno_r ); }
163 {
return _cmd !=
nullptr; }
192 return str <<
"PluginScript[" <<
obj.getPid() <<
"] " <<
obj.script();
205 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
207 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
220 if ( ! (
pi.isFile() &&
pi.isX() ) )
249 DBG <<
"Close:" << *
this << endl;
255 if (
ret.isAckCommand() )
259 _lastExecError =
ret.body().asString();
268 _lastReturn = _cmd->close();
269 _lastExecError = _cmd->execError();
271 DBG << *
this <<
" -> [" << _lastReturn <<
"] " << _lastExecError << endl;
282 if (
frame_r.command().empty() )
283 WAR <<
"Send: No command in frame" <<
frame_r << endl;
288 std::ostringstream
datas;
292 DBG << *
this <<
" ->send " <<
frame_r << endl;
296 std::istringstream
datas( data );
301 FILE *
filep = _cmd->outputFile();
311 PluginDumpStderr
_dump( *_cmd );
313 const char *
buffer = data.c_str();
344 ERR <<
"write(): " <<
Errno() << endl;
354 WAR <<
"Not ready to write within timeout." << endl;
361 ERR <<
"select(): " <<
Errno() << endl;
375 FILE *
filep = _cmd->inputFile();
386 PluginDebugBuffer _debug( data );
387 PluginDumpStderr
_dump( *_cmd );
392 data.push_back(
ch );
396 else if ( ::feof(
filep ) )
398 WAR <<
"Unexpected EOF" << endl;
418 WAR <<
"Not ready to read within timeout." << endl;
425 ERR <<
"select(): " <<
Errno() << endl;
432 ERR <<
"read(): " <<
Errno() << endl;
439 std::istringstream
datas( data );
441 DBG << *
this <<
" <-" <<
ret << endl;
466 {
return _pimpl->_sendTimeout; }
469 {
return _pimpl->_receiveTimeout; }
490 {
return _pimpl->script(); }
493 {
return _pimpl->args(); }
496 {
return _pimpl->isOpen(); }
499 {
return _pimpl->getPid(); }
502 {
return _pimpl->lastReturn(); }
505 {
return _pimpl->lastExecError(); }
517 {
return _pimpl->close(); }
523 {
return _pimpl->receive(); }
ExternalProgramWithStderr & _prog
const std::string & _buffer
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
void swap(AutoDispose &rhs) noexcept
Exchange the contents of two AutoDispose objects.
void reset()
Reset to default Ctor values.
shared_ptr< Impl > _pimpl
DefaultIntegral & reset()
Reset to the defined initial value.
Convenience errno wrapper.
ExternalProgram extended to offer reading programs stderr.
Command frame for communication with PluginScript.
Base class for PluginScript Exception.
Interface to plugin scripts using a Stomp inspired communication protocol.
PluginFrame receive() const
Receive a PluginFrame.
std::vector< std::string > Arguments
Commandline arguments passed to a script on open.
long sendTimeout() const
Local default timeout (sec.) when sending data.
void send(const PluginFrame &frame_r) const
Send a PluginFrame.
PluginScript()
Default ctor.
RW_pointer< Impl > _pimpl
Pointer to implementation.
int lastReturn() const
Remembers a scripts return value after close until next open.
static long defaultReceiveTimeout()
Global default timeout (sec.) when receiving data.
static const pid_t NotConnected
pid_t(-1) constant indicating no connection.
int close()
Close any open connection.
const std::string & lastExecError() const
Remembers a scripts execError string after close until next open.
pid_t getPid() const
Return a connected scripts pid or NotConnected.
void open()
Setup connection and execute script.
const Pathname & script() const
Return the script path if set.
static long defaultSendTimeout()
Global default timeout (sec.) when sending data.
bool isOpen() const
Whether we are connected to a script.
long receiveTimeout() const
Local default timeout (sec.) when receiving data.
const Arguments & args() const
Return the script arguments if set.
Exception safe signal handler save/restore.
Wrapper class for stat/lstat.
String related utilities and Regular expression matching.
std::ostream & copyIndent(std::istream &from_r, std::ostream &to_r, const std::string &indent_r="> ")
Copy istream to ostream, prefixing each line with indent_r (default "> " ).
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Easy-to use interface to the ZYPP dependency resolver.
std::ostream & dumpRangeLine(std::ostream &str, TIterator begin, TIterator end)
Print range defined by iterators (single line style).
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
PluginScript implementation.
PluginFrame receive() const
std::string _lastExecError
static long _defaultSendTimeout
Impl(const Impl &)=delete
DefaultIntegral< int, 0 > _lastReturn
Impl & operator=(const Impl &)=delete
const Pathname & script() const
scoped_ptr< ExternalProgramWithStderr > _cmd
void open(const Pathname &script_r=Pathname(), const Arguments &args_r=Arguments())
void send(const PluginFrame &frame_r) const
Impl & operator=(Impl &&)=delete
static long _defaultReceiveTimeout
const std::string & lastExecError() const
Impl(Pathname &&script_r=Pathname(), Arguments &&args_r=Arguments())
const Arguments & args() const
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.