--- VTK/Common/vtkSocket.h	2011-04-14 10:50:32.655498357 -0700
+++ VTK/Common/vtkSocket.h	2011-04-14 10:51:53.335704415 -0700
@@ -36,7 +36,7 @@
 
   // Description:
   // Close the socket.
-  void CloseSocket() {this->CloseSocket(this->SocketDescriptor);}
+  void CloseSocket();
 
   // ------ Communication API ---
   // Description:
--- VTK/Common/vtkSocket.cxx	2011-02-27 13:47:42.787573794 -0800
+++ VTK/Common/vtkSocket.cxx	2011-02-27 14:00:30.506483646 -0800
@@ -16,6 +16,13 @@
 
 #include "vtkObjectFactory.h"
 
+#include <algorithm>
+using std::max;
+
+#if defined(__BORLANDC__)
+# pragma warn -8012 /* signed/unsigned comparison */
+#endif
+
 // The VTK_SOCKET_FAKE_API definition is given to the compiler
 // command line by CMakeLists.txt if there is no real sockets
 // interface available.  When this macro is defined we simply make
@@ -38,25 +45,99 @@
   #include <unistd.h>
   #include <sys/time.h>
   #include <errno.h>
+  #include <string.h>
+  #include <stdio.h>
 #endif
 #endif
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
+
+// TODO : document why we restrict to v1.1
 #define WSA_VERSION MAKEWORD(1,1)
-#define vtkCloseSocketMacro(sock) (closesocket(sock))
-#else
-#define vtkCloseSocketMacro(sock) (close(sock))
-#endif
 
-#if defined(__BORLANDC__)
-# pragma warn -8012 /* signed/unsigned comparison */
+#define vtkCloseSocketMacro(sock)      (closesocket(sock))
+#define vtkErrnoMacro                  (WSAGetLastError())
+#define vtkStrerrorMacro(_num)         (wsaStrerror(_num))
+#define vtkSocketErrorIdMacro(_id)     (WSA##_id)
+#define vtkSocketErrorReturnMacro      (SOCKET_ERROR)
+
+#else
+
+#define vtkCloseSocketMacro(sock)      (close(sock))
+#define vtkErrnoMacro                  (errno)
+#define vtkStrerrorMacro(_num)         (strerror(_num))
+#define vtkSocketErrorIdMacro(_id)     (_id)
+#define vtkSocketErrorReturnMacro      (-1)
+
+#endif
+
+// This macro wraps a system function call(_call),
+// restarting the call in case it was interrupted
+// by a signal (EINTR).
+#define vtkRestartInterruptedSystemCallMacro(_call,_ret)\
+  do                                                    \
+    {                                                   \
+    (_ret)=(_call);                                     \
+    }                                                   \
+  while (((_ret)==vtkSocketErrorReturnMacro)            \
+    && (vtkErrnoMacro==vtkSocketErrorIdMacro(EINTR)));
+
+// use when _str may be a null pointer but _fallback is not.
+#define vtkSafeStrMacro(_str,_fallback) ((_str)?(_str):(_fallback))
+
+// convert error number to string and report via vtkErrorMacro.
+#define vtkSocketErrorMacro(_eno, _message)             \
+  vtkErrorMacro(                                        \
+    << (_message)                                       \
+    << " "                                              \
+    << vtkSafeStrMacro(                                 \
+         vtkStrerrorMacro(_eno),                        \
+         "unknown error")                               \
+    << ".");
+
+// this pointer is not accessable in a static member function
+#define vtkGenericErrorMacro(x)                         \
+{ if (vtkObject::GetGlobalWarningDisplay()) {           \
+      vtkOStreamWrapper::EndlType endl;                 \
+      vtkOStreamWrapper::UseEndl(endl);                 \
+      vtkOStrStreamWrapper vtkmsg;                      \
+      vtkmsg                                            \
+        << "Error: In " __FILE__ ", line "              \
+        << __LINE__ << "\n" x                           \
+        << "\n\n";                                      \
+      vtkOutputWindowDisplayErrorText(vtkmsg.str());    \
+      vtkmsg.rdbuf()->freeze(0);}}
+
+// convert error number to string and report via vtkGenericErrorMacro
+#define vtkSocketGenericErrorMacro(_message)            \
+  vtkGenericErrorMacro(                                 \
+    << (_message)                                       \
+    << " "                                              \
+    << vtkSafeStrMacro(                                 \
+         vtkStrerrorMacro(vtkErrnoMacro),               \
+         "unknown error")                               \
+    << ".");
+
+// on windows sterror doesn't handle socket error codes
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static
+const char *wsaStrerror(int wsaeid)
+{
+  static char buf[256]={'\0'};
+  int ok;
+  ok=FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,wsaeid,0,buf,256,0);
+  if (!ok)
+    {
+    return 0;
+    }
+  return buf;
+}
 #endif
 
 //-----------------------------------------------------------------------------
 vtkSocket::vtkSocket()
 {
   this->SocketDescriptor = -1;
-  
 }
 
 //-----------------------------------------------------------------------------
@@ -73,13 +154,26 @@
 int vtkSocket::CreateSocket()
 {
 #ifndef VTK_SOCKET_FAKE_API
-  int sock = socket(AF_INET, SOCK_STREAM, 0);
+  int sock;
+  vtkRestartInterruptedSystemCallMacro(socket(AF_INET,SOCK_STREAM, 0), sock);
+  if (sock == vtkSocketErrorReturnMacro)
+    {
+    vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to socket.");
+    return -1;
+    }
+
   // Elimate windows 0.2 second delay sending (buffering) data.
   int on = 1;
-  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on)))
+  int iErr;
+  vtkRestartInterruptedSystemCallMacro(
+    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on)),
+    iErr);
+  if (iErr == vtkSocketErrorReturnMacro)
     {
+    vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to setsockopt.");
     return -1;
     }
+
   return sock;
 #else
   return -1;
@@ -87,6 +181,13 @@
 }
 
 //-----------------------------------------------------------------------------
+void vtkSocket::CloseSocket()
+{
+  this->CloseSocket(this->SocketDescriptor);
+  this->SocketDescriptor = -1;
+}
+
+//-----------------------------------------------------------------------------
 int vtkSocket::BindSocket(int socketdescriptor, int port)
 {
 #ifndef VTK_SOCKET_FAKE_API
@@ -97,16 +198,31 @@
   server.sin_port = htons(port);
   // Allow the socket to be bound to an address that is already in use
   int opt=1;
+  int iErr=~vtkSocketErrorReturnMacro;
 #ifdef _WIN32
-  setsockopt(socketdescriptor, SOL_SOCKET, SO_REUSEADDR, (char*) &opt, sizeof(int));
+  vtkRestartInterruptedSystemCallMacro(
+    setsockopt(socketdescriptor,SOL_SOCKET,SO_REUSEADDR,(char*)&opt,sizeof(int)),
+    iErr);
 #elif defined(VTK_HAVE_SO_REUSEADDR)
-  setsockopt(socketdescriptor, SOL_SOCKET, SO_REUSEADDR, (void *) &opt, sizeof(int));
+  vtkRestartInterruptedSystemCallMacro(
+    setsockopt(socketdescriptor,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(int)),
+    iErr);
 #endif
+  if (iErr == vtkSocketErrorReturnMacro)
+    {
+    vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to setsockopt.");
+    return -1;
+    }
 
-  if ( bind(socketdescriptor, reinterpret_cast<sockaddr*>(&server), sizeof(server)) )
+  vtkRestartInterruptedSystemCallMacro(
+    bind(socketdescriptor,reinterpret_cast<sockaddr*>(&server),sizeof(server)),
+    iErr);
+  if (iErr == vtkSocketErrorReturnMacro)
     {
+    vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to bind.");
     return -1;
     }
+
   return 0;
 #else
   static_cast<void>(socketdescriptor);
@@ -121,9 +237,20 @@
 #ifndef VTK_SOCKET_FAKE_API
   if (socketdescriptor < 0)
     {
+    vtkErrorMacro("Invalid descriptor.");
     return -1;
     }
-  return accept(socketdescriptor, 0, 0);
+
+  int newDescriptor;
+  vtkRestartInterruptedSystemCallMacro(
+    accept(socketdescriptor, 0, 0), newDescriptor);
+  if (newDescriptor == vtkSocketErrorReturnMacro)
+    {
+    vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to accept.");
+    return -1;
+    }
+
+  return newDescriptor;
 #else
   static_cast<void>(socketdescriptor);
   return -1;
@@ -136,9 +263,19 @@
 #ifndef VTK_SOCKET_FAKE_API
   if (socketdescriptor < 0)
     {
+    vtkErrorMacro("Invalid descriptor.");
+    return -1;
+    }
+
+  int iErr;
+  vtkRestartInterruptedSystemCallMacro(listen(socketdescriptor, 1), iErr);
+  if (iErr == vtkSocketErrorReturnMacro)
+    {
+    vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to listen.");
     return -1;
     }
-  return listen(socketdescriptor, 1);
+
+  return 0;
 #else
   static_cast<void>(socketdescriptor);
   return -1;
@@ -151,32 +288,54 @@
 #ifndef VTK_SOCKET_FAKE_API
   if (socketdescriptor < 0 )
     {
-    // invalid socket descriptor.
+    vtkErrorMacro("Invalid descriptor.");
     return -1;
     }
-  
+
   fd_set rset;
-  struct timeval tval;
-  struct timeval* tvalptr = 0;
-  if ( msec > 0 )
+  int res;
+  do
     {
-    tval.tv_sec = msec / 1000;
-    tval.tv_usec = (msec % 1000)*1000;
-    tvalptr = &tval;
+    struct timeval tval;
+    struct timeval* tvalptr = 0;
+    if (msec>0)
+      {
+      tval.tv_sec = msec / 1000;
+      tval.tv_usec = (msec % 1000)*1000;
+      tvalptr = &tval;
+      }
+
+    FD_ZERO(&rset);
+    FD_SET(socketdescriptor, &rset);
+
+    // block until socket is readable.
+    res = select(socketdescriptor+1, &rset, 0, 0, tvalptr);
     }
-  FD_ZERO(&rset);
-  FD_SET(socketdescriptor, &rset);
-  int res = select(socketdescriptor + 1, &rset, 0, 0, tvalptr);
-  if(res == 0)
+  while ((res == vtkSocketErrorReturnMacro)
+    && (vtkErrnoMacro == vtkSocketErrorIdMacro(EINTR)));
+
+  if (res == 0)
     {
-    return 0;//for time limit expire
+    // time out
+    return 0;
     }
-
-  if ( res < 0 || !(FD_ISSET(socketdescriptor, &rset)) )
+  else
+  if (res == vtkSocketErrorReturnMacro)
     {
-    // Some error.
+    // error in the call
+    vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to select.");
     return -1;
     }
+  else
+  if (!FD_ISSET(socketdescriptor, &rset))
+     {
+     vtkErrorMacro("Socket error in select. Descriptor not selected.");
+     return -1;
+     }
+
+  // NOTE: not checking for pending errors,these will be handled
+  // in the next call to read/recv
+
   // The indicated socket has some activity on it.
   return 1;
 #else
@@ -191,50 +350,70 @@
     unsigned long msec, int* selected_index)
 {
 #ifndef VTK_SOCKET_FAKE_API
-  int i;
-  int max_fd = -1;
+
   *selected_index = -1;
-  if (size <  0)
+
+  if (size < 0)
     {
+    vtkGenericErrorMacro("Can't select fewer than 0.");
     return -1;
     }
-  
+
   fd_set rset;
-  struct timeval tval;
-  struct timeval* tvalptr = 0;
-  if ( msec > 0 )
-    {
-    tval.tv_sec = msec / 1000;
-    tval.tv_usec = msec % 1000;
-    tvalptr = &tval;
-    }
-  FD_ZERO(&rset);
-  for (i=0; i<size; i++)
+  int res = -1;
+  do
     {
-    FD_SET(sockets_to_select[i],&rset);
-    max_fd = (sockets_to_select[i] > max_fd)? sockets_to_select[i] : max_fd;
+    struct timeval tval;
+    struct timeval* tvalptr = 0;
+    if (msec>0)
+      {
+      tval.tv_sec = msec / 1000;
+      tval.tv_usec = msec % 1000;
+      tvalptr = &tval;
+      }
+
+    FD_ZERO(&rset);
+    int max_fd = -1;
+    for (int i=0; i<size; i++)
+      {
+      FD_SET(sockets_to_select[i],&rset);
+      max_fd = max(sockets_to_select[i],max_fd);
+      }
+
+    // block until one socket is ready to read.
+    res = select(max_fd + 1, &rset, 0, 0, tvalptr);
     }
-  
-  int res = select(max_fd + 1, &rset, 0, 0, tvalptr);
-  if (res == 0)
+  while ((res == vtkSocketErrorReturnMacro)
+    && (vtkErrnoMacro == vtkSocketErrorIdMacro(EINTR)));
+
+  if (res==0)
     {
-    return 0; //Timeout
+    // time out
+    return 0;
     }
-  if (res < 0)
+  else
+  if (res == vtkSocketErrorReturnMacro)
     {
-    // SelectSocket error.
+    // error in the call
+    vtkSocketGenericErrorMacro("Socket error in call to select.");
     return -1;
     }
-  
-  //check which socket has some activity.
-  for (i=0; i<size; i++)
+
+  // find the first socket which has some activity.
+  for (int i=0; i<size; i++)
     {
     if ( FD_ISSET(sockets_to_select[i],&rset) )
       {
+      // NOTE: not checking for pending errors, these
+      // will be handled in the next call to read/recv
+
       *selected_index = i;
       return 1;
       }
     }
+
+  // no activity on any of the sockets
+  vtkGenericErrorMacro("Socket error in select. No descriptor selected.");
   return -1; 
 #else
   static_cast<void>(sockets_to_select);
@@ -251,6 +430,7 @@
 #ifndef VTK_SOCKET_FAKE_API
   if (socketdescriptor < 0)
     {
+    vtkErrorMacro("Invalid descriptor.");
     return -1;
     }
 
@@ -261,10 +441,9 @@
     unsigned long addr = inet_addr(hostName);
     hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
     }
-
   if (!hp)
     {
-    // vtkErrorMacro("Unknown host: " << hostName);
+    vtkErrorMacro("Unknown host: " << hostName);
     return -1;
     }
 
@@ -273,8 +452,48 @@
   memcpy(&name.sin_addr, hp->h_addr, hp->h_length);
   name.sin_port = htons(port);
 
-  return connect(socketdescriptor, reinterpret_cast<sockaddr*>(&name), 
-    sizeof(name));
+  int iErr
+    = connect(socketdescriptor, reinterpret_cast<sockaddr*>(&name),sizeof(name));
+  if ( (iErr == vtkSocketErrorReturnMacro )
+    && (vtkErrnoMacro == vtkSocketErrorIdMacro(EINTR)) )
+    {
+    // Restarting an interrupted connect call only works on linux,
+    // other unix require a call to select which blocks until the
+    // connection is complete.
+    // See Stevens 2d ed, 15.4 p413, "interrupted connect"
+    iErr = this->SelectSocket(socketdescriptor,0);
+    if (iErr == -1)
+      {
+      // SelectSocket doesn't test for pending errors.
+      int pendingErr;
+      socklen_t pendingErrLen=sizeof(pendingErr);
+      vtkRestartInterruptedSystemCallMacro(
+        getsockopt(socketdescriptor, SOL_SOCKET, SO_ERROR, &pendingErr, &pendingErrLen),
+        iErr);
+      if (iErr == vtkSocketErrorReturnMacro)
+        {
+        vtkSocketErrorMacro(
+          vtkErrnoMacro, "Socket error in call to getsockopt.");
+        return -1;
+        }
+      else
+      if (pendingErr)
+        {
+        vtkSocketErrorMacro(
+          pendingErr, "Socket error pending from call to connect.");
+        return -1;
+        }
+      }
+    }
+  else
+  if (iErr == vtkSocketErrorReturnMacro)
+    {
+    vtkSocketErrorMacro(
+      vtkErrnoMacro, "Socket error in call to connect.");
+    return -1;
+    }
+
+  return 0;
 #else
   static_cast<void>(socketdescriptor);
   static_cast<void>(hostName);
@@ -294,8 +513,14 @@
 #else
   int sizebuf = sizeof(sockinfo);
 #endif
-  if(getsockname(sock, reinterpret_cast<sockaddr*>(&sockinfo), &sizebuf) != 0)
+  int iErr;
+  vtkRestartInterruptedSystemCallMacro(
+    getsockname(sock, reinterpret_cast<sockaddr*>(&sockinfo), &sizebuf),
+    iErr);
+  if (iErr == vtkSocketErrorReturnMacro)
     {
+    vtkSocketErrorMacro(
+      vtkErrnoMacro, "Socket error in call to getsockname.");
     return 0;
     }
   return ntohs(sockinfo.sin_port);
@@ -311,9 +536,18 @@
 #ifndef VTK_SOCKET_FAKE_API
   if (socketdescriptor < 0)
     {
+    vtkErrorMacro("Invalid descriptor.");
     return;
     }
-  vtkCloseSocketMacro(socketdescriptor);
+  int iErr;
+  vtkRestartInterruptedSystemCallMacro(
+    vtkCloseSocketMacro(socketdescriptor),
+    iErr);
+  if (iErr == vtkSocketErrorReturnMacro)
+    {
+    vtkSocketErrorMacro(
+      vtkErrnoMacro, "Socket error in call to close/closesocket.");
+    }
 #else
   static_cast<void>(socketdescriptor);
   return;
@@ -326,6 +560,7 @@
 #ifndef VTK_SOCKET_FAKE_API
   if (!this->GetConnected())
     {
+    vtkErrorMacro("Not connected.");
     return 0;
     }
   if (length == 0)
@@ -337,22 +572,19 @@
   int total = 0;
   do
     {
-    int flags;
-#if defined(_WIN32) && !defined(__CYGWIN__)
-    flags = 0;
-#else
-    // disabling, since not present on SUN.
-    // flags = MSG_NOSIGNAL; //disable signal on Unix boxes.
-    flags = 0;
-#endif
-    int n = send(this->SocketDescriptor, buffer+total, length-total, flags);
-    if(n < 0)
+    int flags=0;
+    int nSent;
+    vtkRestartInterruptedSystemCallMacro(
+      send(this->SocketDescriptor, buffer+total, length-total, flags),
+      nSent);
+    if (nSent == vtkSocketErrorReturnMacro)
       {
-      vtkErrorMacro("Socket Error: Send failed.");
+      vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to send.");
       return 0;
       }
-    total += n;
+    total += nSent;
     } while(total < length);
+
   return 1;
 #else
   static_cast<void>(data);
@@ -367,39 +599,49 @@
 #ifndef VTK_SOCKET_FAKE_API
   if (!this->GetConnected())
     {
+    vtkErrorMacro("Not connected.");
     return 0;
     }
 
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  int trys = 0;
+#endif
+
   char* buffer = reinterpret_cast<char*>(data);
   int total = 0;
   do
     {
-#if defined(_WIN32) && !defined(__CYGWIN__)
-    int trys = 0;
-#endif
-    int n = recv(this->SocketDescriptor, buffer+total, length-total, 0);
-    if(n < 1)
+    int nRecvd;
+    vtkRestartInterruptedSystemCallMacro(
+      recv(this->SocketDescriptor, buffer+total, length-total, 0),
+      nRecvd);
+
+    if (nRecvd == 0)
       {
+      // peer shut down
+      return 0;
+      }
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
+    if ((nRecvd == vtkSocketErrorReturnMacro)
+      && (WSAGetLastError() == WSAENOBUFS))
+      {
       // On long messages, Windows recv sometimes fails with WSAENOBUFS, but
       // will work if you try again.
-      int error = WSAGetLastError();
-      if ((error == WSAENOBUFS) && (trys++ < 1000))
+      if ((trys++ < 1000))
         {
         Sleep(1);
         continue;
         }
-#else
-      // On unix, a recv may be interrupted by a signal.  In this case we should
-      // retry.
-      int errorNumber = errno;
-      if (errorNumber == EINTR) continue;
-#endif
-      vtkErrorMacro("Socket Error: Receive failed.");
+      vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to recv.");
       return 0;
       }
-    total += n;
-    } while(readFully && total < length);
+#endif
+
+    total += nRecvd;
+    } 
+  while( readFully && (total < length));
+
   return total;
 #else
   static_cast<void>(data);
