(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.9.4.7 and 1.32.4.1

version 1.9.4.7, 2003/08/13 19:39:50 version 1.32.4.1, 2008/09/12 07:56:43
Line 1 
Line 1 
 //%/////////////////////////////////////////////////////////////////////////////  //%2006////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,  // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // The Open Group, Tivoli Systems  // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation, The Open Group.
   // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; Symantec Corporation; The Open Group.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 21 
Line 29 
 // //
 //============================================================================== //==============================================================================
 // //
 // Author: Mike Brasher (mbrasher@bmc.com)  
 //  
 // Modified By:  
 //  
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include "Socket.h" #include "Socket.h"
   #include "Network.h"
 #ifdef PEGASUS_OS_TYPE_WINDOWS  
 #include <windows.h>  
 # ifndef _WINSOCKAPI_  
 #   include <winsock2.h>  
 # endif  
 #else  
 # include <cctype> # include <cctype>
 #ifndef PEGASUS_OS_OS400  #include <cstring>
 #   include <unistd.h>  
 #else  
 #   include <unistd.cleinc>  
 #endif  
 #   include <string.h>  // added by rk for memcpy  
 # include <cstdlib>  
 # include <errno.h>  
 # include <fcntl.h>  
 # include <netdb.h>  
 # include <netinet/in.h>  
 # include <arpa/inet.h>  
 # include <sys/socket.h>  
 # include <errno.h>  
 #endif  
   
 #include <Pegasus/Common/Sharable.h> #include <Pegasus/Common/Sharable.h>
   #include <Pegasus/Common/Logger.h>
   #include <Pegasus/Common/System.h>
   #include <Pegasus/Common/Tracer.h>
   
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
 static Uint32 _socketInterfaceRefCount = 0; static Uint32 _socketInterfaceRefCount = 0;
  
 Sint32 Socket::read(Sint32 socket, void* ptr, Uint32 size)  Boolean Socket::timedConnect(
       SocketHandle socket,
       sockaddr* address,
       int addressLength,
       Uint32 timeoutMilliseconds)
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS      int connectResult;
     return ::recv(socket, (char*)ptr, size, 0);      PEGASUS_RETRY_SYSTEM_CALL(
 #elif defined(PEGASUS_OS_ZOS)          ::connect(socket, address, addressLength), connectResult);
     int i=::read(socket, (char*)ptr, size);  
     __atoe_l((char *)ptr,size);  
     return i;  
 #else  
   
 #if defined (__GNUC__)  
     int ccode = TEMP_FAILURE_RETRY(::read(socket, (char*)ptr, size));  
     return ccode;  
 #else  
     return ::read(socket, (char*)ptr, size);  
 #endif  
 #endif  
 }  
  
 Sint32 Socket::write(Sint32 socket, const void* ptr, Uint32 size)      if (connectResult == 0)
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS          return true;
     return ::send(socket, (const char*)ptr, size, 0);  
 #elif defined(PEGASUS_OS_ZOS)  
     char * ptr2 = (char *)malloc(size);  
     int i;  
     memcpy(ptr2,ptr,size);  
     __etoa_l(ptr2,size);  
     i = ::write(socket, ptr2, size);  
     free(ptr2);  
     return i;  
 #else  
 #if (__GNUC__)  
     int ccode = TEMP_FAILURE_RETRY(::write(socket, (char*)ptr, size));  
     return ccode;  
 #else  
     return ::write(socket, (char*)ptr, size);  
 #endif  
 #endif  
 } }
  
 void Socket::close(Sint32 socket)      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 #ifdef PEGASUS_OS_TYPE_WINDOWS
     closesocket(socket);          PEGASUS_RETRY_SYSTEM_CALL(
               select(FD_SETSIZE, NULL, &fdwrite, &fdwrite, &timeoutValue),
               selectResult);
 #else #else
 #if (__GNUC__)          PEGASUS_RETRY_SYSTEM_CALL(
     TEMP_FAILURE_RETRY(::close(socket));              select(FD_SETSIZE, NULL, &fdwrite, NULL, &timeoutValue),
 #else              selectResult);
     ::close(socket);  
 #endif  
 #endif #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 Socket::close2(Sint32 socket)  
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS              int optval;
     return closesocket(socket);              SocketLength optlen = sizeof(int);
 #else              getsockopt(socket, SOL_SOCKET, SO_ERROR, (char*)&optval, &optlen);
 #if (__GNUC__)              if (optval == 0)
     int ccode = TEMP_FAILURE_RETRY(::close(socket));              {
     return ccode;                  PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
 #else                      "Connection with server established.");
     return ::close(socket);                  return true;
 #endif              }
 #endif              else
               {
                   PEG_TRACE((TRC_HTTP, Tracer::LEVEL1,
                       "Did not connect, getsockopt() returned optval = %d",
                       optval));
                   return false;
 } }
           }
           else
 void Socket::enableBlocking(Sint32 socket)  
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS              PEG_TRACE((TRC_HTTP, Tracer::LEVEL1,
     unsigned long flag = 0;                  "select() returned error code %d",
     ioctlsocket(socket, FIONBIO, &flag);                  getSocketError()));
 #else              return false;
     int flags = fcntl(socket, F_GETFL, 0);          }
     flags &= ~O_NONBLOCK;  
     fcntl(socket, F_SETFL, flags);  
 #endif  
 } }
  
 int Socket::enableBlocking2(Sint32 socket)      PEG_TRACE((TRC_HTTP, Tracer::LEVEL1,
 {          "connect() returned error code %d",
 #ifdef PEGASUS_OS_TYPE_WINDOWS          getSocketError()));
     unsigned long flag = 0;      return false;
     return ioctlsocket(socket, FIONBIO, &flag);  
 #else  
     int flags = fcntl(socket, F_GETFL, 0);  
     flags &= ~O_NONBLOCK;  
     return fcntl(socket, F_SETFL, flags);  
 #endif  
 } }
  
 void Socket::disableBlocking(Sint32 socket)  Sint32 Socket::read(SocketHandle socket, void* ptr, Uint32 size)
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
     unsigned long flag = 1;      return ::recv(socket, (char*)ptr, size, 0);
     ioctlsocket(socket, FIONBIO, &flag);  
 #else #else
     int flags = fcntl(socket, F_GETFL, 0);      int status;
     flags |= O_NONBLOCK;      PEGASUS_RETRY_SYSTEM_CALL(::read(socket, (char*)ptr, size), status);
     fcntl(socket, F_SETFL, flags);      return status;
 #endif #endif
 } }
  
 int Socket::disableBlocking2(Sint32 socket)  Sint32 Socket::write(SocketHandle socket, const void* ptr, Uint32 size)
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
     unsigned long flag = 1;      return ::send(socket, (const char*)ptr, size, 0);
     return ioctlsocket(socket, FIONBIO, &flag);  
 #else #else
     int flags = fcntl(socket, F_GETFL, 0);      int status;
     flags |= O_NONBLOCK;      PEGASUS_RETRY_SYSTEM_CALL(::write(socket, (char*)ptr, size), status);
     return fcntl(socket, F_SETFL, flags);      return status;
 #endif #endif
 } }
  
 void Socket::initializeInterface()  Sint32 Socket::timedWrite(
       SocketHandle socket,
       const void* ptr,
       Uint32 size,
       Uint32 socketWriteTimeout)
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS      Sint32 bytesWritten = 0;
     if (_socketInterfaceRefCount == 0)      Sint32 totalBytesWritten = 0;
     {      Boolean socketTimedOut = false;
         WSADATA tmp;      int selreturn = 0;
       while (1)
         if (WSAStartup(0x202, &tmp) == SOCKET_ERROR)  
             WSACleanup();  
     }  
   
     _socketInterfaceRefCount++;  
 #endif  
 }  
   
 void Socket::uninitializeInterface()  
 { {
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
     _socketInterfaceRefCount--;          PEGASUS_RETRY_SYSTEM_CALL(
               ::send(socket, (const char*)ptr, size, 0), bytesWritten);
     if (_socketInterfaceRefCount == 0)  
         WSACleanup();  
 #endif  
 }  
   
   
 class PEGASUS_COMMON_LINKAGE abstract_socket : public Sharable  
 {  
    public:  
       abstract_socket(void) { }  
       virtual ~abstract_socket(void){ }  
   
       virtual operator Sint32() const = 0;  
       virtual int socket(int sock_type, int sock_style, int sock_protocol, void *ssl_context = 0) = 0;  
   
       virtual Sint32 read(void* ptr, Uint32 size) = 0;  
       virtual Sint32 write(const void* ptr, Uint32 size) = 0;  
       virtual int close(void) = 0;  
       virtual int enableBlocking(void) = 0;  
       virtual int disableBlocking(void) = 0;  
   
       virtual int getsockname (struct sockaddr *addr, size_t *length_ptr) = 0;  
       virtual int bind (struct sockaddr *addr, size_t length) = 0;  
   
       // change size_t to size_t for ZOS and windows  
       virtual abstract_socket* accept(struct sockaddr *addr, size_t *length_ptr) = 0;  
       virtual int connect (struct sockaddr *addr, size_t length) = 0;  
       virtual int shutdown(int how) = 0;  
       virtual int listen(int q) = 0;  
       virtual int getpeername (struct sockaddr *addr, size_t *length_ptr) = 0;  
       virtual int send (void *buffer, size_t size, int flags) = 0;  
       virtual int recv (void *buffer, size_t size, int flags) = 0;  
       virtual int sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length) = 0;  
       virtual int recvfrom(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t *length_ptr) = 0;  
       virtual int setsockopt (int level, int optname, void *optval, size_t optlen) = 0;  
       virtual int getsockopt (int level, int optname, void *optval, size_t *optlen_ptr) = 0;  
   
       virtual Boolean incompleteReadOccurred(Sint32 retCode) = 0;  
       virtual Boolean is_secure(void) = 0;  
       virtual void set_close_on_exec(void) = 0;  
       virtual const char* get_err_string(void) = 0;  
   
    private:  
   
       abstract_socket(const abstract_socket& );  
       abstract_socket& operator=(const abstract_socket& );  
 };  
   
   
   
 /**  
  * null socket class -  
  * error handling rep for empty pegasus_sockets -  
  *  
  */  
 class empty_socket_rep : public abstract_socket  
 {  
    public:  
       empty_socket_rep(void){ }  
       ~empty_socket_rep(void){ }  
       operator Sint32() const { return -1 ;}  
   
       int socket(int sock_type, int sock_style,  
                  int sock_protocol, void *ssl_context = 0) { return -1 ;}  
   
       Sint32 read(void* ptr, Uint32 size) { return -1 ;}  
       Sint32 write(const void* ptr, Uint32 size){ return -1 ;}  
       int close(void){ return -1 ;}  
       int enableBlocking(void){ return -1 ;}  
       int disableBlocking(void){ return -1 ;}  
   
        int getsockname (struct sockaddr *addr, size_t *length_ptr){ return -1 ;}  
        int bind (struct sockaddr *addr, size_t length) { return -1;}  
   
       // change size_t to size_t for ZOS and windows  
        abstract_socket* accept(struct sockaddr *addr, size_t *length_ptr) { return 0;}  
        int connect (struct sockaddr *addr, size_t length) { return -1;}  
        int shutdown(int how) { return -1;}  
        int listen(int queue_len ) { return -1;}  
       int getpeername (struct sockaddr *addr, size_t *length_ptr) { return -1;}  
        int send (void *buffer, size_t size, int flags) { return -1;}  
        int recv (void *buffer, size_t size, int flags) { return -1;}  
        int sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length) { return -1;}  
        int recvfrom(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t *length_ptr) { return -1;}  
       int setsockopt (int level, int optname, void *optval, size_t optlen) { return -1;}  
       int getsockopt (int level, int optname, void *optval, size_t *optlen_ptr) { return -1;}  
   
        Boolean incompleteReadOccurred(Sint32 retCode) { return false;}  
        Boolean is_secure(void) { return false;}  
       void set_close_on_exec(void) { }  
       const char* get_err_string(void)  
       {  
          static const char* msg = "Unsupported.";  
          return msg;  
       }  
    private:  
       empty_socket_rep(int);  
 };  
   
   
 /**  
  * internet socket class  
  * designed to be overriden by ssl_socket_rep and file_socket_rep  
  *  
  */  
 class bsd_socket_rep : public abstract_socket  
 {  
    public:  
   
       /**  
        * map to pegasus_socket::sock_err  
        */  
   
       bsd_socket_rep(void);  
       virtual ~bsd_socket_rep(void);  
       // used to allow the accept method to work  
       bsd_socket_rep(int sock);  
   
       operator Sint32() const;  
       int socket(int sock_type, int sock_style, int sock_protocol, void *ssl_context = 0);  
   
       virtual Sint32 read(void* ptr, Uint32 size);  
       virtual Sint32 write(const void* ptr, Uint32 size);  
       virtual int close(void);  
       int enableBlocking(void);  
       int disableBlocking(void);  
   
       virtual int getsockname (struct sockaddr *addr, size_t *length_ptr);  
       virtual int bind (struct sockaddr *addr, size_t length);  
   
       // change size_t to size_t for ZOS and windows  
       virtual abstract_socket* accept(struct sockaddr *addr, size_t *length_ptr);  
       virtual int connect (struct sockaddr *addr, size_t length);  
       virtual int shutdown(int how);  
       virtual int listen(int queue_len );  
       int getpeername (struct sockaddr *addr, size_t *length_ptr);  
       virtual int send (void *buffer, size_t size, int flags);  
       virtual int recv (void *buffer, size_t size, int flags);  
       virtual int sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length);  
       virtual int recvfrom(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t *length_ptr);  
       int setsockopt (int level, int optname, void *optval, size_t optlen);  
       int getsockopt (int level, int optname, void *optval, size_t *optlen_ptr);  
   
       virtual Boolean incompleteReadOccurred(Sint32 retCode);  
       virtual Boolean is_secure(void);  
       void set_close_on_exec(void);  
       virtual const char* get_err_string(void);  
   
    private:  
   
   
       bsd_socket_rep& operator=(const bsd_socket_rep& );  
       // use to perform one-time initializion and destruction  
       struct _library_init  
       {  
             _library_init(void)  
             {  
             }  
             ~_library_init(void)  
             {  
             }  
       };  
   
       static struct _library_init _lib_init;  
   
       int _socket;  
       void *_ssl_context;  
       int _errno;  
       char _strerr[256];  
 };  
   
   
   
   
 #if defined(__GNUC__) && GCC_VERSION >= 30200  
 // TEMP_FAILURE_RETRY (expression)  
 #else #else
           PEGASUS_RETRY_SYSTEM_CALL(
               ::write(socket, (char*)ptr, size), bytesWritten);
 #endif #endif
           // Some data written this cycle ?
           // Add it to the total amount of written data.
 /**          if (bytesWritten > 0)
  * default constructor for an (uninitialized) bsd socket  
  */  
 bsd_socket_rep::bsd_socket_rep(void)  
    :_errno(0)  
 {  
 }  
   
 bsd_socket_rep::bsd_socket_rep(int sock)  
    : _socket(sock)  
 { {
               totalBytesWritten += bytesWritten;
               socketTimedOut = false;
 } }
  
           // All data written ? return amount of data written
 /**          if ((Uint32)bytesWritten == size)
  * default destructor for bsd_socket_rep  
  *  
  */  
 bsd_socket_rep::~bsd_socket_rep(void)  
 { {
               return totalBytesWritten;
 } }
           // If data has been written partially, we resume writing data
 int bsd_socket_rep::shutdown(int how)          // this also accounts for the case of a signal interrupt
           // (i.e. errno = EINTR)
           if (bytesWritten > 0)
 { {
    int ccode = ::shutdown(_socket, how);              size -= bytesWritten;
    if(ccode == -1)              ptr = (void *)((char *)ptr + bytesWritten);
       _errno = errno;              continue;
    return ccode;  
 } }
           // Something went wrong
 bsd_socket_rep::operator Sint32() const          if (bytesWritten == PEGASUS_SOCKET_ERROR)
 { {
    return (Sint32)_socket;              // if we already waited for the socket to get ready, bail out
 }              if (socketTimedOut) return bytesWritten;
   #ifdef PEGASUS_OS_TYPE_WINDOWS
 int bsd_socket_rep::socket(int sock_type, int sock_style, int sock_protocol, void *ssl_context)              if (WSAGetLastError() == WSAEWOULDBLOCK)
 {  #else
    _socket = ::socket(sock_type, sock_style, sock_protocol);              if (errno == EAGAIN || errno == EWOULDBLOCK)
    if(-1 == _socket )  #endif
    {  
       _errno = errno;  
    }  
    return _socket;  
 }  
   
   
 Sint32 bsd_socket_rep::read(void* ptr, Uint32 size)  
 {  
    int ccode = Socket::read(_socket, ptr, size);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
 Sint32 bsd_socket_rep::write(const void* ptr, Uint32 size)  
 {  
    int ccode = Socket::write(_socket, ptr, size);  
    if(ccode == -1)  
       errno = _errno;  
    return ccode;  
 }  
   
   
 int bsd_socket_rep::close(void)  
 {  
    int ccode;  
   
    shutdown(2);  
    ccode = Socket::close2(_socket);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
   
 int  bsd_socket_rep::enableBlocking(void)  
 {  
    return Socket::enableBlocking2(_socket);  
 }  
   
 int bsd_socket_rep::disableBlocking(void)  
 {  
    return Socket::disableBlocking2(_socket);  
 }  
   
 int bsd_socket_rep::getsockname (struct sockaddr *addr, size_t *length_ptr)  
 {  
    int ccode = ::getsockname(_socket, addr, length_ptr);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
 /**  
  * default implementation allows reuseof address  
  * sockaddr structure needs to be fully initialized or call will fail  
  */  
 int bsd_socket_rep::bind (struct sockaddr *addr, size_t length)  
 {  
    int opt = 1;  
    int ccode = setsockopt(SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));  
    if(ccode < 0)  
    {  
       _errno = errno;  
       return ccode;  
    }  
    return ::bind(_socket, addr, length);  
 }  
   
 abstract_socket* bsd_socket_rep::accept(struct sockaddr *addr, size_t *length_ptr)  
 {  
    int new_sock = ::accept(_socket, addr, length_ptr);  
    if(new_sock == -1)  
    {  
       _errno = errno;  
       return 0;  
    }  
   
    bsd_socket_rep *rep = new bsd_socket_rep(new_sock);  
    // set the close-on-exec flag  
    rep->set_close_on_exec();  
    return rep;  
 }  
   
 int bsd_socket_rep::connect (struct sockaddr *addr, size_t length)  
 {  
    int ccode = ::connect(_socket, addr, length);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
 int bsd_socket_rep::listen(int queue_len)  
 {  
    int ccode = ::listen(_socket, queue_len);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
 int bsd_socket_rep::getpeername (struct sockaddr *addr, size_t *length_ptr)  
 {  
    int ccode = ::getpeername(_socket, addr, length_ptr);  
    if(ccode == -1 )  
       _errno = errno;  
    return ccode;  
 }  
   
 int bsd_socket_rep::send (void *buffer, size_t size, int flags)  
 {  
    int ccode = ::send(_socket, buffer, size, flags);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
 int bsd_socket_rep::recv (void *buffer, size_t size, int flags)  
 {  
    int ccode = ::recv(_socket, buffer, size, flags);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
 int bsd_socket_rep::sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length)  
 {  
    int ccode = ::sendto(_socket, buffer, size, flags, addr, length);  
       if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
 int bsd_socket_rep::recvfrom(void *buffer,  
                              size_t size,  
                              int flags,  
                              struct sockaddr *addr,  
                              size_t *length_ptr)  
 {  
    int ccode = ::recvfrom(_socket, buffer, size, flags, addr, length_ptr);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
 int bsd_socket_rep::setsockopt (int level, int optname, void *optval, size_t optlen)  
 {  
    int ccode = ::setsockopt(_socket, level, optname, optval, optlen);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
 int bsd_socket_rep::getsockopt (int level, int optname, void *optval, size_t *optlen_ptr)  
 {  
    int ccode = ::getsockopt(_socket, level, optname, optval, optlen_ptr);  
    if(ccode == -1)  
       _errno = errno;  
    return ccode;  
 }  
   
   
 Boolean bsd_socket_rep::incompleteReadOccurred(Sint32 retCode)  
 {  
    return false;  
 }  
   
 Boolean bsd_socket_rep::is_secure(void)  
 { {
    return false;                  fd_set fdwrite;
                    // max. timeout seconds waiting for the socket to get ready
                   struct timeval tv = { socketWriteTimeout, 0 };
                   FD_ZERO(&fdwrite);
                   FD_SET(socket, &fdwrite);
                   selreturn = select(FD_SETSIZE, NULL, &fdwrite, NULL, &tv);
                   if (selreturn == 0) socketTimedOut = true; // ran out of time
                   continue;
 } }
               return bytesWritten;
 void bsd_socket_rep::set_close_on_exec(void)  
 {  
    int sock_flags;  
    if( (sock_flags = fcntl(_socket, F_GETFD, 0)) >= 0)  
    {  
       sock_flags |= FD_CLOEXEC;  
       fcntl(_socket, F_SETFD, sock_flags);  
    }    }
 } }
   
   
 const char* bsd_socket_rep::get_err_string(void)  
 {  
    strncpy(_strerr, strerror(_errno), 255);  
    return _strerr;  
 } }
  
   void Socket::close(SocketHandle& socket)
 bsd_socket_factory::bsd_socket_factory(void)  
 { {
 }      if (socket != PEGASUS_INVALID_SOCKET)
   
 bsd_socket_factory::~bsd_socket_factory(void)  
 { {
 }  #ifdef PEGASUS_OS_TYPE_WINDOWS
           if (!closesocket(socket))
 abstract_socket* bsd_socket_factory::make_socket(void)  
 {  
    return new bsd_socket_rep();  
 }  
   
   
   
   
 /**  
  * pegasus_socket - the high level socket object in pegasus  
  *  
  **/  
   
 pegasus_socket::pegasus_socket(void)  
 { {
    _rep = new empty_socket_rep();              socket = PEGASUS_INVALID_SOCKET;
 } }
   #else
           int status;
           PEGASUS_RETRY_SYSTEM_CALL(::close(socket), status);
  
           if (status == 0)
 pegasus_socket::pegasus_socket(socket_factory *factory)  
 { {
    _rep = factory->make_socket();              socket = PEGASUS_INVALID_SOCKET;
 } }
   #endif
 pegasus_socket::pegasus_socket(const pegasus_socket& s)  
 {  
    if(this != &s)  
    {  
       Inc(this->_rep = s._rep);  
    }    }
 };  
   
 pegasus_socket::pegasus_socket(abstract_socket* s)  
 {  
    Inc(this->_rep = s);  
 } }
  
   void Socket::disableBlocking(SocketHandle socket)
 pegasus_socket::~pegasus_socket(void)  
 { {
    Dec(_rep);  #ifdef PEGASUS_OS_TYPE_WINDOWS
       unsigned long flag = 1;    // Use "flag = 0" to enable blocking
       ioctlsocket(socket, FIONBIO, &flag);
   #elif PEGASUS_OS_VMS
       int flag=1;                // Use "flag = 0" to enable blocking
       ioctl(socket, FIONBIO, &flag);
   #else
       int flags = fcntl(socket, F_GETFL, 0);
       flags |= O_NONBLOCK;    // Use "flags &= ~O_NONBLOCK" to enable blocking
       fcntl(socket, F_SETFL, flags);
   #endif
 } }
  
 pegasus_socket& pegasus_socket::operator =(const pegasus_socket& s)  void Socket::initializeInterface()
 { {
    if(this != &s)  #ifdef PEGASUS_OS_TYPE_WINDOWS
       if (_socketInterfaceRefCount == 0)
    {    {
       Dec(_rep);          WSADATA tmp;
       Inc(this->_rep = s._rep);  
    }  
    return *this;  
 }  
  
 pegasus_socket::operator Sint32() const          int err = WSAStartup(0x202, &tmp);
           if (err != 0)
 { {
    return _rep->operator Sint32();              throw Exception(MessageLoaderParms(
                   "Common.Socket.WSASTARTUP_FAILED.WINDOWS",
                   "WSAStartup failed with error $0.",
                   err));
 } }
   
 int pegasus_socket::socket(int type, int style, int protocol, void *ssl_context)  
 {  
    return _rep->socket(type, style, protocol, ssl_context);  
 } }
  
       _socketInterfaceRefCount++;
 Sint32 pegasus_socket::read(void* ptr, Uint32 size)  #endif
 {  
    return _rep->read(ptr, size);  
 }  
   
 Sint32 pegasus_socket::write(const void* ptr, Uint32 size)  
 {  
    return _rep->write(ptr, size);  
 } }
  
 int pegasus_socket::close(void)  void Socket::uninitializeInterface()
 { {
    return _rep->close();  #ifdef PEGASUS_OS_TYPE_WINDOWS
 }      _socketInterfaceRefCount--;
  
 int pegasus_socket::enableBlocking(void)      if (_socketInterfaceRefCount == 0)
 {          WSACleanup();
    return _rep->enableBlocking();  #endif
 } }
  
 int pegasus_socket::disableBlocking(void)  //------------------------------------------------------------------------------
 {  //
    return _rep->disableBlocking();  // _setTCPNoDelay()
 }  //
   //------------------------------------------------------------------------------
  
 int pegasus_socket::getsockname (struct sockaddr *addr, size_t *length_ptr)  inline void _setTCPNoDelay(SocketHandle socket)
 { {
    return _rep->getsockname(addr, length_ptr);      // This function disables "Nagle's Algorithm" also known as "the TCP delay
 }      // algorithm", which causes read operations to obtain whatever data is
       // already in the input queue and then wait a little longer to see if
       // more data arrives. This algorithm optimizes the case in which data is
       // sent in only one direction but severely impairs performance of round
       // trip servers. Disabling TCP delay is a standard technique for round
       // trip servers.
  
 int pegasus_socket::bind (struct sockaddr *addr, size_t length)     int opt = 1;
 {     setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
    return _rep->bind(addr, length);  
 } }
   //------------------------------------------------------------------------------
 // change socklen_t to size_t for ZOS and windows  //
 pegasus_socket pegasus_socket::accept(struct sockaddr *addr, size_t *length_ptr)  // _setInformIfNewTCPIP()
   //
   //------------------------------------------------------------------------------
   inline void _setInformIfNewTCPIP(SocketHandle socket)
 { {
    return pegasus_socket(_rep->accept(addr, length_ptr));  #ifdef PEGASUS_OS_ZOS
 }     // 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
      // restart of the transport layer. When this option is in effect,
      // the accetp(), select(), and read() request will receive an errno=EIO.
      // Once this happens, the socket should be closed and create a new.
  
 int pegasus_socket::connect (struct sockaddr *addr, size_t length)     int NewTcpipOn = 1;
 {     setibmsockopt(
    return _rep->connect(addr, length);         socket,
          SOL_SOCKET,
          SO_EioIfNewTP,
          (char*)&NewTcpipOn,
          sizeof(NewTcpipOn));
   #endif
 } }
  
 int pegasus_socket::shutdown(int how)  
 {  
    return _rep->shutdown(how);  
 }  
  
 int pegasus_socket::listen(int q)  SocketHandle Socket::createSocket(int domain, int type, int protocol)
 { {
    return _rep->listen(q);      SocketHandle newSocket;
 }  
  
 int pegasus_socket::getpeername (struct sockaddr *addr, size_t *length_ptr)      if (domain == AF_UNIX)
 { {
    return _rep->getpeername(addr, length_ptr);          return socket(domain,type,protocol);
 } }
  
 int pegasus_socket::send(void *buffer, size_t size, int flags)      bool sendTcpipMsg = true;
 {  
    return _rep->send(buffer, size, flags);  
 }  
  
 int pegasus_socket::recv(void *buffer, size_t size, int flags)      while (1)
 { {
    return _rep->recv(buffer, size, flags);          newSocket = socket(domain,type,protocol);
 }  
  
 int pegasus_socket::sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length)          if ((newSocket != PEGASUS_INVALID_SOCKET) ||
               (getSocketError() != PEGASUS_NETWORK_TRYAGAIN))
 { {
    return _rep->sendto(buffer, size, flags, addr, length);              break;
 } }
  
 int pegasus_socket::recvfrom(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t *length_ptr)  #ifdef PEGASUS_OS_ZOS
 {          // The program should wait for transport layer to become ready.
    return _rep->recvfrom(buffer, size, flags, addr, length_ptr);  
 }  
  
 int pegasus_socket::setsockopt (int level, int optname, void *optval, size_t optlen)          if (sendTcpipMsg)
 { {
    return _rep->setsockopt(level, optname, optval, optlen);              Logger::put_l(
                   Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
                   "Common.Socket.WAIT_FOR_TCPIP",
                   "TCP/IP temporary unavailable.");
               sendTcpipMsg = false;
 } }
  
 int pegasus_socket::getsockopt (int level, int optname, void *optval, size_t *optlen_ptr)          System::sleep(30);
 {  #endif
    return _rep->getsockopt(level, optname, optval, optlen_ptr);      } // wait for the transport layer become ready.
 }  
  
 Boolean pegasus_socket::incompleteReadOccurred(Sint32 retCode)      // Is the socket in an unrecoverable error ?
       if (newSocket == PEGASUS_INVALID_SOCKET)
 { {
    return _rep->incompleteReadOccurred(retCode);          // return immediate
           return PEGASUS_INVALID_SOCKET;
 } }
       else
 Boolean pegasus_socket::is_secure(void)  
 { {
    return _rep->is_secure();          // set aditional socket options
 }          _setTCPNoDelay(newSocket);
           _setInformIfNewTCPIP(newSocket);
  
 void pegasus_socket::set_close_on_exec(void)          return newSocket;
 {  
    return _rep->set_close_on_exec();  
 } }
   
   
 const char* pegasus_socket::get_err_string(void)  
 {  
    return _rep->get_err_string();  
 } }
  
   
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END
   


Legend:
Removed from v.1.9.4.7  
changed lines
  Added in v.1.32.4.1

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2