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