NCBI C++ ToolKit
ncbi_pipe_connector.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_pipe_connector.cpp 97266 2022-06-30 14:11:07Z lavr $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Denis Vakatov, Anton Lavrentiev, Vladimir Ivanov
27  *
28  * File Description:
29  * Implement CONNECTOR for a pipe interprocess communication
30  * (based on the NCBI CPipe).
31  *
32  * See in "connectr.h" for the detailed specification of the underlying
33  * connector("CONNECTOR", "SConnectorTag") methods and structures.
34  *
35  */
36 
37 #include <ncbi_pch.hpp>
38 #include "ncbi_ansi_ext.h"
40 
41 
43 
44 
45 /***********************************************************************
46  * INTERNAL -- Auxiliary types and static functions
47  ***********************************************************************/
48 
49 // All internal data necessary to perform the (re)connect and i/o
50 typedef struct {
51  CPipe* pipe; // pipe handle; non-NULL
52  string cmd; // program to execute
53  vector<string> args; // program arguments
54  CPipe::TCreateFlags flags; // pipe create flags
55  bool own_pipe; // true if pipe is owned
56  size_t pipe_size; // pipe size
58 
59 
60 /***********************************************************************
61  * INTERNAL -- "s_VT_*" functions for the "virt. table" of connector methods
62  ***********************************************************************/
63 
64 
65 extern "C" {
66 
67 
68 static const char* s_VT_GetType
69 (CONNECTOR /*connector*/)
70 {
71  return "PIPE";
72 }
73 
74 
75 static char* s_VT_Descr(CONNECTOR connector)
76 {
77  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
78  string cmd_line(xxx->cmd);
79  for (auto arg : xxx->args) {
80  if ( !cmd_line.empty() ) {
81  cmd_line += ' ';
82  }
83  string quote;
84  bool replace = false;
85  if (arg.find(' ') == NPOS) {
86  ;
87  } else if (arg.find('"') == NPOS) {
88  quote = string(1, '"');
89  } else if (arg.find('\'') == NPOS) {
90  quote = string(1, '\'');
91  } else {
92  quote = string(1, '"');
93  replace = true;
94  }
95  string tmp;
96  if (replace) {
97  tmp = arg;
98  _ASSERT(!quote.empty());
99  NStr::ReplaceInPlace(tmp, quote, '\\' + quote);
100  }
101  if ( !quote.empty() ) {
102  cmd_line += quote;
103  }
104  cmd_line += replace ? tmp : arg;
105  if ( !quote.empty() ) {
106  cmd_line += quote;
107  }
108  }
109  return strdup(cmd_line.c_str());
110 }
111 
112 
114 (CONNECTOR connector,
115  const STimeout* /*timeout*/)
116 {
117  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
118  return xxx->pipe->Open(xxx->cmd, xxx->args, xxx->flags,
119  kEmptyStr, NULL, xxx->pipe_size);
120 }
121 
122 
124 (CONNECTOR connector,
125  EIO_Event event,
126  const STimeout* timeout)
127 {
128  _ASSERT(timeout != kDefaultTimeout);
129  _ASSERT(event == eIO_Read || event == eIO_Write);
130  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
131  CPipe::TChildPollMask what = 0;
132  if (event & eIO_Read) {
133  what |= CPipe::fDefault;
134  }
135  if (event & eIO_Write) {
136  what |= CPipe::fStdIn;
137  }
138  return xxx->pipe->Poll(what, timeout) ? eIO_Success : eIO_Unknown;
139 }
140 
141 
143 (CONNECTOR connector,
144  const void* buf,
145  size_t size,
146  size_t* n_written,
147  const STimeout* timeout)
148 {
149  _ASSERT(timeout != kDefaultTimeout);
150  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
151  _VERIFY(xxx->pipe->SetTimeout(eIO_Write, timeout) == eIO_Success);
152  return xxx->pipe->Write(buf, size, n_written);
153 }
154 
155 
157 (CONNECTOR connector,
158  void* buf,
159  size_t size,
160  size_t* n_read,
161  const STimeout* timeout)
162 {
163  _ASSERT(timeout != kDefaultTimeout);
164  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
165  _VERIFY(xxx->pipe->SetTimeout(eIO_Read, timeout) == eIO_Success);
166  return xxx->pipe->Read(buf, size, n_read);
167 }
168 
169 
171 (CONNECTOR connector,
172  EIO_Event dir)
173 {
174  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
175  return xxx->pipe->Status(dir);
176 }
177 
178 
180 (CONNECTOR connector,
181  const STimeout* timeout)
182 {
183  _ASSERT(timeout != kDefaultTimeout);
184  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
185  _VERIFY(xxx->pipe->SetTimeout(eIO_Close, timeout) == eIO_Success);
186  return xxx->pipe->Close();
187 }
188 
189 
190 static void s_Setup
191 (CONNECTOR connector)
192 {
193  SMetaConnector* meta = connector->meta;
194 
195  // Initialize virtual table
196  CONN_SET_METHOD(meta, get_type, s_VT_GetType, connector);
197  CONN_SET_METHOD(meta, descr, s_VT_Descr, connector);
198  CONN_SET_METHOD(meta, open, s_VT_Open, connector);
199  CONN_SET_METHOD(meta, wait, s_VT_Wait, connector);
200  CONN_SET_METHOD(meta, write, s_VT_Write, connector);
201  CONN_SET_METHOD(meta, flush, 0, 0);
202  CONN_SET_METHOD(meta, read, s_VT_Read, connector);
203  CONN_SET_METHOD(meta, status, s_VT_Status, connector);
204  CONN_SET_METHOD(meta, close, s_VT_Close, connector);
206 }
207 
208 
209 static void s_Destroy
210 (CONNECTOR connector)
211 {
212  SPipeConnector* xxx = (SPipeConnector*) connector->handle;
213  connector->handle = 0;
214 
215  _ASSERT(xxx->pipe);
216  if (xxx->own_pipe) {
217  delete xxx->pipe;
218  }
219  xxx->pipe = 0;
220  delete xxx;
221  free(connector);
222 }
223 
224 
225 } /* extern "C" */
226 
227 
229 
230 
231 /***********************************************************************
232  * EXTERNAL -- the connector's "constructors"
233  ***********************************************************************/
234 
236 (const string& cmd,
237  const vector<string>& args,
239  CPipe* pipe,
240  EOwnership own_pipe,
241  size_t pipe_size)
242 {
243  auto ccc = make_c_unique((SConnector*) malloc(sizeof(SConnector)));
244  if (!ccc) {
245  return 0;
246  }
247 
248  // Initialize internal data structures
249  unique_ptr<SPipeConnector> xxx(new SPipeConnector);
250  xxx->cmd = cmd;
251  xxx->args = args;
252  xxx->flags = flags;
253  xxx->pipe = pipe ? pipe : new CPipe;
254  xxx->own_pipe = pipe ? own_pipe == eTakeOwnership : true;
255  xxx->pipe_size = pipe_size;
256 
257  // Initialize connector data
258  ccc->handle = xxx.release();
259  ccc->next = 0;
260  ccc->meta = 0;
261  ccc->setup = s_Setup;
262  ccc->destroy = s_Destroy;
263 
264  return ccc.release();
265 }
266 
267 
CPipe –.
Definition: ncbi_pipe.hpp:76
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static uch flags
int close(int fd)
Definition: connection.cpp:45
unique_ptr< T, TDeleter > make_c_unique(T *p, TDeleter d)
Eliminates the necessity for specifying types of both allocated resource and deallocating C function.
Definition: ncbimisc.hpp:1448
@ eTakeOwnership
An object can take ownership of another.
Definition: ncbi_types.h:136
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
CONNECTOR PIPE_CreateConnector(const string &cmd, const vector< string > &args, CPipe::TCreateFlags flags, CPipe *pipe, EOwnership own_pipe, size_t pipe_size)
Create CPipe-based CONNECTOR.
#define CONN_SET_METHOD(meta, method, function, connector)
const STimeout * default_timeout
default timeout pointer
void * handle
data handle of the connector
SMetaConnector * meta
back link to original meta
#define _VERIFY(expr)
Definition: ncbidbg.hpp:161
EIO_Status Write(const void *data, size_t count, size_t *written=0)
Write data to pipe (data always goes to the child's eStdIn handle).
Definition: ncbi_pipe.cpp:1991
TChildPollMask Poll(TChildPollMask mask, const STimeout *timeout=0)
Wait for I/O event(s).
Definition: ncbi_pipe.cpp:2006
unsigned int TChildPollMask
bitwise OR of "EChildIOHandle"
Definition: ncbi_pipe.hpp:124
EIO_Status SetTimeout(EIO_Event event, const STimeout *timeout)
Specify timeout for the pipe I/O.
Definition: ncbi_pipe.cpp:2047
EIO_Status Read(void *buf, size_t count, size_t *read=0, EChildIOHandle from_handle=eDefault)
Read data from the pipe's default read handle.
Definition: ncbi_pipe.cpp:1968
EIO_Status Open(const string &cmd, const vector< string > &args, TCreateFlags create_flags=0, const string &current_dir=kEmptyStr, const char *const env[]=0, size_t pipe_size=0)
Open pipe.
Definition: ncbi_pipe.cpp:1893
unsigned int TCreateFlags
bitwise OR of "ECreateFlag"
Definition: ncbi_pipe.hpp:111
EIO_Status Close(int *exitcode=0)
Close pipe.
Definition: ncbi_pipe.cpp:1931
EIO_Status Status(EIO_Event direction) const
Return a status of the last I/O operation.
Definition: ncbi_pipe.cpp:2031
@ fStdIn
Definition: ncbi_pipe.hpp:115
@ fDefault
see Wait()
Definition: ncbi_pipe.hpp:118
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
#define NPOS
Definition: ncbistr.hpp:133
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3401
#define kInfiniteTimeout
Definition: ncbi_types.h:82
EIO_Status
I/O status.
Definition: ncbi_core.h:132
enum ENcbiOwnership EOwnership
Ownership relations between objects.
EIO_Event
I/O event (or direction).
Definition: ncbi_core.h:118
#define kDefaultTimeout
Definition: ncbi_types.h:81
@ eIO_Success
everything is fine, no error occurred
Definition: ncbi_core.h:133
@ eIO_Unknown
unknown I/O error (likely fatal but can retry)
Definition: ncbi_core.h:139
@ eIO_Write
write
Definition: ncbi_core.h:121
@ eIO_Close
also serves as an error indicator in SOCK_Poll
Definition: ncbi_core.h:123
@ eIO_Read
read
Definition: ncbi_core.h:120
char * buf
if(yy_accept[yy_current_state])
const struct ncbi::grid::netcache::search::fields::SIZE size
#define strdup
Definition: ncbi_ansi_ext.h:70
static EIO_Status s_VT_Write(CONNECTOR connector, const void *buf, size_t size, size_t *n_written, const STimeout *timeout)
static EIO_Status s_VT_Read(CONNECTOR connector, void *buf, size_t size, size_t *n_read, const STimeout *timeout)
static EIO_Status s_VT_Close(CONNECTOR connector, const STimeout *timeout)
static const char * s_VT_GetType(CONNECTOR)
static void s_Setup(CONNECTOR connector)
USING_NCBI_SCOPE
static EIO_Status s_VT_Status(CONNECTOR connector, EIO_Event dir)
static EIO_Status s_VT_Wait(CONNECTOR connector, EIO_Event event, const STimeout *timeout)
static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout *)
static void s_Destroy(CONNECTOR connector)
static char * s_VT_Descr(CONNECTOR connector)
Implement CONNECTOR for a pipe interprocess communication (based on the NCBI CPipe).
static char tmp[2048]
Definition: utf8.c:42
Connector specification.
Standard set of connector methods to handle a connection (corresponding connectors are also in here),...
CPipe::TCreateFlags flags
vector< string > args
Timeout structure.
Definition: ncbi_types.h:76
#define _ASSERT
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Mon Dec 11 02:36:08 2023 by modify_doxy.py rev. 669887