ncbi_pipe.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:15k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbi_pipe.hpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/02/12 21:51:42  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [CORE_001] Dev-tree R1.20
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef CONNECT___NCBI_PIPE__HPP
  10. #define CONNECT___NCBI_PIPE__HPP
  11. /*  $Id: ncbi_pipe.hpp,v 1000.2 2004/02/12 21:51:42 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author:  Anton Lavrentiev, Vladimir Ivanov
  37.  *
  38.  *
  39.  */
  40. /// @file ncbi_pipe.hpp
  41. /// Portable class for work with process pipes.
  42. ///
  43. /// Defines classes: 
  44. ///     CPipe -  class for work with pipes
  45. ///
  46. /// Implemented for: UNIX, MS-Windows
  47. #include <corelib/ncbistd.hpp>
  48. #include <corelib/ncbi_process.hpp>
  49. #include <connect/ncbi_core.h>
  50. #include <vector>
  51. #if !defined(NCBI_OS_MSWIN)  &&  !defined(NCBI_OS_UNIX)
  52. #  error "Class CPipe is only supported on Windows and Unix"
  53. #endif
  54. /** @addtogroup Pipes
  55.  *
  56.  * @{
  57.  */
  58. BEGIN_NCBI_SCOPE
  59. // Forward declaration.
  60. class CPipeHandle;
  61. /////////////////////////////////////////////////////////////////////////////
  62. /// CPipeException --
  63. ///
  64. /// Define exceptions generated by CPipe.
  65. ///
  66. /// CPipeException inherits its basic functionality from CCoreException
  67. /// and defines additional error codes for CPipe.
  68. class NCBI_XCONNECT_EXPORT CPipeException : public CCoreException
  69. {
  70. public:
  71.     /// Error types for pipe exceptions.
  72.     enum EErrCode {
  73.         eInit,      ///< Pipe initialization error
  74.         eOpen,      ///< Unable to open pipe (from constructor)
  75.         eSetBuf     ///< setbuf() not permitted
  76.     };
  77.     /// Translate from an error code value to its string representation.
  78.     virtual const char* GetErrCodeString(void) const
  79.     {
  80.         switch (GetErrCode()) {
  81.         case eInit:   return "eInit";
  82.         case eOpen:   return "eOpen";
  83.         case eSetBuf: return "eSetBuf";
  84.         default:      return CException::GetErrCodeString();
  85.         }
  86.     }
  87.     // Standard exception boiler plate code.
  88.     NCBI_EXCEPTION_DEFAULT(CPipeException,CCoreException);
  89. };
  90. /////////////////////////////////////////////////////////////////////////////
  91. ///
  92. /// CPipe --
  93. ///
  94. /// Launch child process with pipes connected to its standard I/O.
  95. ///
  96. /// Program can read from stdin/stderr and write to stdin of the
  97. /// executed child process using pipe object functions Read/Write.
  98. /// Program can read from stdin/stderr and write to stdin of the
  99. /// executed child process using pipe object functions Read/Write.
  100. ///
  101. /// @sa
  102. ///   CNamedPipe, CExec
  103. class NCBI_XCONNECT_EXPORT CPipe
  104. {
  105. public:
  106.     /// Flags for creating standard I/O handles of child process.
  107.     ///
  108.     /// Default is 0 
  109.     ///    fStdIn_Open | fStdOut_Open | fStdErr_Close | fCloseOnClose.
  110.     enum ECreateFlags {
  111.         fStdIn_Open    =    0,  ///< Do     open child stdin (default).
  112.         fStdIn_Close   = 0x01,  ///< Do not open child's stdin.
  113.         fStdOut_Open   =    0,  ///< Do     open child stdout (default).
  114.         fStdOut_Close  = 0x02,  ///< Do not open child's stdout.
  115.         fStdErr_Open   = 0x04,  ///< Do     open child stderr.
  116.         fStdErr_Close  =    0,  ///< Do not open child stderr (default).
  117.         fKeepOnClose   = 0x08,  ///< Close(): just return eIO_Timeout on
  118.                                 ///< eIO_Close timeout w/o closing pipe
  119.                                 ///< handles and/or killing child process.
  120.         fCloseOnClose  =    0,  ///< Close(): always close all pipe handles
  121.                                 ///< but do not send any signal to running
  122.                                 ///< process if eIO_Close timeout expired.
  123.         fKillOnClose   = 0x10   ///< Close(): kill child process if it didn't
  124.                                 ///< terminate after eIO_Close timeout.
  125.     };
  126.     typedef unsigned int TCreateFlags;  ///< bit-wise OR of "ECreateFlags"
  127.     /// Which of the child I/O handles to use.
  128.     enum EChildIOHandle {
  129.         eStdIn,
  130.         eStdOut,
  131.         eStdErr,
  132.         eDefault
  133.     };
  134.     /// Constructor.
  135.     CPipe();
  136.     /// Constructor.
  137.     ///
  138.     /// Call the Open() method to open a pipe.
  139.     /// Throw CPipeException on failure to create the pipe.
  140.     ///
  141.     /// @param cmd
  142.     ///   Command name to execute.
  143.     /// @param args
  144.     ///   Vector of string arguments for the command.
  145.     /// @param create_flags
  146.     ///   Specifies the options to be applied when creating the pipe.
  147.     /// @sa
  148.     ///   Open()
  149.     CPipe
  150.         (const string&         cmd,
  151.          const vector<string>& args,
  152.          TCreateFlags          create_flags = 0
  153.         );
  154.     /// Destructor. 
  155.     ///
  156.     /// If the pipe was opened then close it by calling Close().
  157.     ~CPipe(void);
  158.     /// Open pipe.
  159.     ///
  160.     /// Create a pipe and execute a command with the vector of arguments
  161.     /// "args". The other end of the pipe is associated with the spawned
  162.     /// command's standard input/output/error according to "create_flags".
  163.     ///
  164.     /// @param cmd
  165.     ///   Command name to execute.
  166.     /// @param args
  167.     ///   Vector of string arguments for command.
  168.     /// @param create_flags
  169.     ///   Specifies options to be applied when creating the pipe.
  170.     /// @return 
  171.     ///   Completion status.
  172.     /// @sa
  173.     ///   Read(), Write(), Close()
  174.     EIO_Status Open
  175.         (const string&         cmd,
  176.          const vector<string>& args,
  177.          TCreateFlags          create_flags = 0
  178.         );
  179.     /// Close pipe.
  180.     ///
  181.     /// Wait for the spawned child process to terminate and then close
  182.     /// the associated pipe.
  183.     ///
  184.     /// @param exitcode
  185.     ///   Pointer to store the exit code at, if the child process terminated
  186.     ///   successfully, or -1 in case of an error. Can be passed as NULL.
  187.     /// @return
  188.     ///   Completion status.
  189.     ///   The returned status eIO_Timeout means that child process is still 
  190.     ///   running and the pipe was not yet closed. Any other return status
  191.     ///   means that the pipe is not suitable for further I/O until reopened.
  192.     ///
  193.     ///   eIO_Closed  - pipe was already closed;
  194.     ///   eIO_Timeout - the eIO_Close timeout expired, child process
  195.     ///                 is still running and the pipe was not yet closed
  196.     ///                 (return only if fKeepOnClose create flag was set);
  197.     ///   eIO_Success - pipe was succesfully closed. The child process
  198.     ///                 running status depend on the flags:
  199.     ///       fKeepOnClose  - process is terminated with "exitcode";
  200.     ///       fCloseOnClose - process is self-terminated if "exitcode" != -1,
  201.     ///                       or is still running otherwise;
  202.     ///       fKillOnClose  - process is self-terminated if "exitcode" != -1,
  203.     ///                       or was forcibly terminated otherwise;
  204.     ///   Otherwise   - an error was detected;
  205.     /// @sa
  206.     ///   Description for flags fKeepOnClose, fCloseOnClose, fKillOnClose.
  207.     ///   Open()
  208.     EIO_Status Close(int* exitcode = 0);
  209.     /// Close specified pipe handle.
  210.     ///
  211.     /// @param handle
  212.     ///   Pipe handle to close
  213.     /// @return
  214.     ///   Completion status.
  215.     /// @sa
  216.     ///   Close()
  217.     EIO_Status CloseHandle(EChildIOHandle handle);
  218.     /// Read data from pipe. 
  219.     ///
  220.     /// @param buf
  221.     ///   Buffer into which data is read.
  222.     /// @param count
  223.     ///   Number of bytes to read.
  224.     /// @param read
  225.     ///   Number of bytes actually read, which may be less than "count". 
  226.     /// @param from_handle
  227.     ///   Handle to read data from.
  228.     /// @return
  229.     ///   Always return eIO_Success if some data were read (regardless of pipe
  230.     ///   conditions that may include EOF/error).
  231.     ///   Return other (error) status only if no data at all could be obtained.
  232.     /// @sa
  233.     ///   Write(), SetTimeout()
  234.     EIO_Status Read
  235.         (void*          buf, 
  236.          size_t         count, 
  237.          size_t*        read = 0,
  238.          EChildIOHandle from_handle = eDefault
  239.         );
  240.     /// Set standard output handle to read data from.
  241.     ///
  242.     /// @from_handle
  243.     ///   Handle which used to read data (eStdOut/eStdErr).
  244.     /// @return
  245.     ///   Return eIO_Success if new handler is eStdOut or eStdErr.
  246.     ///   Return eIO_Unknown otherwise.
  247.     /// @sa
  248.     ///   Read()
  249.     EIO_Status SetReadHandle(EChildIOHandle from_handle);
  250.     /// Write data to pipe. 
  251.     ///
  252.     /// @param buf
  253.     ///   Buffer from which data is written.
  254.     /// @param count
  255.     ///   Number of bytes to write.
  256.     /// @param written
  257.     ///   Number of bytes actually written, which may be less than "count".
  258.     /// @return
  259.     ///   Return eIO_Success if some data were written.
  260.     ///   Return other (error) code only if no data at all could be written.
  261.     /// @sa
  262.     ///   Read(), SetTimeout()
  263.     EIO_Status Write
  264.         (const void* buf,
  265.          size_t      count,
  266.          size_t*     written = 0
  267.         );
  268.     /// Return a status of the last I/O operation.
  269.     /// 
  270.     /// @param direction
  271.     ///   Direction to get status for.
  272.     /// @return
  273.     ///   I/O status for the specified direction.
  274.     ///   eIO_Closed     - if the pipe is closed;
  275.     ///   eIO_Unknown    - if an error was detected during the last I/O;
  276.     ///   eIO_InvalidArg - if "direction" is not one of:  eIO_Read, eIO_Write;
  277.     ///   eIO_Timeout    - if the timeout was on last I/O;
  278.     ///   eIO_Success    - otherwise.
  279.     /// @sa
  280.     ///   Read(), Write()
  281.     EIO_Status Status(EIO_Event direction) const;
  282.     /// Specify timeout for the pipe I/O.
  283.     ///
  284.     /// @param event
  285.     ///   I/O event for which the timeout is set.
  286.     /// @param timeout
  287.     ///   Timeout value to set.
  288.     ///   If "timeout" is NULL then set the timeout to be infinite.
  289.     ///   - By default, initially all timeouts are infinite;
  290.     ///   - kDefaultTimeout has no effect.
  291.     /// @return
  292.     ///   Completion status.
  293.     /// @sa
  294.     ///   Read(), Write(), Close(), GetTimeout()
  295.     EIO_Status SetTimeout(EIO_Event event, const STimeout* timeout);
  296.     /// Get pipe I/O timeout.
  297.     ///
  298.     /// @param event
  299.     ///   I/O event for which timeout is obtained.
  300.     /// @return
  301.     //    Timeout for specified event (or NULL, if the timeout is infinite).
  302.     ///   The returned timeout is guaranteed to be pointing to a valid
  303.     ///   (and correct) structure in memory at least until the pipe is
  304.     ///   closed or SetTimeout() is called for this pipe.
  305.     /// @sa
  306.     ///   SetTimeout()
  307.     const STimeout* GetTimeout(EIO_Event event) const;
  308.     /// Get the process handle for the piped child.
  309.     ///
  310.     /// @return
  311.     ///   Returned value greater than 0 is a child process handle.
  312.     ///   Return 0 if child process is not running.
  313.     /// @sa
  314.     ///   Open(), Close(), CProcess
  315.     TProcessHandle GetProcessHandle(void) const;
  316. protected:
  317.     CPipeHandle*   m_PipeHandle;        ///< Internal pipe handle that handles
  318.     EChildIOHandle m_ReadHandle;        ///< Default read handle
  319.     // Last IO status
  320.     EIO_Status     m_ReadStatus;        ///< Last read status
  321.     EIO_Status     m_WriteStatus;       ///< Last write status
  322.     // Timeouts
  323.     STimeout*      m_ReadTimeout;       ///< eIO_Read timeout
  324.     STimeout*      m_WriteTimeout;      ///< eIO_Write timeout
  325.     STimeout*      m_CloseTimeout;      ///< eIO_Close timeout
  326.     STimeout       m_ReadTimeoutValue;  ///< Storage for m_ReadTimeout
  327.     STimeout       m_WriteTimeoutValue; ///< Storage for m_WriteTimeout
  328.     STimeout       m_CloseTimeoutValue; ///< Storage for m_CloseTimeout
  329. private:
  330.     /// Disable copy constructor and assignment.
  331.     CPipe(const CPipe&);
  332.     CPipe& operator= (const CPipe&);
  333. };
  334. END_NCBI_SCOPE
  335. /* @} */
  336. /*
  337.  * ===========================================================================
  338.  * $Log: ncbi_pipe.hpp,v $
  339.  * Revision 1000.2  2004/02/12 21:51:42  gouriano
  340.  * PRODUCTION: UPGRADED [CORE_001] Dev-tree R1.20
  341.  *
  342.  * Revision 1.20  2003/12/04 16:29:50  ivanov
  343.  * Added new create flags: fKeepOnClose, fCloseOnClose, fKillOnClose.
  344.  * Added GetProcessHandle(). Comments changes.
  345.  *
  346.  * Revision 1.19  2003/11/13 17:51:47  lavr
  347.  * -<stdio.h>
  348.  *
  349.  * Revision 1.18  2003/11/12 16:34:48  ivanov
  350.  * Removed references to CPipeIOStream from  comments
  351.  *
  352.  * Revision 1.17  2003/09/23 21:03:06  lavr
  353.  * PipeStreambuf and special stream removed: now all in ncbi_conn_stream.hpp
  354.  *
  355.  * Revision 1.16  2003/09/16 14:55:49  ivanov
  356.  * Removed extra comma in the enum definition
  357.  *
  358.  * Revision 1.15  2003/09/09 19:23:16  ivanov
  359.  * Comment changes
  360.  *
  361.  * Revision 1.14  2003/09/02 20:46:59  lavr
  362.  * -<connect/connect_export.h> -- included from <connect/ncbi_core.h>
  363.  *
  364.  * Revision 1.13  2003/09/02 20:24:32  ivanov
  365.  * Moved ncbipipe to CONNECT library from CORELIB.
  366.  * Rewritten CPipe class using I/O timeouts.
  367.  *
  368.  * Revision 1.12  2003/08/26 14:06:51  siyan
  369.  * Minor doc fixes.
  370.  *
  371.  * Revision 1.11  2003/08/24 22:53:03  siyan
  372.  * Added documentation.
  373.  *
  374.  * Revision 1.10  2003/04/23 20:50:27  ivanov
  375.  * Added CPipe::CloseHandle()
  376.  *
  377.  * Revision 1.9  2003/04/01 14:20:13  siyan
  378.  * Added doxygen support
  379.  *
  380.  * Revision 1.8  2003/03/03 14:46:02  dicuccio
  381.  * Reimplemented CPipe using separate private platform-specific implementations
  382.  *
  383.  * Revision 1.7  2002/12/18 22:53:21  dicuccio
  384.  * Added export specifier for building DLLs in windows.  Added global list of
  385.  * all such specifiers in mswin_exports.hpp, included through ncbistl.hpp
  386.  *
  387.  * Revision 1.6  2002/07/15 18:17:52  gouriano
  388.  * renamed CNcbiException and its descendents
  389.  *
  390.  * Revision 1.5  2002/07/11 14:17:55  gouriano
  391.  * exceptions replaced by CNcbiException-type ones
  392.  *
  393.  * Revision 1.4  2002/06/12 19:38:45  ucko
  394.  * Remove a superfluous comma from the definition of EMode.
  395.  *
  396.  * Revision 1.3  2002/06/11 19:25:06  ivanov
  397.  * Added class CPipeIOStream
  398.  *
  399.  * Revision 1.2  2002/06/10 18:35:13  ivanov
  400.  * Changed argument's type of a running child program from char*[]
  401.  * to vector<string>
  402.  *
  403.  * Revision 1.1  2002/06/10 16:57:04  ivanov
  404.  * Initial revision
  405.  *
  406.  * ===========================================================================
  407.  */
  408. #endif  /* CONNECT__NCBI_PIPE__HPP */