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