NCBI C++ ToolKit
ncbi_pipe.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CONNECT___NCBI_PIPE__HPP
2 #define CONNECT___NCBI_PIPE__HPP
3 
4 /* $Id: ncbi_pipe.hpp 101750 2024-02-07 00:04:44Z lavr $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Anton Lavrentiev, Vladimir Ivanov
30  *
31  *
32  */
33 
34 /// @file ncbi_pipe.hpp
35 /// Portable class to work with a spawned process via pipes.
36 ///
37 /// Defines classes:
38 /// CPipe - class to work with a spawned process via pipes
39 ///
40 /// Implemented for: UNIX, MS-Windows
41 
42 #include <corelib/ncbi_process.hpp>
44 
45 #if !defined(NCBI_OS_MSWIN) && !defined(NCBI_OS_UNIX)
46 # error "Class CPipe is only supported on Windows and Unix"
47 #endif
48 
49 
50 /** @addtogroup Pipes
51  *
52  * @{
53  */
54 
55 
57 
58 
59 // Forward declaration.
60 class CPipeHandle;
61 
62 
63 /////////////////////////////////////////////////////////////////////////////
64 ///
65 /// CPipe --
66 ///
67 /// Spawn a child process (command) with pipes attached to its standard I/O.
68 ///
69 /// The application can then read from stdout/stderr and write to stdin of the
70 /// launched child process using the Read / Write methods of the pipe object.
71 ///
72 /// @sa
73 /// CNamedPipe, CExec
74 
76 {
77 public:
78  /// Flags for creating standard I/O handles of the child process.
79  /// @note Flags pertaining to the same stdio handle are processed in the
80  /// order of their appearances in the definitions below.
81  ///
82  /// Default is 0:
83  /// fStdIn_Open | fStdOut_Open | fStdErr_Close | fCloseOnClose
84  enum ECreateFlag {
85  fStdIn_Open = 0, ///< Do open child's stdin (default)
86  fStdIn_Close = 0x001, ///< Do not open child's stdin
87  fStdOut_Open = 0, ///< Do open child's stdout (default)
88  fStdOut_Close = 0x002, ///< Do not open child's stdout
89  fStdErr_Open = 0x004, ///< Do open child's stderr
90  fStdErr_Close = 0, ///< Do not open child's stderr (default)
91  fStdErr_Share = 0x008, ///< Keep stderr (share it with child)
92  fStdErr_StdOut = 0x080, ///< Redirect stderr to whatever stdout goes
93  fKeepOnClose = 0x010, ///< Close(): just return eIO_Timeout
94  ///< if Close() cannot complete within
95  ///< the allotted time; don't close any
96  ///< pipe handles nor signal the child
97  fCloseOnClose = 0, ///< Close(): always close all pipe handles
98  ///< but do not send any signal to running
99  ///< process if Close()'s timeout expired
100  fKillOnClose = 0x020, ///< Close(): kill child process if it hasn't
101  ///< terminated within the allotted time.
102  ///< NOTE: If both fKeepOnClose and
103  ///< fKillOnClose are set, the safer
104  ///< fKeepOnClose takes the effect.
105  fSigPipe_Restore = 0x040, ///< Restore SIGPIPE processing for child
106  ///< process to system default
107  fNewGroup = 0x100 ///< UNIX: new process group will be created,
108  ///< and the child process will become the
109  ///< leader of the new process group
110  };
111  typedef unsigned int TCreateFlags; ///< bitwise OR of "ECreateFlag"
112 
113  /// Which of the child I/O handles to use.
115  fStdIn = (1 << 0),
116  fStdOut = (1 << 1),
117  fStdErr = (1 << 2),
118  fDefault = (1 << 3), ///< see Wait()
119  eStdIn = fStdIn,
120  eStdOut = fStdOut,
121  eStdErr = fStdErr,
122  eDefault = fDefault ///< see SetReadHandle()
123  };
124  typedef unsigned int TChildPollMask; ///< bitwise OR of "EChildIOHandle"
125 
126  /// Constructor.
127  CPipe(size_t pipe_size = 0/*use default*/);
128 
129  /// Constructor.
130  ///
131  /// Call the Open() method to actually open the pipe.
132  /// Throw CPipeException on failure to create the pipe.
133  ///
134  /// @param cmd
135  /// Command name to execute
136  /// @param args
137  /// Vector of string arguments for the command (argv[0] excluded)
138  /// @param create_flags
139  /// Specifies the options to be applied when creating the pipe
140  /// @param current_dir
141  /// Current working directory for the new process if specified
142  /// @param envp
143  /// An optional pointer to a vector with environment variables to use
144  /// in the child process. If not specified, a copy of the parent's
145  /// process environment is used. Note that the new environment entirely
146  /// replaces the default environment otherwise inherited from the parent
147  /// process, and so it does not just add / modify some values.
148  /// @sa
149  /// Open
150  CPipe(const string& cmd,
151  const vector<string>& args,
152  TCreateFlags create_flags = 0,
153  const string& current_dir = kEmptyStr,
154  const char* const envp[] = 0,
155  size_t pipe_size = 0/*use default*/);
156 
157  /// Destructor.
158  ///
159  /// If the pipe was opened then the destructor first closes it by calling
160  /// Close().
161  /// @sa
162  /// Close
163  ~CPipe(void);
164 
165  /// Open pipe.
166  ///
167  /// Execute a command with the vector of arguments "args". The other end
168  /// of the pipe is associated with the spawned command's standard
169  /// input/output/error according to "create_flags". Default child's read
170  /// handle is always reset to be eStdOut, regardless of the return status.
171  ///
172  /// @param cmd
173  /// Command name to execute.
174  /// Note when specifying both "cmd" with relative path and non-empty
175  /// "current_dir": at run-time the current directory must be considered
176  /// undefined, as it may still be the same of the parent process that
177  /// issues the call, or it can already be changed to the specified
178  /// "current_dir". So, using the absolute path for "cmd" is always
179  /// recommended in such cases.
180  /// @param args
181  /// Vector of string arguments for the command (argv[0] excluded)
182  /// @param create_flags
183  /// Specifies options to be applied when creating the pipe
184  /// @param current_dir
185  /// Current working directory for the new process
186  /// The string must be an absolute path. On MS Windows it should
187  /// also contain a drive letter. If this parameter is empty, the new
188  /// process will have the same current directory as the calling process.
189  /// @param envp
190  /// An optional pointer to a vector with environment variables to use
191  /// in the child process. If not specified, a copy of the parent's
192  /// process environment is used. Note that the new environment entirely
193  /// replaces the default environment otherwise inherited from the parent
194  /// process, and so it does not just add / modify some values.
195  /// @return
196  /// Completion status
197  /// @sa
198  /// Read, Write, Close, SetReadHandle, GetReadHandle
199  EIO_Status Open(const string& cmd,
200  const vector<string>& args,
201  TCreateFlags create_flags = 0,
202  const string& current_dir = kEmptyStr,
203  const char* const envp[] = 0,
204  size_t pipe_size = 0/*use default*/);
205 
206  /// Open the standard streams of the current process.
207  ///
208  /// The standard input stream is opened as if it's the output stream of a
209  /// child process, so it can be read from. Similarly, the standard output
210  /// stream is opened as if it's a child input stream, so it can be written.
211  /// The standard error stream is left untouched.
212  /// Throw CPipeExcepionon on errors.
213  ///
214  /// @sa
215  /// Read, Write, Close
216  void OpenSelf(void);
217 
218  /// Close pipe.
219  ///
220  /// Sever communication channel with the spawned child process, and then
221  /// wait for the process to terminate.
222  ///
223  /// @note
224  /// A CPipe opened with OpenSelf() always closes with eIO_Success, and
225  /// "*exitcode" returns as 0 (yet the current process continues to run).
226  ///
227  /// @param exitcode
228  /// Pointer to store the exit code at, if the child process terminated
229  /// successfully, or -1 in case of an error. Can be passed as NULL.
230  /// @return
231  /// Completion status.
232  /// The returned status eIO_Timeout means that child process is still
233  /// running (yet the communication with it has been severed). Any other
234  /// return status means that the pipe is not suitable for further I/O
235  /// until reopened.
236  ///
237  /// eIO_Closed - pipe was already closed;
238  /// eIO_Timeout - the eIO_Close timeout expired, child process is still
239  /// running (return only if fKeepOnClose was set);
240  /// eIO_Success - pipe was successfully closed. The running status of
241  /// the child process depends on the flags:
242  /// fKeepOnClose - process has terminated with "exitcode";
243  /// fCloseOnClose - process has self-terminated if "exitcode" != -1,
244  /// or is still running otherwise;
245  /// fKillOnClose - process has self-terminated if "exitcode" != -1,
246  /// or has been forcibly terminated otherwise;
247  /// Otherwise - an error was detected.
248  /// @sa
249  /// Open, OpenSelf, fKeepOnClose, fCloseOnClose, fKillOnClose, fNewGroup
250  EIO_Status Close(int* exitcode = 0);
251 
252  /// Close the specified child's pipe handle
253  /// (even for CPipe opened with OpenSelf()).
254  ///
255  /// @param handle
256  /// Child's pipe handle to close
257  /// @return
258  /// Completion status
259  /// @sa
260  /// Close, OpenSelf
261  EIO_Status CloseHandle(EChildIOHandle handle);
262 
263  /// Set standard output handle to read data from.
264  ///
265  /// @param from_handle
266  /// Child's handle which is to use to read data from (eStdOut/eStdErr),
267  /// or eDefault to restore the handle to eStdOut
268  /// @return
269  /// Return eIO_Success if new handle is now eStdOut or eStdErr; and an
270  // / error, otherwise
271  /// @sa
272  /// GetReadHandle, Read
273  EIO_Status SetReadHandle(EChildIOHandle from_handle);
274 
275  /// Get standard output handle to read data from.
276  ///
277  /// @return
278  /// Return either eStdOut(default) or eStdErr
279  /// @sa
280  /// SetReadHandle, Read
281  EChildIOHandle GetReadHandle(void) const { return m_ReadHandle; }
282 
283  /// Read data from the pipe's default read handle.
284  ///
285  /// @param buf
286  /// Buffer into which data is read
287  /// @param count
288  /// Number of bytes to read
289  /// @param read
290  /// Number of bytes actually read, which may be less than "count"
291  /// @param from_handle
292  /// Handle to read data from
293  /// @return
294  /// Always return eIO_Success if some data were read (regardless of pipe
295  /// conditions that may include EOF/error).
296  /// Return other (error) status only if no data at all could be obtained.
297  /// @sa
298  /// SetReadHandle, GetReadHandle, Write, SetTimeout
299  EIO_Status Read(void* buf,
300  size_t count,
301  size_t* read = 0,
302  EChildIOHandle from_handle = eDefault);
303 
304  /// Write data to pipe (data always goes to the child's eStdIn handle).
305  ///
306  /// @param data
307  /// Data to be written
308  /// @param count
309  /// Number of bytes to write
310  /// @param written
311  /// Number of bytes actually written, which may be less than "count"
312  /// @return
313  /// Return eIO_Success if some data were written.
314  /// Return other (error) code only if no data at all could be written.
315  /// @sa
316  /// Read, SetTimeout
317  EIO_Status Write(const void* data,
318  size_t count,
319  size_t* written = 0);
320 
321  /// Wait for I/O event(s).
322  ///
323  /// Block until at least one of the I/O handles enlisted in poll mask
324  /// becomes available for I/O, or until timeout expires.
325  /// Throw CPipeException on failure to create the pipe.
326  /// NOTE: MS Windows doesn't have mechanism to get status of 'write end'
327  /// of the pipe, so only fStdOut/fStdErr/fDefault can be used for polling
328  /// child stdin/stderr handles. If fStdIn flag is set in the 'mask',
329  /// that it will be copied to resulting mask also.
330  ///
331  /// @param mask
332  /// Mask of I/O handles to poll
333  /// @param timeout
334  /// Timeout value to set. If "timeout" is kInfiniteTimeout(0) then set
335  /// the timeout to be infinite.
336  /// @return
337  /// Mask of I/O handles that ready for I/O.
338  /// Return zero on timeout or if all I/O handles are closed.
339  /// If fDefault is polled and the corresponding Err/Out is ready
340  /// then return fDefault, and not the "real" fStdOut/fStdErr.
341  /// @sa
342  /// Read, Write, SetReadHandle
343  TChildPollMask Poll(TChildPollMask mask, const STimeout* timeout = 0);
344 
345  /// Return a status of the last I/O operation.
346  ///
347  /// @param direction
348  /// Direction to get status for
349  /// @return
350  /// I/O status for the specified direction.
351  /// eIO_Closed - if the pipe is closed;
352  /// eIO_Unknown - if an error was detected during the last I/O;
353  /// eIO_InvalidArg - if "direction" is not one of: eIO_Read, eIO_Write;
354  /// eIO_Timeout - if the timeout was on last I/O;
355  /// eIO_Success - otherwise.
356  /// @sa
357  /// Read, Write, Close
358  EIO_Status Status(EIO_Event direction) const;
359 
360  /// Specify timeout for the pipe I/O.
361  ///
362  /// @param event
363  /// I/O event for which the timeout is set
364  /// @param timeout
365  /// Timeout value to set. If "timeout" is kInfiniteTimeout(0) then set
366  /// the timeout to be infinite.
367  /// - By default, initially all timeouts are infinite;
368  /// - kDefaultTimeout has no effect.
369  /// @return
370  /// Completion status
371  /// @sa
372  /// Read, Write, Close, GetTimeout
373  EIO_Status SetTimeout(EIO_Event event, const STimeout* timeout);
374 
375  /// Get pipe I/O timeout.
376  ///
377  /// @param event
378  /// I/O event for which timeout is obtained
379  /// @return
380  // Timeout for specified event (kInfiniteTimeout(0) is returned for the
381  /// infinite timeout).
382  /// The returned timeout is guaranteed to be pointing to a valid
383  /// (and correct) structure in memory at least until the pipe is
384  /// closed or SetTimeout() is called for this pipe.
385  /// @sa
386  /// SetTimeout
387  const STimeout* GetTimeout(EIO_Event event) const;
388 
389  /// Get the process handle for the piped child.
390  ///
391  /// @return
392  /// Returned value greater than 0 is a child process handle.
393  /// Return 0 if child process is not running.
394  /// @sa
395  /// Open, Close, CProcess class
396  TProcessHandle GetProcessHandle(void) const;
397 
398 
399  /// Callback interface for ExecWait()
400  ///
401  /// @sa ExecWait
403  {
404  public:
405  /// An action which the ExecWait() method should take
406  /// after the Watch() method has returned.
407  enum EAction {
408  eContinue, ///< Continue running
409  eStop, ///< Kill the child process and exit
410  eExit ///< Exit without waiting for the child process
411  };
412  virtual ~IProcessWatcher();
413 
414  /// This method is called when the process has just
415  /// been started by the ExecWait() method.
416  ///
417  /// @param pid
418  /// Process Id to monitor
419  /// @return
420  /// eContinue to continue with the process; other code to kill the
421  /// process and to return from ExecWait() with eCanceled
422  virtual EAction OnStart(TProcessHandle /*pid*/) { return eContinue; }
423 
424  /// This method is getting called periodically during
425  /// the process execution by the ExecWait() method.
426  ///
427  /// @param pid
428  /// Process Id to monitor
429  /// @return
430  /// eContinue to keep the process running; eStop to kill the process;
431  /// or eExit to bail from ExecWait() with eCanceled (the process is
432  /// not killed, but all I/O is severed with it)
433  virtual EAction Watch(TProcessHandle /*pid*/) = 0;
434  };
435 
436  /// ExecWait return code
437  enum EFinish {
438  eDone, ///< Process finished normally
439  eCanceled ///< Watcher requested to bail out
440  };
441 
442  /// Execute a command with a vector of arguments, and wait for its
443  /// completion.
444  ///
445  /// @param cmd
446  /// Command name to execute.
447  /// Beware if both the command contains a relative path and 'current_dir'
448  /// parameter is specified. In this case, the current directory must
449  /// be considered undefined, as it can either still be the same as in the
450  /// parent process or already be changed to 'current_dir'. So using of
451  /// an absolute path is always recommended in such cases.
452  /// @param args
453  /// Vector of string arguments for the command (argv[0] excluded)
454  /// @param in
455  /// Stream this data which will be sent to the child process's stdin
456  /// @param out
457  /// Stream where the child process's stdout will be written to
458  /// @param err
459  /// Stream where the child process's stderr will be written to
460  /// @param exit_code
461  /// The child process's exit_code
462  /// @param current_dir
463  /// Current working directory for the new process.
464  /// The string must be an absolute path. On MS Windows it should
465  /// also contain a drive letter. If this parameter is empty, the new
466  /// process will have the same current directory as the calling process.
467  /// @param envp
468  /// An optional pointer to a vector with environment variables to use
469  /// in the child process. If not specified, a copy of the parent's
470  /// process environment is used. Note that the new environment entirely
471  /// replaces the default environment otherwise inherited from the parent
472  /// process, and so it does not just add / modify some values.
473  /// @param watcher
474  /// Call back object to monitor the child process execution status
475  /// @param kill_timeout
476  /// Wait time between first "soft" and second "hard" attempts to
477  /// terminate the process.
478  /// @note that on UNIX in case of a zero or a very small timeout
479  /// the killed process may not be released immediately and continue to
480  /// persist as a zombie process even after this call completes.
481  /// @return
482  /// eDone if process has finished normally, or eCanceled if the watcher
483  /// decided to stop it
484  ///
485  /// @sa IProcessWatcher, Open
486  static EFinish ExecWait(const string& cmd,
487  const vector<string>& args,
488  CNcbiIstream& in,
489  CNcbiOstream& out,
490  CNcbiOstream& err,
491  int& exit_code,
492  const string& current_dir = kEmptyStr,
493  const char* const envp[] = 0,
494  IProcessWatcher* watcher = 0,
495  const STimeout* kill_timeout = 0,
496  size_t pipe_size = 0/*default*/);
497 
498 protected:
499  size_t m_PipeSize; ///< Pipe size
500 
501  CPipeHandle* m_PipeHandle; ///< Internal OS-specific pipe handle
502  EChildIOHandle m_ReadHandle; ///< Default handle used for read
503 
504  // Last I/O status
505  EIO_Status m_ReadStatus; ///< Last read status
506  EIO_Status m_WriteStatus; ///< Last write status
507 
508  // Timeouts
509  const STimeout* m_ReadTimeout; ///< eIO_Read timeout
510  const STimeout* m_WriteTimeout; ///< eIO_Write timeout
511  const STimeout* m_CloseTimeout; ///< eIO_Close timeout
512  STimeout m_ReadTimeoutValue; ///< Storage for m_ReadTimeout
513  STimeout m_WriteTimeoutValue; ///< Storage for m_WriteTimeout
514  STimeout m_CloseTimeoutValue; ///< Storage for m_CloseTimeout
515 
516 private:
517  // Disable copy constructor and assignment
518  CPipe(const CPipe&);
519  CPipe& operator= (const CPipe&);
520 };
521 
522 
523 
524 /////////////////////////////////////////////////////////////////////////////
525 /// CPipeException --
526 ///
527 /// Define exceptions generated by CPipe.
528 ///
529 /// CPipeException inherits its basic functionality from CCoreException
530 /// and defines additional error codes for CPipe.
531 
534 {
535 public:
536  /// Error types for pipe exceptions.
537  enum EErrCode {
538  eOpen ///< Unable to open pipe
539  };
540  /// Translate from an error code value to its string representation.
541  virtual const char* GetErrCodeString(void) const override;
542  // Standard exception boiler plate code.
544 };
545 
546 
548 
549 
550 /* @} */
551 
552 #endif /* CONNECT__NCBI_PIPE__HPP */
ncbi::TMaskedQueryRegions mask
Helper hook-up class that installs default logging/registry/locking (but only if they have not yet be...
CCoreException –.
Definition: ncbiexpt.hpp:1476
CPipeException –.
Definition: ncbi_pipe.hpp:534
Callback interface for ExecWait()
Definition: ncbi_pipe.hpp:403
CPipe –.
Definition: ncbi_pipe.hpp:76
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
std::ofstream out("events_result.xml")
main entry point for tests
#define EXCEPTION_VIRTUAL_BASE
Do not use virtual base classes in exception declaration at all, because in this case derived class s...
Definition: ncbiexpt.hpp:1388
void Read(CObjectIStream &in, TObjectPtr object, const CTypeRef &type)
Definition: serial.cpp:60
void Write(CObjectOStream &out, TConstObjectPtr object, const CTypeRef &type)
Definition: serial.cpp:55
virtual EAction Watch(TProcessHandle)=0
This method is getting called periodically during the process execution by the ExecWait() method.
EIO_Status m_ReadStatus
Last read status.
Definition: ncbi_pipe.hpp:505
CPipe(const CPipe &)
EChildIOHandle m_ReadHandle
Default handle used for read.
Definition: ncbi_pipe.hpp:502
EChildIOHandle
Which of the child I/O handles to use.
Definition: ncbi_pipe.hpp:114
EFinish
ExecWait return code.
Definition: ncbi_pipe.hpp:437
unsigned int TChildPollMask
bitwise OR of "EChildIOHandle"
Definition: ncbi_pipe.hpp:124
ECreateFlag
Flags for creating standard I/O handles of the child process.
Definition: ncbi_pipe.hpp:84
virtual EAction OnStart(TProcessHandle)
This method is called when the process has just been started by the ExecWait() method.
Definition: ncbi_pipe.hpp:422
EChildIOHandle GetReadHandle(void) const
Get standard output handle to read data from.
Definition: ncbi_pipe.hpp:281
const STimeout * m_ReadTimeout
eIO_Read timeout
Definition: ncbi_pipe.hpp:509
EAction
An action which the ExecWait() method should take after the Watch() method has returned.
Definition: ncbi_pipe.hpp:407
size_t m_PipeSize
Pipe size.
Definition: ncbi_pipe.hpp:499
STimeout m_CloseTimeoutValue
Storage for m_CloseTimeout.
Definition: ncbi_pipe.hpp:514
STimeout m_WriteTimeoutValue
Storage for m_WriteTimeout.
Definition: ncbi_pipe.hpp:513
CPipeHandle * m_PipeHandle
Internal OS-specific pipe handle.
Definition: ncbi_pipe.hpp:501
STimeout m_ReadTimeoutValue
Storage for m_ReadTimeout.
Definition: ncbi_pipe.hpp:512
const STimeout * m_CloseTimeout
eIO_Close timeout
Definition: ncbi_pipe.hpp:511
NCBI_EXCEPTION_DEFAULT(CPipeException, CCoreException)
unsigned int TCreateFlags
bitwise OR of "ECreateFlag"
Definition: ncbi_pipe.hpp:111
EIO_Status m_WriteStatus
Last write status.
Definition: ncbi_pipe.hpp:506
const STimeout * m_WriteTimeout
eIO_Write timeout
Definition: ncbi_pipe.hpp:510
EErrCode
Error types for pipe exceptions.
Definition: ncbi_pipe.hpp:537
@ eDone
Process finished normally.
Definition: ncbi_pipe.hpp:438
@ eContinue
Continue running.
Definition: ncbi_pipe.hpp:408
@ eStop
Kill the child process and exit.
Definition: ncbi_pipe.hpp:409
TPid TProcessHandle
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
#define kEmptyStr
Definition: ncbistr.hpp:123
EIO_Status
I/O status.
Definition: ncbi_core.h:132
EIO_Event
I/O event (or direction).
Definition: ncbi_core.h:118
#define NCBI_XCONNECT_EXPORT
char * buf
Defines process management classes.
std::istream & in(std::istream &in_, double &x_)
@ eCanceled
Request canceled.
Timeout structure.
Definition: ncbi_types.h:76
Modified on Wed Feb 28 07:14:36 2024 by modify_doxy.py rev. 669887