1 martin 1.7 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.8 //
|
3 martin 1.7 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.8 //
|
10 martin 1.7 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.8 //
|
17 martin 1.7 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.8 //
|
20 martin 1.7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.8 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.7 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.8 //
|
28 martin 1.7 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32
33 #include "AnonymousPipe.h"
34 #include <Pegasus/Common/Signal.h>
35
36 #if defined (PEGASUS_OS_VMS)
37 # include <climsgdef.h>
38 # include <stdio.h>
39 # include <stdlib.h>
40 # include <perror.h>
41 # include <processes.h>
42 #endif /* PEGASUS_OS_VMS */
43
|
44 ouyang.jian 1.5 #include <unistd.h>
|
45 mike 1.2 #include <errno.h>
46
47 PEGASUS_NAMESPACE_BEGIN
48
49 AnonymousPipe::AnonymousPipe ()
50 {
51 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::AnonymousPipe ()");
52
53 AnonymousPipeHandle thePipe [2];
54 if (pipe (thePipe) < 0)
55 {
|
56 marek 1.6 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
57 marek 1.4 "Failed to create pipe: %s", strerror (errno)));
|
58 mike 1.2 PEG_METHOD_EXIT ();
|
59 kumpf 1.3
|
60 mike 1.2 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
61 "Failed to create pipe.");
62 throw Exception (mlp);
63 }
64
65 _readHandle = thePipe [0];
66 _writeHandle = thePipe [1];
67 _readOpen = true;
68 _writeOpen = true;
69
70 PEG_METHOD_EXIT ();
71 }
72
73 AnonymousPipe::AnonymousPipe (
74 const char * readHandle,
75 const char * writeHandle)
76 {
|
77 kumpf 1.3 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION,
|
78 mike 1.2 "AnonymousPipe::AnonymousPipe (const char *, const char *)");
79
80 _readHandle = 0;
81 _writeHandle = 0;
82 _readOpen = false;
83 _writeOpen = false;
84
85 if (readHandle != NULL)
86 {
87 if (sscanf (readHandle, "%d", &_readHandle) != 1)
88 {
|
89 marek 1.6 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
90 marek 1.4 "Failed to create pipe: invalid read handle %s", readHandle));
|
91 mike 1.2 PEG_METHOD_EXIT ();
92
93 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
94 "Failed to create pipe.");
95 throw Exception (mlp);
96 }
97 _readOpen = true;
98 }
99
100 if (writeHandle != NULL)
101 {
102 if (sscanf (writeHandle, "%d", &_writeHandle) != 1)
103 {
|
104 marek 1.6 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
105 marek 1.4 "Failed to create pipe: invalid write handle %s", writeHandle));
|
106 mike 1.2 PEG_METHOD_EXIT ();
107
108 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
109 "Failed to create pipe.");
110 throw Exception (mlp);
111 }
112 _writeOpen = true;
113 }
114
115 PEG_METHOD_EXIT ();
116 }
117
118 AnonymousPipe::~AnonymousPipe ()
119 {
120 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::~AnonymousPipe");
121
122 if (_readOpen)
123 {
124 closeReadHandle ();
125 }
126 if (_writeOpen)
127 mike 1.2 {
128 closeWriteHandle ();
129 }
130
131 PEG_METHOD_EXIT ();
132 }
133
134 AnonymousPipe::Status AnonymousPipe::writeBuffer (
135 const void * buffer,
136 Uint32 bytesToWrite)
137 {
138 //
139 // Treat invalid handle as connection closed
140 //
141 if (!_writeOpen)
142 {
|
143 marek 1.4 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
144 mike 1.2 "Attempted to write to pipe whose write handle is not open");
145 return STATUS_CLOSED;
146 }
147
148 //
149 // Ignore SIGPIPE signals
150 //
151 SignalHandler::ignore (PEGASUS_SIGPIPE);
152
153 const char * writeBuffer = reinterpret_cast<const char*>(buffer);
154 int expectedBytes = bytesToWrite;
155 do
156 {
157 int bytesWritten = write (_writeHandle, writeBuffer, expectedBytes);
158
159 if (bytesWritten < 0)
160 {
|
161 marek 1.4 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
162 "Failed to write buffer to pipe: %s", strerror (errno)));
|
163 mike 1.2
164 if (errno == EPIPE)
165 {
166 //
167 // Other end of pipe is closed
168 //
169 return STATUS_CLOSED;
170 }
171 else if (errno == EINTR)
172 {
173 //
174 // Keep trying to write
175 //
176 bytesWritten = 0;
177 }
178 else
179 {
180 return STATUS_ERROR;
181 }
182 }
183
184 mike 1.2 expectedBytes -= bytesWritten;
185 writeBuffer += bytesWritten;
186 } while (expectedBytes > 0);
187
188 return STATUS_SUCCESS;
189 }
190
191 AnonymousPipe::Status AnonymousPipe::readBuffer (
192 void * buffer,
193 Uint32 bytesToRead)
194 {
195 //
196 // Treat invalid handle as connection closed
197 //
198 if (!_readOpen)
199 {
|
200 marek 1.4 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
201 mike 1.2 "Attempted to read from pipe whose read handle is not open");
202 return STATUS_CLOSED;
203 }
204
205 Uint32 expectedBytes = bytesToRead;
206
207 do
208 {
209 int bytesRead = read (_readHandle, buffer, bytesToRead);
210
211 if (bytesRead == 0)
212 {
213 //
214 // Connection closed
215 //
|
216 marek 1.4 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
217 mike 1.2 "Failed to read buffer from pipe: connection closed");
218 return STATUS_CLOSED;
219 }
220
221 if (bytesRead < 0)
222 {
|
223 marek 1.4 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
224 "Failed to read buffer from pipe: %s", strerror (errno)));
|
225 mike 1.2
226 //
227 // If read was interrupted, keep trying
228 // Otherwise, return error
229 //
230 if (errno == EINTR)
231 {
232 if (bytesToRead == expectedBytes)
233 {
234 //
235 // Got a signal and haven't read any bytes yet
236 //
237 return STATUS_INTERRUPT;
238 }
239 bytesRead = 0;
240 }
241 else
242 {
243 //
244 // Error reading from pipe
245 //
246 mike 1.2 return STATUS_ERROR;
247 }
248 }
249
250 buffer = reinterpret_cast<char *>(buffer) + bytesRead;
251 bytesToRead -= bytesRead;
252 } while (bytesToRead > 0);
253
254 return STATUS_SUCCESS;
255 }
256
257 void AnonymousPipe::exportReadHandle (
258 char * buffer) const
259 {
260 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::exportReadHandle");
261
262 sprintf (buffer, "%d", _readHandle);
263
264 PEG_METHOD_EXIT ();
265 }
266
267 mike 1.2 void AnonymousPipe::exportWriteHandle (
268 char * buffer) const
269 {
270 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::exportWriteHandle");
271
272 sprintf (buffer, "%d", _writeHandle);
273
274 PEG_METHOD_EXIT ();
275 }
276
277 void AnonymousPipe::closeReadHandle ()
278 {
279 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::closeReadHandle");
280
281 if (_readOpen)
282 {
283 if (close (_readHandle) != 0)
284 {
|
285 marek 1.4 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
286 "Failed to close read handle: %s", strerror (errno)));
|
287 mike 1.2 }
288 else
289 {
290 _readOpen = false;
291 }
292 }
293 else
294 {
|
295 marek 1.4 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
296 mike 1.2 "Attempted to close read handle that was not open");
297 }
298
299 PEG_METHOD_EXIT ();
300 }
301
302 void AnonymousPipe::closeWriteHandle ()
303 {
304 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::closeWriteHandle");
305
306 if (_writeOpen)
307 {
308 if (close (_writeHandle) != 0)
309 {
|
310 marek 1.4 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
311 "Failed to close write handle: %s", strerror (errno)));
|
312 mike 1.2 }
313 else
314 {
315 _writeOpen = false;
316 }
317 }
318 else
319 {
|
320 marek 1.4 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
321 mike 1.2 "Attempted to close write handle that was not open");
322 }
323
324 PEG_METHOD_EXIT ();
325 }
326
327 PEGASUS_NAMESPACE_END
|