12 #include <sys/types.h>
36 const char * PLUGIN_DEBUG = getenv(
"ZYPP_PLUGIN_DEBUG" );
41 struct PluginDebugBuffer
43 PluginDebugBuffer(
const std::string & buffer_r ) :
_buffer( buffer_r ) {}
50 _DBG(
"PLUGIN") <<
"< (empty)" << endl;
54 std::istringstream datas(
_buffer );
65 struct PluginDumpStderr
67 PluginDumpStderr( ExternalProgramWithStderr & prog_r ) :
_prog( prog_r ) {}
71 while (
_prog.stderrGetline( line ) )
72 _WAR(
"PLUGIN") <<
"! " << line << endl;
74 ExternalProgramWithStderr &
_prog;
77 inline void setBlocking( FILE * file_r,
bool yesno_r =
true )
80 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
82 int fd = ::fileno( file_r );
84 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
86 int flags = ::fcntl( fd, F_GETFL );
88 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
92 else if ( flags & O_NONBLOCK )
95 flags = ::fcntl( fd, F_SETFL, flags );
97 ZYPP_THROW( PluginScriptException(
"setNonBlocking" ) );
100 inline void setNonBlocking( FILE * file_r,
bool yesno_r =
true )
101 { setBlocking( file_r, !yesno_r ); }
120 {
try {
close(); }
catch(...) {} }
160 scoped_ptr<ExternalProgramWithStderr>
_cmd;
170 obj.
args().begin(), obj.
args().end() );
177 const long PLUGIN_TIMEOUT = str::strtonum<long>( getenv(
"ZYPP_PLUGIN_TIMEOUT" ) );
178 const long PLUGIN_SEND_TIMEOUT = str::strtonum<long>( getenv(
"ZYPP_PLUGIN_SEND_TIMEOUT" ) );
179 const long PLUGIN_RECEIVE_TIMEOUT = str::strtonum<long>( getenv(
"ZYPP_PLUGIN_RECEIVE_TIMEOUT" ) );
183 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
185 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
191 dumpRangeLine(
DBG <<
"Open " << script_r, args_r.begin(), args_r.end() ) << endl;
197 PathInfo pi( script_r );
198 if ( ! ( pi.isFile() && pi.isX() ) )
205 args.reserve( args_r.size()+1 );
206 args.push_back( script_r.asString() );
207 args.insert( args.end(), args_r.begin(), args_r.end() );
211 setNonBlocking(
_cmd->outputFile() );
212 setNonBlocking(
_cmd->inputFile() );
220 DBG << *
this << endl;
227 DBG <<
"Close:" << *
this << endl;
237 _lastExecError = ret.
body();
246 _lastReturn = _cmd->close();
247 _lastExecError = _cmd->execError();
249 DBG << *
this <<
" -> [" << _lastReturn <<
"] " << _lastExecError << endl;
260 if ( frame_r.
command().empty() )
261 WAR <<
"Send: No command in frame" << frame_r << endl;
266 std::ostringstream datas;
268 datas.str().swap( data );
270 DBG <<
"->send " << frame_r << endl;
274 std::istringstream datas( data );
279 FILE * filep = _cmd->outputFile();
283 int fd = ::fileno( filep );
289 PluginDumpStderr _dump( *_cmd );
291 const char * buffer = data.c_str();
292 ssize_t buffsize = data.size();
299 tv.tv_sec = _sendTimeout;
302 int retval = select( fd+1, NULL, &wfds, NULL, &tv );
306 ssize_t ret =
::write( fd, buffer, buffsize );
307 if ( ret == buffsize )
322 if ( errno != EINTR )
324 ERR <<
"write(): " <<
Errno() << endl;
325 if ( errno == EPIPE )
332 else if ( retval == 0 )
334 WAR <<
"Not ready to write within timeout." << endl;
335 ZYPP_THROW( PluginScriptSendTimeout(
"Not ready to write within timeout." ) );
339 if ( errno != EINTR )
341 ERR <<
"select(): " <<
Errno() << endl;
355 FILE * filep = _cmd->inputFile();
359 int fd = ::fileno( filep );
366 PluginDebugBuffer _debug( data );
367 PluginDumpStderr _dump( *_cmd );
369 int ch = fgetc( filep );
372 data.push_back( ch );
376 else if ( ::feof( filep ) )
378 WAR <<
"Unexpected EOF" << endl;
381 else if ( errno != EINTR )
383 if ( errno == EWOULDBLOCK )
391 tv.tv_sec = _receiveTimeout;
394 int retval = select( fd+1, &rfds, NULL, NULL, &tv );
399 else if ( retval == 0 )
401 WAR <<
"Not ready to read within timeout." << endl;
402 ZYPP_THROW( PluginScriptReceiveTimeout(
"Not ready to read within timeout." ) );
406 if ( errno != EINTR )
408 ERR <<
"select(): " <<
Errno() << endl;
415 ERR <<
"read(): " <<
Errno() << endl;
422 std::istringstream datas( data );
424 DBG <<
"<-" << ret << endl;
465 : _pimpl( new
Impl( script_r ) )
469 : _pimpl( new
Impl( script_r, args_r ) )
511 {
return str << *obj.
_pimpl; }