1 martin 1.10 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.11 //
|
3 martin 1.10 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.11 //
|
10 martin 1.10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.11 //
|
17 martin 1.10 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.11 //
|
20 martin 1.10 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.11 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.10 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.11 //
|
28 martin 1.10 //////////////////////////////////////////////////////////////////////////
|
29 kumpf 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32
33 #include "AnonymousPipe.h"
34 #include <Pegasus/Common/Signal.h>
|
35 mike 1.6 #include "Network.h"
|
36 kumpf 1.1 #include <windows.h>
37 #include <stdio.h>
38
39
40 PEGASUS_NAMESPACE_BEGIN
41
|
42 kumpf 1.7 AnonymousPipe::AnonymousPipe()
|
43 kumpf 1.1 {
|
44 kumpf 1.7 PEG_METHOD_ENTER(TRC_OS_ABSTRACTION, "AnonymousPipe::AnonymousPipe()");
|
45 kumpf 1.1
|
46 kumpf 1.7 AnonymousPipeHandle thePipe[2];
|
47 kumpf 1.1
48 SECURITY_ATTRIBUTES saAttr;
|
49 kumpf 1.7 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
50 kumpf 1.1 saAttr.bInheritHandle = TRUE;
51 saAttr.lpSecurityDescriptor = NULL;
52
|
53 kumpf 1.7 if (!CreatePipe(&thePipe[0], &thePipe[1], &saAttr, 0))
|
54 kumpf 1.1 {
|
55 marek 1.9 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
56 marek 1.8 "Failed to create pipe. Error code: %d", GetLastError()));
|
57 kumpf 1.7 PEG_METHOD_EXIT();
|
58 kumpf 1.1
|
59 kumpf 1.7 MessageLoaderParms mlp("Common.AnonymousPipe.CREATE_PIPE_FAILED",
|
60 kumpf 1.1 "Failed to create pipe.");
|
61 kumpf 1.7 throw Exception(mlp);
|
62 kumpf 1.1 }
63
|
64 kumpf 1.7 _readHandle = thePipe[0];
65 _writeHandle = thePipe[1];
|
66 kumpf 1.1 _readOpen = true;
67 _writeOpen = true;
68
|
69 kumpf 1.7 PEG_METHOD_EXIT();
|
70 kumpf 1.1 }
71
|
72 kumpf 1.7 AnonymousPipe::AnonymousPipe(
|
73 kumpf 1.1 const char * readHandle,
74 const char * writeHandle)
75 {
|
76 kumpf 1.7 PEG_METHOD_ENTER(TRC_OS_ABSTRACTION,
77 "AnonymousPipe::AnonymousPipe(const char *, const char *)");
|
78 kumpf 1.1
79 _readHandle = 0;
80 _writeHandle = 0;
81 _readOpen = false;
82 _writeOpen = false;
83
84 if (readHandle != NULL)
85 {
|
86 kumpf 1.7 if (sscanf(readHandle, "%p", &_readHandle) != 1)
|
87 kumpf 1.1 {
|
88 marek 1.9 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
89 marek 1.8 "Failed to create pipe: invalid read handle %s", readHandle));
|
90 kumpf 1.7 PEG_METHOD_EXIT();
|
91 kumpf 1.1
|
92 kumpf 1.7 MessageLoaderParms mlp("Common.AnonymousPipe.CREATE_PIPE_FAILED",
|
93 kumpf 1.1 "Failed to create pipe.");
|
94 kumpf 1.7 throw Exception(mlp);
|
95 kumpf 1.1 }
96 _readOpen = true;
97 }
98
99 if (writeHandle != NULL)
100 {
|
101 kumpf 1.7 if (sscanf(writeHandle, "%p", &_writeHandle) != 1)
|
102 kumpf 1.1 {
|
103 marek 1.9 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
|
104 marek 1.8 "Failed to create pipe: invalid write handle %s", writeHandle));
|
105 kumpf 1.7 PEG_METHOD_EXIT();
|
106 kumpf 1.1
|
107 kumpf 1.7 MessageLoaderParms mlp("Common.AnonymousPipe.CREATE_PIPE_FAILED",
|
108 kumpf 1.1 "Failed to create pipe.");
|
109 kumpf 1.7 throw Exception(mlp);
|
110 kumpf 1.1 }
111 _writeOpen = true;
112 }
113
|
114 kumpf 1.7 PEG_METHOD_EXIT();
|
115 kumpf 1.1 }
116
|
117 kumpf 1.7 AnonymousPipe::~AnonymousPipe()
|
118 kumpf 1.1 {
|
119 kumpf 1.7 PEG_METHOD_ENTER(TRC_OS_ABSTRACTION, "AnonymousPipe::~AnonymousPipe");
|
120 kumpf 1.1
121 if (_readOpen)
122 {
|
123 kumpf 1.7 closeReadHandle();
|
124 kumpf 1.1 }
125
126 if (_writeOpen)
127 {
|
128 kumpf 1.7 closeWriteHandle();
|
129 kumpf 1.1 }
130
|
131 kumpf 1.7 PEG_METHOD_EXIT();
|
132 kumpf 1.1 }
133
|
134 kumpf 1.7 AnonymousPipe::Status AnonymousPipe::writeBuffer(
|
135 david.dillard 1.3 const void * buffer,
|
136 kumpf 1.1 Uint32 bytesToWrite)
137 {
138 //
139 // Treat invalid handle as connection closed
140 //
141 if (!_writeOpen)
142 {
|
143 marek 1.8 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
144 kumpf 1.1 "Attempted to write to pipe whose write handle is not open");
145 return STATUS_CLOSED;
146 }
147
148 //
149 // Ignore SIGPIPE signals
150 //
|
151 kumpf 1.7 SignalHandler::ignore(PEGASUS_SIGPIPE);
|
152 kumpf 1.1
|
153 david.dillard 1.3 const char * writeBuffer = reinterpret_cast<const char *>(buffer);
|
154 kumpf 1.1 DWORD expectedBytes = bytesToWrite;
155 do
156 {
157 BOOL returnValue;
158 DWORD bytesWritten = 0;
|
159 kumpf 1.7 returnValue = WriteFile(_writeHandle, writeBuffer, expectedBytes,
|
160 kumpf 1.1 &bytesWritten, NULL);
161
162 if (!returnValue)
163 {
|
164 marek 1.8 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
165 kumpf 1.7 "Failed to write buffer to pipe. Error code: %d",
|
166 marek 1.8 GetLastError()));
|
167 kumpf 1.1 return STATUS_ERROR;
168 }
169
170 if (bytesWritten < 0)
171 {
|
172 marek 1.8 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
173 kumpf 1.7 "Failed to write buffer to pipe. Error code: %d",
|
174 marek 1.8 GetLastError()));
|
175 kumpf 1.1
|
176 kumpf 1.7 if ((GetLastError() == ERROR_PIPE_NOT_CONNECTED) ||
177 (GetLastError() == ERROR_BROKEN_PIPE))
|
178 kumpf 1.1 {
179 return STATUS_CLOSED;
180 }
181 else
182 {
183 return STATUS_ERROR;
184 }
185 }
186
187 expectedBytes -= bytesWritten;
188 writeBuffer += bytesWritten;
189 } while (expectedBytes > 0);
190
191 return STATUS_SUCCESS;
192 }
193
|
194 kumpf 1.7 AnonymousPipe::Status AnonymousPipe::readBuffer(
|
195 david.dillard 1.3 void * buffer,
|
196 kumpf 1.1 Uint32 bytesToRead)
197 {
198 //
199 // Treat invalid handle as connection closed
200 //
201 if (!_readOpen)
202 {
|
203 marek 1.8 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
204 kumpf 1.1 "Attempted to read from pipe whose read handle is not open");
205 return STATUS_CLOSED;
206 }
207
208 DWORD expectedBytes = bytesToRead;
209
210 do
211 {
212 BOOL returnValue;
213 DWORD bytesRead;
|
214 kumpf 1.7 returnValue = ReadFile(
215 _readHandle, buffer, bytesToRead, &bytesRead, NULL);
|
216 kumpf 1.1
217 if (!returnValue)
218 {
|
219 marek 1.8 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
220 kumpf 1.7 "Failed to read buffer from pipe. Error code: %d",
|
221 marek 1.8 GetLastError()));
|
222 kumpf 1.7 if ((GetLastError() == ERROR_PIPE_NOT_CONNECTED) ||
223 (GetLastError() == ERROR_BROKEN_PIPE))
|
224 kumpf 1.1 {
225 return STATUS_CLOSED;
226 }
227
228 return STATUS_ERROR;
229 }
230
231 if (bytesRead == 0)
232 {
233 //
234 // Connection closed
235 //
|
236 marek 1.8 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
237 kumpf 1.1 "Failed to read buffer from pipe: connection closed");
238 return STATUS_CLOSED;
239 }
240
241 if (bytesRead < 0)
242 {
|
243 marek 1.8 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
244 kumpf 1.7 "Failed to read buffer from pipe. Error code: %d",
|
245 marek 1.8 GetLastError()));
|
246 kumpf 1.1
247 //
248 // Error reading from pipe
249 //
250 return STATUS_ERROR;
251 }
252
|
253 david.dillard 1.3 buffer = reinterpret_cast<char *>(buffer) + bytesRead;
|
254 kumpf 1.1 bytesToRead -= bytesRead;
255 } while (bytesToRead > 0);
256
257 return STATUS_SUCCESS;
258 }
259
|
260 kumpf 1.7 void AnonymousPipe::exportReadHandle(char * buffer) const
|
261 kumpf 1.1 {
|
262 kumpf 1.7 PEG_METHOD_ENTER(TRC_OS_ABSTRACTION, "AnonymousPipe::exportReadHandle");
|
263 kumpf 1.1
|
264 kumpf 1.7 sprintf(buffer, "%p", _readHandle);
|
265 kumpf 1.1
|
266 kumpf 1.7 PEG_METHOD_EXIT();
|
267 kumpf 1.1 }
268
|
269 kumpf 1.7 void AnonymousPipe::exportWriteHandle(char * buffer) const
|
270 kumpf 1.1 {
|
271 kumpf 1.7 PEG_METHOD_ENTER(TRC_OS_ABSTRACTION, "AnonymousPipe::exportWriteHandle");
|
272 kumpf 1.1
|
273 kumpf 1.7 sprintf(buffer, "%p", _writeHandle);
|
274 kumpf 1.1
|
275 kumpf 1.7 PEG_METHOD_EXIT();
|
276 kumpf 1.1 }
277
|
278 kumpf 1.7 void AnonymousPipe::closeReadHandle()
|
279 kumpf 1.1 {
|
280 kumpf 1.7 PEG_METHOD_ENTER(TRC_OS_ABSTRACTION, "AnonymousPipe::closeReadHandle");
|
281 kumpf 1.1
282 if (_readOpen)
283 {
|
284 kumpf 1.7 if (!CloseHandle(_readHandle))
|
285 kumpf 1.1 {
|
286 marek 1.8 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
287 kumpf 1.7 "Failed to close read handle. Error code: %d",
|
288 marek 1.8 GetLastError()));
|
289 kumpf 1.1 }
290 else
291 {
292 _readOpen = false;
293 }
294 }
295 else
296 {
|
297 marek 1.8 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
298 kumpf 1.1 "Attempted to close read handle that was not open");
299 }
300
|
301 kumpf 1.7 PEG_METHOD_EXIT();
|
302 kumpf 1.1 }
303
|
304 kumpf 1.7 void AnonymousPipe::closeWriteHandle()
|
305 kumpf 1.1 {
|
306 kumpf 1.7 PEG_METHOD_ENTER(TRC_OS_ABSTRACTION, "AnonymousPipe::closeWriteHandle");
|
307 kumpf 1.1
308 if (_writeOpen)
309 {
|
310 kumpf 1.7 if (!CloseHandle(_writeHandle))
|
311 kumpf 1.1 {
|
312 marek 1.8 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
313 kumpf 1.7 "Failed to close write handle. Error code: %d",
|
314 marek 1.8 GetLastError()));
|
315 kumpf 1.1 }
316 else
317 {
318 _writeOpen = false;
319 }
320 }
321 else
322 {
|
323 marek 1.8 PEG_TRACE_CSTRING(TRC_OS_ABSTRACTION, Tracer::LEVEL2,
|
324 kumpf 1.1 "Attempted to close write handle that was not open");
325 }
326
|
327 kumpf 1.7 PEG_METHOD_EXIT();
|
328 kumpf 1.1 }
329
330 PEGASUS_NAMESPACE_END
|