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