(file) Return to AnonymousPipeUnix.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2