20#include <zypp/base/LogTools.h>
21#include <zypp-core/base/DefaultIntegral>
22#include <zypp/base/String.h>
24#include <zypp/base/IOStream.h>
27#include <zypp/ExternalProgram.h>
28#include <zypp/PathInfo.h>
32#undef ZYPP_BASE_LOGGER_LOGGROUP
33#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::plugin"
41 const char * PLUGIN_DEBUG = getenv(
"ZYPP_PLUGIN_DEBUG" );
46 struct PluginDebugBuffer
48 PluginDebugBuffer(
const std::string & buffer_r ) :
_buffer( buffer_r ) {}
55 L_DBG(
"PLUGIN") <<
"< (empty)" << endl;
59 std::istringstream datas(
_buffer );
70 struct PluginDumpStderr
72 PluginDumpStderr( ExternalProgramWithStderr & prog_r ) :
_prog( prog_r ) {}
76 while (
_prog.stderrGetline( line ) )
77 L_WAR(
"PLUGIN") <<
"! " << line << endl;
79 ExternalProgramWithStderr &
_prog;
82 inline void setBlocking( FILE * file_r,
bool yesno_r =
true )
85 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
87 int fd = ::fileno( file_r );
89 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
91 int flags = ::fcntl( fd, F_GETFL );
93 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
97 else if ( flags & O_NONBLOCK )
100 flags = ::fcntl( fd, F_SETFL, flags );
102 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
105 inline void setNonBlocking( FILE * file_r,
bool yesno_r =
true )
106 { setBlocking( file_r, !yesno_r ); }
125 {
try {
close(); }
catch(...) {} }
145 {
return _cmd !=
nullptr; }
174 return str <<
"PluginScript[" <<
obj.getPid() <<
"] " <<
obj.script();
187 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
189 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
202 if ( ! (
pi.isFile() &&
pi.isX() ) )
231 DBG <<
"Close:" << *
this << endl;
237 if (
ret.isAckCommand() )
241 _lastExecError =
ret.body();
250 _lastReturn = _cmd->close();
251 _lastExecError = _cmd->execError();
253 DBG << *
this <<
" -> [" << _lastReturn <<
"] " << _lastExecError << endl;
264 if (
frame_r.command().empty() )
265 WAR <<
"Send: No command in frame" <<
frame_r << endl;
270 std::ostringstream
datas;
274 DBG << *
this <<
" ->send " <<
frame_r << endl;
278 std::istringstream
datas( data );
293 PluginDumpStderr
_dump( *_cmd );
295 const char *
buffer = data.c_str();
325 ERR <<
"write(): " <<
Errno() << endl;
335 WAR <<
"Not ready to write within timeout." << endl;
342 ERR <<
"select(): " <<
Errno() << endl;
367 PluginDebugBuffer _debug( data );
368 PluginDumpStderr
_dump( *_cmd );
373 data.push_back(
ch );
377 else if ( ::feof(
filep ) )
379 WAR <<
"Unexpected EOF" << endl;
399 WAR <<
"Not ready to read within timeout." << endl;
406 ERR <<
"select(): " <<
Errno() << endl;
413 ERR <<
"read(): " <<
Errno() << endl;
420 std::istringstream
datas( data );
422 DBG << *
this <<
" <-" <<
ret << endl;
447 {
return _pimpl->_sendTimeout; }
450 {
return _pimpl->_receiveTimeout; }
471 {
return _pimpl->script(); }
474 {
return _pimpl->args(); }
477 {
return _pimpl->isOpen(); }
480 {
return _pimpl->getPid(); }
483 {
return _pimpl->lastReturn(); }
486 {
return _pimpl->lastExecError(); }
498 {
return _pimpl->close(); }
504 {
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 reset()
Reset to default Ctor values.
shared_ptr< Impl > _pimpl
void swap(AutoDispose &rhs)
Exchange the contents of two AutoDispose objects.
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.
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.
std::vector< std::string > Arguments
Commandline arguments passed to a script on open.
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
DefaultIntegral< int, 0 > _lastReturn
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
static long _defaultReceiveTimeout
const std::string & lastExecError() const
Impl(const Pathname &script_r=Pathname(), const 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.