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

Diff for /pegasus/src/Pegasus/Common/Socket.cpp between version 1.26 and 1.42

version 1.26, 2006/11/10 18:14:58 version 1.42, 2014/11/10 16:16:47
Line 1 
Line 1 
 //%2006////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development  // Licensed to The Open Group (TOG) under one or more contributor license
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.  // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;  // this work for additional information regarding copyright ownership.
 // IBM Corp.; EMC Corporation, The Open Group.  // Each contributor licenses this file to you under the OpenPegasus Open
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;  // Source License; you may not use this file except in compliance with the
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.  // License.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;  //
 // EMC Corporation; VERITAS Software Corporation; The Open Group.  // Permission is hereby granted, free of charge, to any person obtaining a
 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;  // copy of this software and associated documentation files (the "Software"),
 // EMC Corporation; Symantec Corporation; The Open Group.  // to deal in the Software without restriction, including without limitation
   // the rights to use, copy, modify, merge, publish, distribute, sublicense,
   // and/or sell copies of the Software, and to permit persons to whom the
   // Software is furnished to do so, subject to the following conditions:
   //
   // The above copyright notice and this permission notice shall be included
   // in all copies or substantial portions of the Software.
   //
   // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy  //////////////////////////////////////////////////////////////////////////
 // of this software and associated documentation files (the "Software"), to  
 // deal in the Software without restriction, including without limitation the  
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  
 // sell copies of the Software, and to permit persons to whom the Software is  
 // furnished to do so, subject to the following conditions:  
 //  
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
 //  
 //==============================================================================  
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
Line 38 
Line 36 
 #include <Pegasus/Common/Sharable.h> #include <Pegasus/Common/Sharable.h>
 #include <Pegasus/Common/Logger.h> #include <Pegasus/Common/Logger.h>
 #include <Pegasus/Common/System.h> #include <Pegasus/Common/System.h>
   #include <Pegasus/Common/Tracer.h>
   #include <Pegasus/Common/Threads.h>
   #include <Pegasus/Common/Mutex.h>
  
 //------------------------------------------------------------------------------  PEGASUS_NAMESPACE_BEGIN
 //  
 // PEGASUS_RETRY_SYSTEM_CALL()  #ifdef PEGASUS_OS_TYPE_WINDOWS
 //  static Uint32 _socketInterfaceRefCount = 0;
 //     This macro repeats the given system call until it returns something  static Mutex _socketInterfaceRefCountLock;
 //     other than EINTR.  #endif
 //  
 //------------------------------------------------------------------------------  
  
   Boolean Socket::timedConnect(
       SocketHandle socket,
       sockaddr* address,
       int addressLength,
       Uint32 timeoutMilliseconds)
   {
       int connectResult;
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
 #   define PEGASUS_RETRY_SYSTEM_CALL(EXPR, RESULT) RESULT = EXPR      connectResult = ::connect(socket, address, addressLength);
 #else #else
 #   define PEGASUS_RETRY_SYSTEM_CALL(EXPR, RESULT) \      Uint32 maxConnectAttempts = 100;
         while (((RESULT = (EXPR)) == -1) && (errno == EINTR))      // Retry the connect() until it succeeds or it fails with an error other
       // than EINTR, EAGAIN (for Linux), or ECONNREFUSED (for HP-UX and z/OS).
       while (((connectResult = ::connect(socket, address, addressLength)) == -1)
              && (maxConnectAttempts-- > 0)
              && ((errno == EINTR) || (errno == EAGAIN) ||
                  (errno == ECONNREFUSED)))
       {
           Threads::sleep(1);
       }
 #endif #endif
  
 PEGASUS_NAMESPACE_BEGIN      if (connectResult == 0)
       {
           return true;
       }
  
 static Uint32 _socketInterfaceRefCount = 0;      if (getSocketError() == PEGASUS_NETWORK_EINPROGRESS)
       {
           PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
               "Connection to server in progress.  Waiting up to %u milliseconds "
                   "for the socket to become connected.",
               timeoutMilliseconds));
   
           fd_set fdwrite;
           FD_ZERO(&fdwrite);
           FD_SET(socket, &fdwrite);
           struct timeval timeoutValue =
               { timeoutMilliseconds/1000, timeoutMilliseconds%1000*1000 };
           int selectResult = -1;
   
   #ifdef PEGASUS_OS_TYPE_WINDOWS
           PEGASUS_RETRY_SYSTEM_CALL(
               select(FD_SETSIZE, NULL, &fdwrite, &fdwrite, &timeoutValue),
               selectResult);
   #else
           PEGASUS_RETRY_SYSTEM_CALL(
               select(FD_SETSIZE, NULL, &fdwrite, NULL, &timeoutValue),
               selectResult);
   #endif
           if (selectResult == 0)
           {
               PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL1,
                   "select() timed out waiting for the socket connection to be "
                       "established.");
               return false;
           }
           else if (selectResult > 0)
           {
               int optval;
               SocketLength optlen = sizeof(int);
               getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&optval, &optlen);
               if (optval == 0)
               {
                   PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
                       "Connection with server established.");
                   return true;
               }
               else
               {
                   PEG_TRACE((TRC_HTTP, Tracer::LEVEL1,
                       "Did not connect, getsockopt() returned optval = %d",
                       optval));
                   return false;
               }
           }
           else
           {
               PEG_TRACE((TRC_HTTP, Tracer::LEVEL1,
                   "select() returned error code %d",
                   getSocketError()));
               return false;
           }
       }
   
       PEG_TRACE((TRC_HTTP, Tracer::LEVEL1,
           "connect() returned error code %d",
           getSocketError()));
       return false;
   }
  
 Sint32 Socket::read(SocketHandle socket, void* ptr, Uint32 size) Sint32 Socket::read(SocketHandle socket, void* ptr, Uint32 size)
 { {
Line 70 
Line 149 
 #endif #endif
 } }
  
   Sint32 Socket::peek(SocketHandle socket, void* ptr, Uint32 size)
   {
       #ifdef PEGASUS_OS_TYPE_WINDOWS
       return ::recv(socket, (char*)ptr, size, MSG_PEEK);
       #else
       int status;
       PEGASUS_RETRY_SYSTEM_CALL(::recv(socket, (char*)ptr, size, MSG_PEEK),
               status);
       return status;
       #endif
   }
   
 Sint32 Socket::write(SocketHandle socket, const void* ptr, Uint32 size) Sint32 Socket::write(SocketHandle socket, const void* ptr, Uint32 size)
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
Line 147 
Line 238 
     }     }
 } }
  
 void Socket::close(SocketHandle socket)  void Socket::close(SocketHandle& socket)
 { {
     if (socket != -1)      if (socket != PEGASUS_INVALID_SOCKET)
     {     {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
         if (!closesocket(socket))         if (!closesocket(socket))
             socket = -1;          {
               socket = PEGASUS_INVALID_SOCKET;
           }
 #else #else
         int status;         int status;
         PEGASUS_RETRY_SYSTEM_CALL(::close(socket), status);         PEGASUS_RETRY_SYSTEM_CALL(::close(socket), status);
  
         if (status == 0)         if (status == 0)
             socket = -1;  
 #endif  
     }  
 }  
   
 void Socket::enableBlocking(SocketHandle socket)  
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS              socket = PEGASUS_INVALID_SOCKET;
     unsigned long flag = 0;          }
     ioctlsocket(socket, FIONBIO, &flag);  
 #else  
     int flags = fcntl(socket, F_GETFL, 0);  
     flags &= ~O_NONBLOCK;  
     fcntl(socket, F_SETFL, flags);  
 #endif #endif
 } }
   }
  
 void Socket::disableBlocking(SocketHandle socket) void Socket::disableBlocking(SocketHandle socket)
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
     unsigned long flag = 1;      unsigned long flag = 1;    // Use "flag = 0" to enable blocking
     ioctlsocket(socket, FIONBIO, &flag);     ioctlsocket(socket, FIONBIO, &flag);
   #elif PEGASUS_OS_VMS
       int flag=1;                // Use "flag = 0" to enable blocking
       ioctl(socket, FIONBIO, &flag);
 #else #else
     int flags = fcntl(socket, F_GETFL, 0);     int flags = fcntl(socket, F_GETFL, 0);
     flags |= O_NONBLOCK;      flags |= O_NONBLOCK;    // Use "flags &= ~O_NONBLOCK" to enable blocking
     fcntl(socket, F_SETFL, flags);     fcntl(socket, F_SETFL, flags);
 #endif #endif
 } }
Line 191 
Line 277 
 void Socket::initializeInterface() void Socket::initializeInterface()
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
       AutoMutex mtx(_socketInterfaceRefCountLock);
     if (_socketInterfaceRefCount == 0)     if (_socketInterfaceRefCount == 0)
     {     {
         WSADATA tmp;         WSADATA tmp;
  
         if (WSAStartup(0x202, &tmp) == SOCKET_ERROR)          int err = WSAStartup(0x202, &tmp);
             WSACleanup();          if (err != 0)
           {
               throw Exception(MessageLoaderParms(
                   "Common.Socket.WSASTARTUP_FAILED.WINDOWS",
                   "WSAStartup failed with error $0.",
                   err));
           }
     }     }
  
     _socketInterfaceRefCount++;     _socketInterfaceRefCount++;
Line 206 
Line 299 
 void Socket::uninitializeInterface() void Socket::uninitializeInterface()
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
       AutoMutex mtx(_socketInterfaceRefCountLock);
     _socketInterfaceRefCount--;     _socketInterfaceRefCount--;
  
     if (_socketInterfaceRefCount == 0)     if (_socketInterfaceRefCount == 0)
Line 232 
Line 326 
    int opt = 1;    int opt = 1;
    setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));    setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
 } }
 //------------------------------------------------------------------------------  
 //  #ifdef PEGASUS_OS_ZOS
 // _setInformIfNewTCPIP()  
 //  
 //------------------------------------------------------------------------------  
 inline void _setInformIfNewTCPIP(SocketHandle socket) inline void _setInformIfNewTCPIP(SocketHandle socket)
 { {
 #ifdef PEGASUS_OS_ZOS  
    // This function enables the notification of the CIM Server that a new    // This function enables the notification of the CIM Server that a new
    // TCPIP transport layer is active. This is needed to be aware of a    // TCPIP transport layer is active. This is needed to be aware of a
    // restart of the transport layer. When this option is in effect,    // restart of the transport layer. When this option is in effect,
Line 253 
Line 343 
        SO_EioIfNewTP,        SO_EioIfNewTP,
        (char*)&NewTcpipOn,        (char*)&NewTcpipOn,
        sizeof(NewTcpipOn));        sizeof(NewTcpipOn));
 #endif  
 } }
   #else
   inline void _setInformIfNewTCPIP(SocketHandle)
   {
   }
   #endif
  
  
 SocketHandle Socket::createSocket(int domain, int type, int protocol) SocketHandle Socket::createSocket(int domain, int type, int protocol)
Line 266 
Line 360 
         return socket(domain,type,protocol);         return socket(domain,type,protocol);
     }     }
  
   #ifdef PEGASUS_OS_ZOS
     bool sendTcpipMsg = true;     bool sendTcpipMsg = true;
   #endif
  
     while (1)     while (1)
     {     {
         newSocket = socket(domain,type,protocol);         newSocket = socket(domain,type,protocol);
  
           if ((newSocket != PEGASUS_INVALID_SOCKET) ||
               (getSocketError() != PEGASUS_NETWORK_TRYAGAIN))
           {
               break;
           }
   
   #ifdef PEGASUS_OS_ZOS
         // The program should wait for transport layer to become ready.         // The program should wait for transport layer to become ready.
  
         if (newSocket == PEGASUS_INVALID_SOCKET &&  
            getSocketError() == PEGASUS_NETWORK_TCPIP_TRYAGAIN )  
         {  
            if (sendTcpipMsg)            if (sendTcpipMsg)
            {            {
                Logger::put_l(                Logger::put_l(
                    Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,                    Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
                   MessageLoaderParms(
                    "Common.Socket.WAIT_FOR_TCPIP",                    "Common.Socket.WAIT_FOR_TCPIP",
                    "TCP/IP temporary unavailable.");                      "TCP/IP temporary unavailable."));
                sendTcpipMsg=false;                sendTcpipMsg=false;
            }            }
  
            System::sleep(30);            System::sleep(30);
            continue;  #endif
         }  
         else  
         {  
            break;  
         }  
     } // wait for the transport layer become ready.     } // wait for the transport layer become ready.
  
     // Is the socket in an unrecoverable error ?     // Is the socket in an unrecoverable error ?


Legend:
Removed from v.1.26  
changed lines
  Added in v.1.42

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2