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