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 #if defined (PEGASUS_OS_OS400)
47 # include <unistd.cleinc>
48 #else
49 # include <unistd.h>
50 #endif
51 #include <errno.h>
52
53 PEGASUS_NAMESPACE_BEGIN
54
55 AnonymousPipe::AnonymousPipe ()
56 {
57 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::AnonymousPipe ()");
58
59 AnonymousPipeHandle thePipe [2];
60 if (pipe (thePipe) < 0)
61 {
62 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
63 "Failed to create pipe: %s", strerror (errno));
64 mike 1.2 PEG_METHOD_EXIT ();
|
84 mike 1.2 "AnonymousPipe::AnonymousPipe (const char *, const char *)");
85
86 _readHandle = 0;
87 _writeHandle = 0;
88 _readOpen = false;
89 _writeOpen = false;
90
91 if (readHandle != NULL)
92 {
93 if (sscanf (readHandle, "%d", &_readHandle) != 1)
94 {
95 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
96 "Failed to create pipe: invalid read handle %s", readHandle);
97 PEG_METHOD_EXIT ();
98
99 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
100 "Failed to create pipe.");
101 throw Exception (mlp);
102 }
103 _readOpen = true;
104 }
105 mike 1.2
106 if (writeHandle != NULL)
107 {
108 if (sscanf (writeHandle, "%d", &_writeHandle) != 1)
109 {
110 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
111 "Failed to create pipe: invalid write handle %s", writeHandle);
112 PEG_METHOD_EXIT ();
113
114 MessageLoaderParms mlp ("Common.AnonymousPipe.CREATE_PIPE_FAILED",
115 "Failed to create pipe.");
116 throw Exception (mlp);
117 }
118 _writeOpen = true;
119 }
120
121 PEG_METHOD_EXIT ();
122 }
123
124 AnonymousPipe::~AnonymousPipe ()
125 {
126 mike 1.2 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::~AnonymousPipe");
127
128 if (_readOpen)
129 {
130 closeReadHandle ();
131 }
132 if (_writeOpen)
133 {
134 closeWriteHandle ();
135 }
136
137 PEG_METHOD_EXIT ();
138 }
139
140 AnonymousPipe::Status AnonymousPipe::writeBuffer (
141 const void * buffer,
142 Uint32 bytesToWrite)
143 {
144 //
145 // Treat invalid handle as connection closed
146 //
147 mike 1.2 if (!_writeOpen)
148 {
149 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
150 "Attempted to write to pipe whose write handle is not open");
151 return STATUS_CLOSED;
152 }
153
154 //
155 // Ignore SIGPIPE signals
156 //
157 SignalHandler::ignore (PEGASUS_SIGPIPE);
158
159 const char * writeBuffer = reinterpret_cast<const char*>(buffer);
160 int expectedBytes = bytesToWrite;
161 do
162 {
163 int bytesWritten = write (_writeHandle, writeBuffer, expectedBytes);
164
165 if (bytesWritten < 0)
166 {
167 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
168 mike 1.2 "Failed to write buffer to pipe: %s", strerror (errno));
169
170 if (errno == EPIPE)
171 {
172 //
173 // Other end of pipe is closed
174 //
175 return STATUS_CLOSED;
176 }
177 else if (errno == EINTR)
178 {
179 //
180 // Keep trying to write
181 //
182 bytesWritten = 0;
183 }
184 else
185 {
186 return STATUS_ERROR;
187 }
188 }
189 mike 1.2
190 expectedBytes -= bytesWritten;
191 writeBuffer += bytesWritten;
192 } while (expectedBytes > 0);
193
194 return STATUS_SUCCESS;
195 }
196
197 AnonymousPipe::Status AnonymousPipe::readBuffer (
198 void * buffer,
199 Uint32 bytesToRead)
200 {
201 //
202 // Treat invalid handle as connection closed
203 //
204 if (!_readOpen)
205 {
206 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
207 "Attempted to read from pipe whose read handle is not open");
208 return STATUS_CLOSED;
209 }
210 mike 1.2
211 Uint32 expectedBytes = bytesToRead;
212
213 do
214 {
215 int bytesRead = read (_readHandle, buffer, bytesToRead);
216
217 if (bytesRead == 0)
218 {
219 //
220 // Connection closed
221 //
222 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
223 "Failed to read buffer from pipe: connection closed");
224 return STATUS_CLOSED;
225 }
226
227 if (bytesRead < 0)
228 {
229 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
230 "Failed to read buffer from pipe: %s", strerror (errno));
231 mike 1.2
232 //
233 // If read was interrupted, keep trying
234 // Otherwise, return error
235 //
236 if (errno == EINTR)
237 {
238 if (bytesToRead == expectedBytes)
239 {
240 //
241 // Got a signal and haven't read any bytes yet
242 //
243 return STATUS_INTERRUPT;
244 }
245 bytesRead = 0;
246 }
247 else
248 {
249 //
250 // Error reading from pipe
251 //
252 mike 1.2 return STATUS_ERROR;
253 }
254 }
255
256 buffer = reinterpret_cast<char *>(buffer) + bytesRead;
257 bytesToRead -= bytesRead;
258 } while (bytesToRead > 0);
259
260 return STATUS_SUCCESS;
261 }
262
263 void AnonymousPipe::exportReadHandle (
264 char * buffer) const
265 {
266 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::exportReadHandle");
267
268 sprintf (buffer, "%d", _readHandle);
269
270 PEG_METHOD_EXIT ();
271 }
272
273 mike 1.2 void AnonymousPipe::exportWriteHandle (
274 char * buffer) const
275 {
276 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::exportWriteHandle");
277
278 sprintf (buffer, "%d", _writeHandle);
279
280 PEG_METHOD_EXIT ();
281 }
282
283 void AnonymousPipe::closeReadHandle ()
284 {
285 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::closeReadHandle");
286
287 if (_readOpen)
288 {
289 if (close (_readHandle) != 0)
290 {
291 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
292 "Failed to close read handle: %s", strerror (errno));
293 }
294 mike 1.2 else
295 {
296 _readOpen = false;
297 }
298 }
299 else
300 {
301 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
302 "Attempted to close read handle that was not open");
303 }
304
305 PEG_METHOD_EXIT ();
306 }
307
308 void AnonymousPipe::closeWriteHandle ()
309 {
310 PEG_METHOD_ENTER (TRC_OS_ABSTRACTION, "AnonymousPipe::closeWriteHandle");
311
312 if (_writeOpen)
313 {
314 if (close (_writeHandle) != 0)
315 mike 1.2 {
316 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
317 "Failed to close write handle: %s", strerror (errno));
318 }
319 else
320 {
321 _writeOpen = false;
322 }
323 }
324 else
325 {
326 Tracer::trace (TRC_OS_ABSTRACTION, Tracer::LEVEL2,
327 "Attempted to close write handle that was not open");
328 }
329
330 PEG_METHOD_EXIT ();
331 }
332
333 PEGASUS_NAMESPACE_END
|