diff options
Diffstat (limited to 'cpp/src/Ice/Network.cpp')
-rw-r--r-- | cpp/src/Ice/Network.cpp | 104 |
1 files changed, 94 insertions, 10 deletions
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 0f62100639d..3514147aab1 100644 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -20,6 +20,14 @@ using namespace std; using namespace Ice; using namespace IceInternal; +#ifdef __sun +# define INADDR_NONE -1 +#endif + +#ifdef _WIN32 +# define HAVE_NO_GETHOSTBYNAME_R +#endif + bool IceInternal::interrupted() { @@ -179,16 +187,38 @@ IceInternal::closeSocket(SOCKET fd) { #ifdef _WIN32 int error = WSAGetLastError(); - closesocket(fd); + if(closesocket(fd) == SOCKET_ERROR) + { + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } WSASetLastError(error); #else int error = errno; + if(close(fd) == SOCKET_ERROR) + { + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } close(fd); errno = error; #endif } void +IceInternal::shutdownSocket(SOCKET fd) +{ + if(shutdown(fd, SHUT_WR) == SOCKET_ERROR) + { + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } +} + +void IceInternal::setBlock(SOCKET fd, bool block) { if(block) @@ -546,7 +576,9 @@ repeatAccept: return ret; } +#ifdef HAVE_NO_GETHOSTBYNAME_R static IceUtil::Mutex getHostByNameMutex; +#endif void IceInternal::getAddress(const string& host, int port, struct sockaddr_in& addr) @@ -556,20 +588,18 @@ IceInternal::getAddress(const string& host, int port, struct sockaddr_in& addr) addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(host.c_str()); -#ifdef __sun -#define INADDR_NONE -1 -#endif - if(addr.sin_addr.s_addr == INADDR_NONE) { - IceUtil::Mutex::Lock sync(getHostByNameMutex); - struct hostent* entry; int retry = 5; +#ifdef HAVE_NO_GETHOSTBYNAME_R + + IceUtil::Mutex::Lock sync(getHostByNameMutex); + do { - entry = gethostbyname(host.c_str()); + entry = gethostbyname(host); } #ifdef _WIN32 while(!entry && WSAGetLastError() == WSATRY_AGAIN && --retry >= 0); @@ -589,6 +619,32 @@ IceInternal::getAddress(const string& host, int port, struct sockaddr_in& addr) throw ex; } +#else + + struct hostent entryBuf; + vector<char> buf(1024); + int res; + int herr = 0; + + do + { + while((res = gethostbyname_r(host.c_str(), &entryBuf, &buf[0], buf.size(), &entry, &herr)) == ERANGE) + { + buf.resize(buf.size() * 2); + } + } + while(res && herr == TRY_AGAIN && --retry >= 0); + + if(res) + { + DNSException ex(__FILE__, __LINE__); + ex.error = herr; + ex.host = host; + throw ex; + } + +#endif + memcpy(&addr.sin_addr, entry->h_addr, entry->h_length); } } @@ -605,11 +661,13 @@ IceInternal::getLocalHost(bool numeric) } { - IceUtil::Mutex::Lock sync(getHostByNameMutex); - struct hostent* entry; int retry = 5; +#ifdef HAVE_NO_GETHOSTBYNAME_R + + IceUtil::Mutex::Lock sync(getHostByNameMutex); + do { entry = gethostbyname(host); @@ -632,6 +690,32 @@ IceInternal::getLocalHost(bool numeric) throw ex; } +#else + + struct hostent entryBuf; + vector<char> buf(1024); + int res; + int herr = 0; + + do + { + while((res = gethostbyname_r(host, &entryBuf, &buf[0], buf.size(), &entry, &herr)) == ERANGE) + { + buf.resize(buf.size() * 2); + } + } + while(res && herr == TRY_AGAIN && --retry >= 0); + + if(res) + { + DNSException ex(__FILE__, __LINE__); + ex.error = herr; + ex.host = host; + throw ex; + } + +#endif + if(numeric) { struct sockaddr_in addr; |