libzypp: zypp/PluginScript.cc Source File

libzypp 17.25.10

PluginScript.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <sys/types.h>
13 #include <signal.h>
14
15 #include <iostream>
16 #include <sstream>
17
18 #include <zypp/base/LogTools.h>
19 #include <zypp/base/DefaultIntegral.h>
20 #include <zypp/base/String.h>
21 #include <zypp/base/Signal.h>
22 #include <zypp/base/IOStream.h>
23
24 #include <zypp/PluginScript.h>
25 #include <zypp/ExternalProgram.h>
26 #include <zypp/PathInfo.h>
27
28 using std::endl;
29
30 #undef ZYPP_BASE_LOGGER_LOGGROUP
31 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::plugin"
32
34 namespace zypp
35 {
36
37 namespace
38 {
39 const char * PLUGIN_DEBUG = getenv( "ZYPP_PLUGIN_DEBUG" );
40
44 struct PluginDebugBuffer
45 {
46 PluginDebugBuffer( const std::string & buffer_r ) : _buffer( buffer_r ) {}
47 ~~PluginDebugBuffer()
48 {
49 if ( PLUGIN_DEBUG )
50 {
51 if ( _buffer.empty() )
52 {
53 L_DBG("PLUGIN") << "< (empty)" << endl;
54 }
55 else
56 {
57 std::istringstream datas( _buffer );
58 iostr::copyIndent( datas, L_DBG("PLUGIN"), "< " ) << endl;
59 }
60 }
61 }
62 const std::string & _buffer;
63 };
64
68 struct PluginDumpStderr
69 {
70 PluginDumpStderr( ExternalProgramWithStderr & prog_r ) : _prog( prog_r ) {}
71 ~~PluginDumpStderr()
72 {
73 std::string line;
74 while ( _prog.stderrGetline( line ) )
75 L_WAR("PLUGIN") << "! " << line << endl;
76 }
77 ExternalProgramWithStderr & _prog;
78 };
79
80 inline void setBlocking( FILE * file_r, bool yesno_r = true )
81 {
82 if ( ! file_r )
83 ZYPP_THROW( PluginScriptException( "setNonBlocking" ) );
84
85 int fd = ::fileno( file_r );
86 if ( fd == -1 )
87 ZYPP_THROW( PluginScriptException( "setNonBlocking" ) );
88
89 int flags = ::fcntl( fd, F_GETFL );
90 if ( flags == -1 )
91 ZYPP_THROW( PluginScriptException( "setNonBlocking" ) );
92
93 if ( ! yesno_r )
94 flags |= O_NONBLOCK;
95 else if ( flags & O_NONBLOCK )
96 flags ^= O_NONBLOCK;
97
98 flags = ::fcntl( fd, F_SETFL, flags );
99 if ( flags == -1 )
100 ZYPP_THROW( PluginScriptException( "setNonBlocking" ) );
101 }
102
103 inline void setNonBlocking( FILE * file_r, bool yesno_r = true )
104 { setBlocking( file_r, !yesno_r ); }
105 }
106
108 //
109 // CLASS NAME : PluginScript::Impl
110 //
112 struct PluginScript::Impl
113 {
114 public:
115 Impl( const Pathname & script_r = Pathname(), const Arguments & args_r = Arguments() )
116 : _sendTimeout( _defaultSendTimeout )
117 , _receiveTimeout( _defaultReceiveTimeout )
118 , _script( script_r )
119 , _args( args_r )
120 {}
121
122 ~ Impl()
123 { try { close(); } catch(...) {} }
124
125 public:
126 static long _defaultSendTimeout;
127 static long _defaultReceiveTimeout;
128
129 long _sendTimeout;
130 long _receiveTimeout;
131
132 public:
133 const Pathname & script() const
134 { return _script; }
135
136 const Arguments & args() const
137 { return _args; }
138
139 pid_t getPid() const
140 { return _cmd ? _cmd->getpid() : NotConnected; }
141
142 bool isOpen() const
143 { return _cmd != nullptr; }
144
145 int lastReturn() const
146 { return _lastReturn; }
147
148 const std::string & lastExecError() const
149 { return _lastExecError; }
150
151 public:
152 void open( const Pathname & script_r = Pathname(), const Arguments & args_r = Arguments() );
153
154 int close();
155
156 void send( const PluginFrame & frame_r ) const;
157
158 PluginFrame receive() const;
159
160 private:
161 Pathname _script;
162 Arguments _args;
163 scoped_ptr<ExternalProgramWithStderr> _cmd;
164 DefaultIntegral<int,0> _lastReturn;
165 std::string _lastExecError;
166 };
168
170 inline std::ostream & operator<<( std::ostream & str, const PluginScript::Impl & obj )
171 {
172 return str << "PluginScript[" << obj.getPid() << "] " << obj.script();
173 }
174
176
177 namespace
178 {
179 const long PLUGIN_TIMEOUT = str::strtonum<long>( getenv( "ZYPP_PLUGIN_TIMEOUT" ) );
180 const long PLUGIN_SEND_TIMEOUT = str::strtonum<long>( getenv( "ZYPP_PLUGIN_SEND_TIMEOUT" ) );
181 const long PLUGIN_RECEIVE_TIMEOUT = str::strtonum<long>( getenv( "ZYPP_PLUGIN_RECEIVE_TIMEOUT" ) );
182 }
183
184 long PluginScript::Impl::_defaultSendTimeout = ( PLUGIN_SEND_TIMEOUT > 0 ? PLUGIN_SEND_TIMEOUT
185 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
186 long PluginScript::Impl::_defaultReceiveTimeout = ( PLUGIN_RECEIVE_TIMEOUT > 0 ? PLUGIN_RECEIVE_TIMEOUT
187 : ( PLUGIN_TIMEOUT > 0 ? PLUGIN_TIMEOUT : 30 ) );
188
190
191 void PluginScript::Impl::open( const Pathname & script_r, const Arguments & args_r )
192 {
193 dumpRangeLine( DBG << "Open " << script_r, args_r.begin(), args_r.end() ) << endl;
194
195 if ( _cmd )
196 ZYPP_THROW( PluginScriptException( "Already connected", str::Str() << *this ) );
197
198 {
199 PathInfo pi( script_r );
200 if ( ! ( pi.isFile() && pi.isX() ) )
201 ZYPP_THROW( PluginScriptException( "Script is not executable", str::Str() << pi ) );
202 }
203
204 // go and launch script
205 // TODO: ExternalProgram::maybe use Stderr_To_FileDesc for script loging
206 Arguments args;
207 args.reserve( args_r.size()+1 );
208 args.push_back( script_r.asString() );
209 args.insert( args.end(), args_r.begin(), args_r.end() );
210 _cmd.reset( new ExternalProgramWithStderr( args ) );
211
212 // Be protected against full pipe, etc.
213 setNonBlocking( _cmd->outputFile() );
214 setNonBlocking( _cmd->inputFile() );
215
216 // store running scripts data
217 _script = script_r;
218 _args = args_r;
219 _lastReturn.reset();
220 _lastExecError.clear();
221
222 dumpRangeLine( DBG << *this, _args.begin(), _args.end() ) << endl;
223 }
224
225 int PluginScript::Impl::close()
226 {
227 if ( _cmd )
228 {
229 DBG << "Close:" << *this << endl;
230 bool doKill = true;
231 try {
232 // do not kill script if _DISCONNECT is ACKed.
233 send( PluginFrame( "_DISCONNECT" ) );
234 PluginFrame ret( receive() );
235 if ( ret.isAckCommand() )
236 {
237 doKill = false;
238 str::strtonum( ret.getHeaderNT( "exit" ), _lastReturn.get() );
239 _lastExecError = ret.body();
240 }
241 }
242 catch (...)
243 { /* NOP */ }
244
245 if ( doKill )
246 {
247 _cmd->kill();
248 _lastReturn = _cmd->close();
249 _lastExecError = _cmd->execError();
250 }
251 DBG << *this << " -> [" << _lastReturn << "] " << _lastExecError << endl;
252 _cmd.reset();
253 }
254 return _lastReturn;
255 }
256
257 void PluginScript::Impl::send( const PluginFrame & frame_r ) const
258 {
259 if ( !_cmd )
260 ZYPP_THROW( PluginScriptNotConnected( "Not connected", str::Str() << *this ) );
261
262 if ( frame_r.command().empty() )
263 WAR << "Send: No command in frame" << frame_r << endl;
264
265 // prepare frame data to write
266 std::string data;
267 {
268 std::ostringstream datas;
269 frame_r.writeTo( datas );
270 datas.str().swap( data );
271 }
272 DBG << *this << " ->send " << frame_r << endl;
273
274 if ( PLUGIN_DEBUG )
275 {
276 std::istringstream datas( data );
277 iostr::copyIndent( datas, L_DBG("PLUGIN") ) << endl;
278 }
279
280 // try writing the pipe....
281 FILE * filep = _cmd->outputFile();
282 if ( ! filep )
283 ZYPP_THROW( PluginScriptException( "Bad file pointer." ) );
284
285 int fd = ::fileno( filep );
286 if ( fd == -1 )
287 ZYPP_THROW( PluginScriptException( "Bad file descriptor" ) );
288
289 //DBG << " ->[" << fd << " " << (::feof(filep)?'e':'_') << (::ferror(filep)?'F':'_') << "]" << endl;
290 {
291 PluginDumpStderr _dump( *_cmd ); // dump scripts stderr before leaving
292 SignalSaver sigsav( SIGPIPE, SIG_IGN );
293 const char * buffer = data.c_str();
294 ssize_t buffsize = data.size();
295 do {
296 fd_set wfds;
297 FD_ZERO( &wfds );
298 FD_SET( fd, &wfds );
299
300 struct timeval tv;
301 tv.tv_sec = _sendTimeout;
302 tv.tv_usec = 0;
303
304 int retval = select( fd+1, NULL, &wfds, NULL, &tv );
305 if ( retval > 0 ) // FD_ISSET( fd, &wfds ) will be true.
306 {
307 //DBG << "Ready to write..." << endl;
308 ssize_t ret = ::write( fd, buffer, buffsize );
309 if ( ret == buffsize )
310 {
311 //DBG << "::write(" << buffsize << ") -> " << ret << endl;
312 ::fflush( filep );
313 break; // -> done
314 }
315 else if ( ret > 0 )
316 {
317 //WAR << "::write(" << buffsize << ") -> " << ret << " INCOMPLETE..." << endl;
318 ::fflush( filep );
319 buffsize -= ret;
320 buffer += ret; // -> continue
321 }
322 else // ( retval == -1 )
323 {
324 if ( errno != EINTR )
325 {
326 ERR << "write(): " << Errno() << endl;
327 if ( errno == EPIPE )
328 ZYPP_THROW( PluginScriptDiedUnexpectedly( "Send: script died unexpectedly", str::Str() << Errno() ) );
329 else
330 ZYPP_THROW( PluginScriptException( "Send: send error", str::Str() << Errno() ) );
331 }
332 }
333 }
334 else if ( retval == 0 )
335 {
336 WAR << "Not ready to write within timeout." << endl;
337 ZYPP_THROW( PluginScriptSendTimeout( "Not ready to write within timeout." ) );
338 }
339 else // ( retval == -1 )
340 {
341 if ( errno != EINTR )
342 {
343 ERR << "select(): " << Errno() << endl;
344 ZYPP_THROW( PluginScriptException( "Error waiting on file descriptor", str::Str() << Errno() ) );
345 }
346 }
347 } while( true );
348 }
349 }
350
351 PluginFrame PluginScript::Impl::receive() const
352 {
353 if ( !_cmd )
354 ZYPP_THROW( PluginScriptNotConnected( "Not connected", str::Str() << *this ) );
355
356 // try reading the pipe....
357 FILE * filep = _cmd->inputFile();
358 if ( ! filep )
359 ZYPP_THROW( PluginScriptException( "Bad file pointer." ) );
360
361 int fd = ::fileno( filep );
362 if ( fd == -1 )
363 ZYPP_THROW( PluginScriptException( "Bad file descriptor" ) );
364
365 ::clearerr( filep );
366 std::string data;
367 {
368 PluginDebugBuffer _debug( data ); // dump receive buffer if PLUGIN_DEBUG
369 PluginDumpStderr _dump( *_cmd ); // dump scripts stderr before leaving
370 do {
371 int ch = fgetc( filep );
372 if ( ch != EOF )
373 {
374 data.push_back( ch );
375 if ( ch == '\0' )
376 break;
377 }
378 else if ( ::feof( filep ) )
379 {
380 WAR << "Unexpected EOF" << endl;
381 ZYPP_THROW( PluginScriptDiedUnexpectedly( "Receive: script died unexpectedly", str::Str() << Errno() ) );
382 }
383 else if ( errno != EINTR )
384 {
385 if ( errno == EWOULDBLOCK )
386 {
387 // wait a while for fd to become ready for reading...
388 fd_set rfds;
389 FD_ZERO( &rfds );
390 FD_SET( fd, &rfds );
391
392 struct timeval tv;
393 tv.tv_sec = _receiveTimeout;
394 tv.tv_usec = 0;
395
396 int retval = select( fd+1, &rfds, NULL, NULL, &tv );
397 if ( retval > 0 ) // FD_ISSET( fd, &rfds ) will be true.
398 {
399 ::clearerr( filep );
400 }
401 else if ( retval == 0 )
402 {
403 WAR << "Not ready to read within timeout." << endl;
404 ZYPP_THROW( PluginScriptReceiveTimeout( "Not ready to read within timeout." ) );
405 }
406 else // ( retval == -1 )
407 {
408 if ( errno != EINTR )
409 {
410 ERR << "select(): " << Errno() << endl;
411 ZYPP_THROW( PluginScriptException( "Error waiting on file descriptor", str::Str() << Errno() ) );
412 }
413 }
414 }
415 else
416 {
417 ERR << "read(): " << Errno() << endl;
418 ZYPP_THROW( PluginScriptException( "Receive: receive error", str::Str() << Errno() ) );
419 }
420 }
421 } while ( true );
422 }
423 // DBG << " <-read " << data.size() << endl;
424 std::istringstream datas( data );
425 PluginFrame ret( datas );
426 DBG << *this << " <-" << ret << endl;
427 return ret;
428 }
429
431 //
432 // CLASS NAME : PluginScript
433 //
435
436 const pid_t PluginScript::NotConnected( -1 );
437
438 long PluginScript::defaultSendTimeout()
439 { return Impl::_defaultSendTimeout; }
440
441 long PluginScript::defaultReceiveTimeout()
442 { return Impl::_defaultReceiveTimeout; }
443
444 void PluginScript::defaultSendTimeout( long newval_r )
445 { Impl::_defaultSendTimeout = newval_r > 0 ? newval_r : 0; }
446
447 void PluginScript::defaultReceiveTimeout( long newval_r )
448 { Impl::_defaultReceiveTimeout = newval_r > 0 ? newval_r : 0; }
449
450 long PluginScript::sendTimeout() const
451 { return _pimpl->_sendTimeout; }
452
453 long PluginScript::receiveTimeout() const
454 { return _pimpl->_receiveTimeout; }
455
456 void PluginScript::sendTimeout( long newval_r )
457 { _pimpl->_sendTimeout = newval_r > 0 ? newval_r : 0; }
458
459 void PluginScript::receiveTimeout( long newval_r )
460 { _pimpl->_receiveTimeout = newval_r > 0 ? newval_r : 0; }
461
462 PluginScript::PluginScript()
463 : _pimpl( new Impl )
464 {}
465
466 PluginScript::PluginScript( const Pathname & script_r )
467 : _pimpl( new Impl( script_r ) )
468 {}
469
470 PluginScript::PluginScript( const Pathname & script_r, const Arguments & args_r )
471 : _pimpl( new Impl( script_r, args_r ) )
472 {}
473
474 const Pathname & PluginScript::script() const
475 { return _pimpl->script(); }
476
477 const PluginScript::Arguments & PluginScript::args() const
478 { return _pimpl->args(); }
479
480 bool PluginScript::isOpen() const
481 { return _pimpl->isOpen(); }
482
483 pid_t PluginScript::getPid() const
484 { return _pimpl->getPid(); }
485
486 int PluginScript::lastReturn() const
487 { return _pimpl->lastReturn(); }
488
489 const std::string & PluginScript::lastExecError() const
490 { return _pimpl->lastExecError(); }
491
492 void PluginScript::open()
493 { _pimpl->open( _pimpl->script(), _pimpl->args() ); }
494
495 void PluginScript::open( const Pathname & script_r )
496 { _pimpl->open( script_r ); }
497
498 void PluginScript::open( const Pathname & script_r, const Arguments & args_r )
499 { _pimpl->open( script_r, args_r ); }
500
501 int PluginScript::close()
502 { return _pimpl->close(); }
503
504 void PluginScript::send( const PluginFrame & frame_r ) const
505 { _pimpl->send( frame_r ); }
506
507 PluginFrame PluginScript::receive() const
508 { return _pimpl->receive(); }
509
511
512 std::ostream & operator<<( std::ostream & str, const PluginScript & obj )
513 { return str << *obj._pimpl; }
514
516 } // namespace zypp
DefaultIntegral.h
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
ExternalProgram.h
IOStream.h
LogTools.h
DBG
#define DBG
Definition: Logger.h:90
ERR
#define ERR
Definition: Logger.h:93
L_WAR
#define L_WAR(GROUP)
Definition: Logger.h:101
WAR
#define WAR
Definition: Logger.h:92
L_DBG
#define L_DBG(GROUP)
Definition: Logger.h:99
PathInfo.h
_prog
ExternalProgramWithStderr & _prog
Definition: PluginScript.cc:77
_buffer
const std::string & _buffer
Definition: PluginScript.cc:62
PluginScript.h
Signal.h
String.h
zypp::DefaultIntegral
Integral type with defined initial value when default constructed.
Definition: DefaultIntegral.h:42
zypp::Errno
Convenience errno wrapper.
Definition: Errno.h:26
zypp::ExternalProgramWithStderr
ExternalProgram extended to offer reading programs stderr.
Definition: ExternalProgram.h:268
zypp::PluginFrame
Command frame for communication with PluginScript.
Definition: PluginFrame.h:41
zypp::PluginFrame::body
const std::string & body() const
Return the frame body.
Definition: PluginFrame.cc:292
zypp::PluginFrame::command
const std::string & command() const
Return the frame command.
Definition: PluginFrame.cc:286
zypp::PluginFrame::getHeaderNT
const std::string & getHeaderNT(const std::string &key_r, const std::string &default_r=std::string()) const
Not throwing version returing one of the matching header values or default_r string.
Definition: PluginFrame.cc:316
zypp::PluginFrame::isAckCommand
bool isAckCommand() const
Convenience to identify an ACK command.
Definition: PluginFrame.h:106
zypp::PluginFrame::writeTo
std::ostream & writeTo(std::ostream &stream_r) const
Write frame to stream.
Definition: PluginFrame.cc:301
zypp::PluginScriptException
Base class for PluginScript Exception.
Definition: PluginScriptException.h:26
zypp::PluginScript
Interface to plugin scripts using a Stomp inspired communication protocol.
Definition: PluginScript.h:63
zypp::PluginScript::receive
PluginFrame receive() const
Receive a PluginFrame.
Definition: PluginScript.cc:507
zypp::PluginScript::sendTimeout
long sendTimeout() const
Local default timeout (sec.) when sending data.
Definition: PluginScript.cc:450
zypp::PluginScript::send
void send(const PluginFrame &frame_r) const
Send a PluginFrame.
Definition: PluginScript.cc:504
zypp::PluginScript::PluginScript
PluginScript()
Default ctor.
Definition: PluginScript.cc:462
zypp::PluginScript::_pimpl
RW_pointer< Impl > _pimpl
Pointer to implementation.
Definition: PluginScript.h:185
zypp::PluginScript::Arguments
std::vector< std::string > Arguments
Commandline arguments passed to a script on open.
Definition: PluginScript.h:68
zypp::PluginScript::lastReturn
int lastReturn() const
Remembers a scripts return value after close until next open.
Definition: PluginScript.cc:486
zypp::PluginScript::defaultReceiveTimeout
static long defaultReceiveTimeout()
Global default timeout (sec.) when receiving data.
Definition: PluginScript.cc:441
zypp::PluginScript::NotConnected
static const pid_t NotConnected
pid_t(-1) constant indicating no connection.
Definition: PluginScript.h:71
zypp::PluginScript::close
int close()
Close any open connection.
Definition: PluginScript.cc:501
zypp::PluginScript::lastExecError
const std::string & lastExecError() const
Remembers a scripts execError string after close until next open.
Definition: PluginScript.cc:489
zypp::PluginScript::getPid
pid_t getPid() const
Return a connected scripts pid or NotConnected.
Definition: PluginScript.cc:483
zypp::PluginScript::open
void open()
Setup connection and execute script.
Definition: PluginScript.cc:492
zypp::PluginScript::script
const Pathname & script() const
Return the script path if set.
Definition: PluginScript.cc:474
zypp::PluginScript::defaultSendTimeout
static long defaultSendTimeout()
Global default timeout (sec.) when sending data.
Definition: PluginScript.cc:438
zypp::PluginScript::isOpen
bool isOpen() const
Whether we are connected to a script.
Definition: PluginScript.cc:480
zypp::PluginScript::receiveTimeout
long receiveTimeout() const
Local default timeout (sec.) when receiving data.
Definition: PluginScript.cc:453
zypp::PluginScript::args
const Arguments & args() const
Return the script arguments if set.
Definition: PluginScript.cc:477
zypp::SignalSaver
Exception safe signal handler save/restore.
Definition: Signal.h:26
zypp::filesystem::PathInfo
Wrapper class for ::stat/::lstat.
Definition: PathInfo.h:221
zypp::filesystem::PathInfo::isX
bool isX() const
Definition: PathInfo.h:304
zypp::filesystem::PathInfo::isFile
bool isFile() const
Definition: PathInfo.h:289
zypp::filesystem::Pathname
Pathname.
Definition: Pathname.h:45
zypp::filesystem::Pathname::asString
const std::string & asString() const
String representation.
Definition: Pathname.h:91
str
String related utilities and Regular expression matching.
zypp::base::sysconfig::write
bool write(const Pathname &path_r, const std::string &key_r, const std::string &val_r, const std::string &newcomment_r)
Add or change a value in sysconfig file path_r.
Definition: Sysconfig.cc:80
zypp::iostr::copyIndent
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 "> " ).
Definition: IOStream.h:64
zypp::str::strtonum
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Definition: String.h:385
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
zypp::dumpRangeLine
std::ostream & dumpRangeLine(std::ostream &str, TIterator begin, TIterator end)
Print range defined by iterators (single line style).
Definition: LogTools.h:114
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Exception &obj)
Definition: Exception.cc:147
zypp::PluginScript::Impl
PluginScript implementation.
Definition: PluginScript.cc:113
zypp::PluginScript::Impl::receive
PluginFrame receive() const
Definition: PluginScript.cc:351
zypp::PluginScript::Impl::args
const Arguments & args() const
Definition: PluginScript.cc:136
zypp::PluginScript::Impl::_script
Pathname _script
Definition: PluginScript.cc:161
zypp::PluginScript::Impl::_lastExecError
std::string _lastExecError
Definition: PluginScript.cc:165
zypp::PluginScript::Impl::_defaultSendTimeout
static long _defaultSendTimeout
Definition: PluginScript.cc:126
zypp::PluginScript::Impl::script
const Pathname & script() const
Definition: PluginScript.cc:133
zypp::PluginScript::Impl::_lastReturn
DefaultIntegral< int, 0 > _lastReturn
Definition: PluginScript.cc:164
zypp::PluginScript::Impl::~ Impl
~ Impl()
Definition: PluginScript.cc:122
zypp::PluginScript::Impl::_receiveTimeout
long _receiveTimeout
Definition: PluginScript.cc:130
zypp::PluginScript::Impl::lastReturn
int lastReturn() const
Definition: PluginScript.cc:145
zypp::PluginScript::Impl::_sendTimeout
long _sendTimeout
Definition: PluginScript.cc:129
zypp::PluginScript::Impl::_cmd
scoped_ptr< ExternalProgramWithStderr > _cmd
Definition: PluginScript.cc:163
zypp::PluginScript::Impl::open
void open(const Pathname &script_r=Pathname(), const Arguments &args_r=Arguments())
Definition: PluginScript.cc:191
zypp::PluginScript::Impl::send
void send(const PluginFrame &frame_r) const
Definition: PluginScript.cc:257
zypp::PluginScript::Impl::getPid
pid_t getPid() const
Definition: PluginScript.cc:139
zypp::PluginScript::Impl::_defaultReceiveTimeout
static long _defaultReceiveTimeout
Definition: PluginScript.cc:127
zypp::PluginScript::Impl::isOpen
bool isOpen() const
Definition: PluginScript.cc:142
zypp::PluginScript::Impl::_args
Arguments _args
Definition: PluginScript.cc:162
zypp::PluginScript::Impl::Impl
Impl(const Pathname &script_r=Pathname(), const Arguments &args_r=Arguments())
Definition: PluginScript.cc:115
zypp::PluginScript::Impl::lastExecError
const std::string & lastExecError() const
Definition: PluginScript.cc:148
zypp::PluginScript::Impl::close
int close()
Definition: PluginScript.cc:225
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:209