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

  1 karl  1.22 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.2  //
  3 karl  1.17 // 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 karl  1.14 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.17 // 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.18 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.22 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.2  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15 kumpf 1.4  // 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 mike  1.2  // 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 karl  1.22 // 
 21 kumpf 1.4  // 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 kumpf 1.4  // 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 mike  1.2  // 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: Mike Brasher (mbrasher@bmc.com)
 33            //
 34 joyce.j 1.19 // Modified By: Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2513
 35 david.dillard 1.20 //              David Dillard, Symantec Corp.,  (david_dillard@symantec.com)
 36 mike          1.2  //
 37                    //%/////////////////////////////////////////////////////////////////////////////
 38                    
 39                    #include "Socket.h"
 40 mike          1.23 #include "Network.h"
 41                    #include <cctype>
 42                    #include <cstring>
 43                    #include <Pegasus/Common/Sharable.h>
 44                    
 45                    //------------------------------------------------------------------------------
 46                    //
 47                    // PEGASUS_RETRY_SYSTEM_CALL()
 48                    //
 49                    //     This macro repeats the given system call until it returns something
 50                    //     other than EINTR.
 51                    //
 52                    //------------------------------------------------------------------------------
 53 mike          1.2  
 54                    #ifdef PEGASUS_OS_TYPE_WINDOWS
 55 mike          1.23 #   define PEGASUS_RETRY_SYSTEM_CALL(EXPR, RESULT) RESULT = EXPR
 56                    #else
 57                    #   define PEGASUS_RETRY_SYSTEM_CALL(EXPR, RESULT) \
 58                            while (((RESULT = (EXPR)) == -1) && (errno == EINTR))
 59 mike          1.2  #endif
 60                    
 61                    PEGASUS_NAMESPACE_BEGIN
 62                    
 63                    static Uint32 _socketInterfaceRefCount = 0;
 64                    
 65 mike          1.23 Sint32 Socket::read(SocketHandle socket, void* ptr, Uint32 size)
 66 mike          1.2  {
 67                    #ifdef PEGASUS_OS_TYPE_WINDOWS
 68                        return ::recv(socket, (char*)ptr, size, 0);
 69                    #else
 70 mike          1.23     int status;
 71                        PEGASUS_RETRY_SYSTEM_CALL(::read(socket, (char*)ptr, size), status);
 72                        return status;
 73 mday          1.11 #endif
 74 mike          1.2  }
 75                    
 76 mike          1.23 Sint32 Socket::write(SocketHandle socket, const void* ptr, Uint32 size)
 77 mike          1.2  {
 78                    #ifdef PEGASUS_OS_TYPE_WINDOWS
 79                        return ::send(socket, (const char*)ptr, size, 0);
 80                    #else
 81 mike          1.23     int status;
 82                        PEGASUS_RETRY_SYSTEM_CALL(::write(socket, (char*)ptr, size), status);
 83                        return status;
 84 mday          1.11 #endif
 85 mike          1.2  }
 86                    
 87 marek         1.24 Sint32 Socket::timedWrite(SocketHandle socket, 
 88                                              const void* ptr, 
 89                                              Uint32 size, 
 90                                              Uint32 socketWriteTimeout)
 91                    {
 92                        Sint32 bytesWritten = 0;
 93                        Sint32 totalBytesWritten = 0;
 94                        Boolean socketTimedOut = false;
 95                        int selreturn = 0;
 96                        while (1)
 97                        {
 98                    #ifdef PEGASUS_OS_TYPE_WINDOWS
 99                            PEGASUS_RETRY_SYSTEM_CALL(
100                                ::send(socket, (const char*)ptr, size, 0), bytesWritten);
101                    #else
102                            PEGASUS_RETRY_SYSTEM_CALL(
103                                ::write(socket, (char*)ptr, size), bytesWritten);
104                    #endif
105                            // Some data written this cycle ? 
106                            // Add it to the total amount of written data.
107                            if (bytesWritten > 0)
108 marek         1.24         {
109                                totalBytesWritten += bytesWritten;
110                                socketTimedOut = false;
111                            }
112                    
113                            // All data written ? return amount of data written
114                            if ((Uint32)bytesWritten == size)
115                            {
116                                return totalBytesWritten;
117                            }
118                            // If data has been written partially, we resume writing data
119                            // this also accounts for the case of a signal interrupt
120                            // (i.e. errno = EINTR)
121                            if (bytesWritten > 0)
122                            {
123                                size -= bytesWritten;
124                                ptr = (void *)((char *)ptr + bytesWritten);
125                                continue;
126                            }
127                            // Something went wrong
128                            if (bytesWritten == PEGASUS_SOCKET_ERROR)
129 marek         1.24         {
130                                // if we already waited for the socket to get ready, bail out
131                                if( socketTimedOut ) return bytesWritten;
132                    #ifdef PEGASUS_OS_TYPE_WINDOWS
133                                if (WSAGetLastError() == WSAEWOULDBLOCK)
134                    #else
135                                if (errno == EAGAIN || errno == EWOULDBLOCK)
136                    #endif
137                                {
138                                    fd_set fdwrite;
139                                     // max. timeout seconds waiting for the socket to get ready
140                                    struct timeval tv = { socketWriteTimeout, 0 };
141                                    FD_ZERO(&fdwrite);
142                                    FD_SET(socket, &fdwrite);
143                                    selreturn = select(FD_SETSIZE, NULL, &fdwrite, NULL, &tv);
144                                    if (selreturn == 0) socketTimedOut = true; // ran out of time
145                                    continue;            
146                                }
147                                return bytesWritten;
148                            }
149                        }
150 marek         1.24 }
151                    
152 mike          1.23 void Socket::close(SocketHandle socket)
153 mike          1.2  {
154 mike          1.23     if (socket != -1)
155                        {
156                    #ifdef PEGASUS_OS_TYPE_WINDOWS
157                    	if(!closesocket(socket)) 
158                    	    socket = -1;
159                    #else
160                    	int status;
161                    	PEGASUS_RETRY_SYSTEM_CALL(::close(socket), status);
162                    
163                    	if (status == 0)
164                    	    socket = -1;
165                    #endif
166                        }
167 mike          1.2  }
168                    
169 mike          1.23 void Socket::enableBlocking(SocketHandle socket)
170 mike          1.2  {
171                    #ifdef PEGASUS_OS_TYPE_WINDOWS
172                        unsigned long flag = 0;
173                        ioctlsocket(socket, FIONBIO, &flag);
174                    #else
175                        int flags = fcntl(socket, F_GETFL, 0);
176                        flags &= ~O_NONBLOCK;
177                        fcntl(socket, F_SETFL, flags);
178                    #endif
179                    }
180                    
181 mike          1.23 void Socket::disableBlocking(SocketHandle socket)
182 mike          1.2  {
183                    #ifdef PEGASUS_OS_TYPE_WINDOWS
184                        unsigned long flag = 1;
185                        ioctlsocket(socket, FIONBIO, &flag);
186                    #else
187                        int flags = fcntl(socket, F_GETFL, 0);
188                        flags |= O_NONBLOCK;
189                        fcntl(socket, F_SETFL, flags);
190                    #endif
191                    }
192                    
193                    void Socket::initializeInterface()
194                    {
195                    #ifdef PEGASUS_OS_TYPE_WINDOWS
196                        if (_socketInterfaceRefCount == 0)
197                        {
198 david.dillard 1.20         WSADATA tmp;
199 mike          1.2  
200 mike          1.23 	if (WSAStartup(0x202, &tmp) == SOCKET_ERROR)
201                    	    WSACleanup();
202 mike          1.2      }
203                    
204                        _socketInterfaceRefCount++;
205                    #endif
206                    }
207                    
208                    void Socket::uninitializeInterface()
209                    {
210                    #ifdef PEGASUS_OS_TYPE_WINDOWS
211                        _socketInterfaceRefCount--;
212                    
213                        if (_socketInterfaceRefCount == 0)
214 david.dillard 1.20         WSACleanup();
215 mike          1.2  #endif
216                    }
217                    
218                    PEGASUS_NAMESPACE_END
219 mday          1.11 

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2