Enlage plugin communication timeouts, also make them configurable via environment.
[platform/upstream/libzypp.git] / zypp / PluginScript.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/PluginScript.h
10  *
11 */
12 #ifndef ZYPP_PLUGINSCRIPT_H
13 #define ZYPP_PLUGINSCRIPT_H
14
15 #include <iosfwd>
16 #include <string>
17 #include <vector>
18
19 #include "zypp/base/PtrTypes.h"
20 #include "zypp/Pathname.h"
21
22 #include "zypp/PluginFrame.h"
23 #include "zypp/PluginScriptException.h"
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28
29   /**
30    * \brief Interface to pluigin scripts using a \c Stomp inspired communication protocol.
31    *
32    * \note \ref PluginScript is copyable and assignable, but the connection is shared
33    * among multiple copies. It gets automatically closed if the last copy goes out of
34    * scope.
35    *
36    * Timeout when sending/receiving data to/from a plugin default to 30 sec. The value
37    * (in seconds) my be changed via the environment variables \c ZYPP_PLUGIN_SEND_TIMEOUT,
38    * \c ZYPP_PLUGIN_RECEIVE_TIMEOUT or \c ZYPP_PLUGIN_TIMEOUT (both: send and receive).
39    *
40    * \code
41    *  // Setup comnnection to plugin script
42    *  PluginScript scr;
43    *  PluginScript::Arguments args;
44    *  args.push_back( "-v" );
45    *  scr.open( "/soem/testplugin", args );
46    *
47    *  // send frame to plugin
48    *  PluginFrame f( "COMMAND" );
49    *  f.setHeader( "key", "value" );
50    *  f.setBody( "some\ndata" );
51    *  scr.send( f );
52    *
53    *  // receive frame from plugin
54    *  PluginFrame r( scr.receive() );
55    *
56    *  // explicitly close or let PluginScript go out of scope
57    *  scr.close();
58    * \endcode
59    *
60    * \see http://stomp.codehaus.org/
61    */
62   class PluginScript
63   {
64     friend std::ostream & operator<<( std::ostream & str, const PluginScript & obj );
65
66     public:
67       /** Commandline arguments passed to a script on \ref open. */
68       typedef std::vector<std::string> Arguments;
69
70       /** \c pid_t(-1) constant indicating no connection. */
71       static const pid_t NotConnected;
72
73     public:
74       /** Default ctor. */
75       PluginScript();
76
77       /** Ctor taking script path and no arguments. */
78       PluginScript( const Pathname & script_r );
79
80       /** Ctor taking script path and script arguments. */
81       PluginScript( const Pathname & script_r, const Arguments & args_r );
82
83     public:
84       /** Return the script path if set. */
85       const Pathname & script() const;
86
87       /** Return the script arguments if set. */
88       const Arguments & args() const;
89
90       /** Whether we are connected to a script. */
91       bool isOpen() const;
92
93       /** Return a connected scripts pid or \ref NotConnected. */
94       pid_t getPid() const;
95
96       /** Remembers a scripts return value after \ref close until next \ref open. */
97       int lastReturn() const;
98
99       /** Remembers a scripts execError string after \ref close until next \ref open.
100        * \see \ref ExternalProgram::execError.
101        */
102       const std::string & lastExecError() const;
103
104     public:
105       /** Setup connection and execute script.
106        * \throw PluginScriptException if already connected to a script
107        * \throw PluginScriptException if script does not exist or is not executable
108        * \throw PluginScriptException on error
109        */
110       void open();
111
112       /** \overload taking script path and no arguments. */
113       void open( const Pathname & script_r );
114
115       /** \overload taking script path and script arguments. */
116       void open( const Pathname & script_r, const Arguments & args_r );
117
118       /** Close any open connection. */
119       int close();
120
121     public:
122       /** Send a \ref PluginFrame.
123        * \throw PluginScriptNotConnected
124        * \throw PluginScriptSendTimeout
125        * \throw PluginScriptDiedUnexpectedly (does not \ref close)
126        * \throw PluginScriptException on error
127        *
128        */
129       void send( const PluginFrame & frame_r ) const;
130
131       /** Receive a \ref PluginFrame.
132        * \throw PluginScriptNotConnected
133        * \throw PluginScriptReceiveTimeout
134        * \throw PluginScriptDiedUnexpectedly (does not \ref close)
135        * \throw PluginScriptException on error
136        */
137       PluginFrame receive() const;
138
139     public:
140       /** Implementation. */
141       class Impl;
142     private:
143       /** Pointer to implementation. */
144       RW_pointer<Impl> _pimpl;
145   };
146
147   /** \relates PluginScript Stream output */
148   std::ostream & operator<<( std::ostream & str, const PluginScript & obj );
149
150   /////////////////////////////////////////////////////////////////
151 } // namespace zypp
152 ///////////////////////////////////////////////////////////////////
153 #endif // ZYPP_PLUGINSCRIPT_H