THRIFT-2156: fix errno handling in server socket
Client: C++
Patch: Jim King <jim.king@simplivity.com>

This closes #1033
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp
index dad0882..b3d8898 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp
@@ -284,7 +284,7 @@
   hints.ai_family = PF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
-  sprintf(port, "%d", port_);
+  snprintf(port, sizeof("65535"), "%d", port_);
 
   // If address is not specified use wildcard address (NULL)
   TGetAddrInfoWrapper info(address_.empty() ? NULL : &address_[0], port, &hints);
@@ -445,6 +445,7 @@
   // we may want to try to bind more than once, since THRIFT_NO_SOCKET_CACHING doesn't
   // always seem to work. The client can configure the retry variables.
   int retries = 0;
+  int errno_copy = 0;
 
   if (!path_.empty()) {
 
@@ -453,7 +454,7 @@
     // Unix Domain Socket
     size_t len = path_.size() + 1;
     if (len > sizeof(((sockaddr_un*)NULL)->sun_path)) {
-      int errno_copy = THRIFT_GET_SOCKET_ERROR;
+      errno_copy = THRIFT_GET_SOCKET_ERROR;
       GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy);
       throw TTransportException(TTransportException::NOT_OPEN,
                                 "Unix Domain socket path too long",
@@ -481,6 +482,7 @@
       if (0 == ::bind(serverSocket_, (struct sockaddr*)&address, structlen)) {
         break;
       }
+      errno_copy = THRIFT_GET_SOCKET_ERROR;
       // use short circuit evaluation here to only sleep if we need to
     } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
 #else
@@ -493,6 +495,7 @@
       if (0 == ::bind(serverSocket_, res->ai_addr, static_cast<int>(res->ai_addrlen))) {
         break;
       }
+      errno_copy = THRIFT_GET_SOCKET_ERROR;
       // use short circuit evaluation here to only sleep if we need to
     } while ((retries++ < retryLimit_) && (THRIFT_SLEEP_SEC(retryDelay_) == 0));
 
@@ -502,7 +505,7 @@
       socklen_t len = sizeof(sa);
       std::memset(&sa, 0, len);
       if (::getsockname(serverSocket_, reinterpret_cast<struct sockaddr*>(&sa), &len) < 0) {
-        int errno_copy = errno;
+        errno_copy = THRIFT_GET_SOCKET_ERROR;
         GlobalOutput.perror("TServerSocket::getPort() getsockname() ", errno_copy);
       } else {
         if (sa.ss_family == AF_INET6) {
@@ -520,15 +523,15 @@
   if (retries > retryLimit_) {
     char errbuf[1024];
     if (!path_.empty()) {
-      sprintf(errbuf, "TServerSocket::listen() PATH %s", path_.c_str());
+      snprintf(errbuf, 1024, "TServerSocket::listen() PATH %s", path_.c_str());
     } else {
-      sprintf(errbuf, "TServerSocket::listen() BIND %d", port_);
+      snprintf(errbuf, 1024, "TServerSocket::listen() BIND %d", port_);
     }
     GlobalOutput(errbuf);
     close();
     throw TTransportException(TTransportException::NOT_OPEN,
                               "Could not bind",
-                              THRIFT_GET_SOCKET_ERROR);
+                              errno_copy);
   }
 
   if (listenCallback_)
@@ -536,7 +539,7 @@
 
   // Call listen
   if (-1 == ::listen(serverSocket_, acceptBacklog_)) {
-    int errno_copy = THRIFT_GET_SOCKET_ERROR;
+    errno_copy = THRIFT_GET_SOCKET_ERROR;
     GlobalOutput.perror("TServerSocket::listen() listen() ", errno_copy);
     close();
     throw TTransportException(TTransportException::NOT_OPEN, "Could not listen", errno_copy);