00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00036 #ifndef OW_EXEC_HPP_
00037 #define OW_EXEC_HPP_
00038 #include "OW_config.h"
00039 #include "OW_Types.hpp"
00040 #include "OW_IntrusiveReference.hpp"
00041 #include "OW_String.hpp"
00042 #include "OW_ArrayFwd.hpp"
00043 #include "OW_CommonFwd.hpp"
00044 #include "OW_EnvVars.hpp"
00045 
00046 namespace OW_NAMESPACE
00047 {
00048 
00049 OW_DECLARE_APIEXCEPTION(ExecTimeout, OW_COMMON_API);
00050 OW_DECLARE_APIEXCEPTION(ExecBufferFull, OW_COMMON_API);
00051 OW_DECLARE_APIEXCEPTION(ExecError, OW_COMMON_API);
00052 
00053 class PopenStreamsImpl;
00057 class OW_COMMON_API PopenStreams
00058 {
00059 public:
00060    PopenStreams();
00061    ~PopenStreams();
00062    PopenStreams(const PopenStreams& src);
00063    PopenStreams& operator=(const PopenStreams& src);
00067    UnnamedPipeRef in() const;
00068    
00072    void in(const UnnamedPipeRef& pipe);
00076    UnnamedPipeRef out() const;
00080    void out(const UnnamedPipeRef& pipe);
00084    UnnamedPipeRef err() const;
00088    void err(const UnnamedPipeRef& pipe);
00089 
00093    Array<UnnamedPipeRef> extraPipes() const;
00094 
00098    void setExtraPipes(const Array<UnnamedPipeRef>& pipes);
00099 
00104    ProcId pid() const;
00108    void pid(ProcId newPid);
00109 
00141    int getExitStatus(UInt32 wait_initial, UInt32 wait_close, UInt32 wait_term);
00142 
00146    int getExitStatus();
00147 
00152    void setProcessStatus(int ps);
00153 private:
00154    IntrusiveReference<PopenStreamsImpl> m_impl;
00155 
00156    friend bool operator==(const PopenStreams& x, const PopenStreams& y);
00157 };
00158 
00160 namespace Exec
00161 {
00187    OW_COMMON_API int safeSystem(const Array<String>& command,
00188       const char* const envp[] = 0);
00189 
00190    
00216    OW_COMMON_API int safeSystem(const Array<String>& command,
00217       const EnvVars& envVars);
00218    
00248    OW_COMMON_API PopenStreams safePopen(const Array<String>& command, const char* const envp[] = 0);
00249 
00279    OW_COMMON_API PopenStreams safePopen(const Array<String>& command, const EnvVars& envVars);
00280 
00281    
00282 
00288    OW_COMMON_API PopenStreams safePopen(const Array<String>& command,
00289          const String& initialInput) OW_DEPRECATED;
00290 
00291    const int INFINITE_TIMEOUT = -1;
00292 
00321    OW_COMMON_API void gatherOutput(String& output, PopenStreams& streams, int& processstatus, int timeoutsecs = INFINITE_TIMEOUT, int outputlimit = -1);
00322    
00323    enum EOutputSource
00324    {
00325       E_STDOUT,
00326       E_STDERR
00327    };
00328 
00329    class OutputCallback
00330    {
00331    public:
00332       virtual ~OutputCallback();
00333       void handleData(const char* data, size_t dataLen, EOutputSource outputSource, PopenStreams& theStream, size_t streamIndex, Array<char>& inputBuffer);
00334    private:
00339       virtual void doHandleData(const char* data, size_t dataLen, EOutputSource outputSource, PopenStreams& theStream, size_t streamIndex, Array<char>& inputBuffer) = 0;
00340    };
00341 
00342    class InputCallback
00343    {
00344    public:
00345       virtual ~InputCallback();
00346       void getData(Array<char>& inputBuffer, PopenStreams& theStream, size_t streamIndex);
00347    private:
00348       virtual void doGetData(Array<char>& inputBuffer, PopenStreams& theStream, size_t streamIndex) = 0;
00349    };
00350 
00351    enum EProcessRunning
00352    {
00353       E_PROCESS_RUNNING,
00354       E_PROCESS_EXITED
00355    };
00356 
00357    
00358    class ProcessStatus
00359    {
00360    public:
00361       ProcessStatus()
00362       : m_running(E_PROCESS_RUNNING)
00363       , m_status(0)
00364       {
00365       }
00366 
00367       explicit ProcessStatus(int status)
00368       : m_running(E_PROCESS_EXITED)
00369       , m_status(status)
00370       {
00371       }
00372 
00373       bool hasExited() const
00374       {
00375          return m_running == E_PROCESS_EXITED;
00376       }
00377 
00378       const int& getStatus() const
00379       {
00380          return m_status;
00381       }
00382    private:
00383       EProcessRunning m_running;
00384       int m_status;
00385    };
00386 
00423    OW_COMMON_API void processInputOutput(OutputCallback& output, Array<PopenStreams>& streams, Array<ProcessStatus>& processStatuses,
00424       InputCallback& input, int timeoutSecs = INFINITE_TIMEOUT);
00425    
00485    OW_COMMON_API void executeProcessAndGatherOutput(
00486       const Array<String>& command,
00487       String& output, int& processstatus,
00488       int timeoutsecs = INFINITE_TIMEOUT, int outputlimit = -1, const String& input = String());
00489 
00554    OW_COMMON_API void executeProcessAndGatherOutput(
00555       const Array<String>& command,
00556       String& output, int& processstatus, const EnvVars& envVars,
00557       int timeoutsecs = INFINITE_TIMEOUT, int outputlimit = -1, const String& input = String());
00558    
00559    
00560 } 
00561 
00562 } 
00563 
00564 #endif