Fix issue1628205: Socket file objects returned by socket.socket.makefile() now
properly handles EINTR within the read, readline, write & flush methods.
The socket.sendall() method now properly handles interrupted system calls.
diff --git a/Lib/socket.py b/Lib/socket.py
index dd0f327..a1e0386 100644
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -86,9 +86,11 @@
     from StringIO import StringIO
 
 try:
-    from errno import EBADF
+    import errno
 except ImportError:
-    EBADF = 9
+    errno = None
+EBADF = getattr(errno, 'EBADF', 9)
+EINTR = getattr(errno, 'EINTR', 4)
 
 __all__ = ["getfqdn", "create_connection"]
 __all__.extend(os._get_exports_list(_socket))
@@ -286,10 +288,22 @@
 
     def flush(self):
         if self._wbuf:
-            buffer = "".join(self._wbuf)
+            data = "".join(self._wbuf)
             self._wbuf = []
             self._wbuf_len = 0
-            self._sock.sendall(buffer)
+            buffer_size = max(self._rbufsize, self.default_bufsize)
+            data_size = len(data)
+            write_offset = 0
+            try:
+                while write_offset < data_size:
+                    self._sock.sendall(buffer(data, write_offset, buffer_size))
+                    write_offset += buffer_size
+            finally:
+                if write_offset < data_size:
+                    remainder = data[write_offset:]
+                    del data  # explicit free
+                    self._wbuf.append(remainder)
+                    self._wbuf_len = len(remainder)
 
     def fileno(self):
         return self._sock.fileno()
@@ -329,7 +343,12 @@
             # Read until EOF
             self._rbuf = StringIO()  # reset _rbuf.  we consume it via buf.
             while True:
-                data = self._sock.recv(rbufsize)
+                try:
+                    data = self._sock.recv(rbufsize)
+                except error, e:
+                    if e[0] == EINTR:
+                        continue
+                    raise
                 if not data:
                     break
                 buf.write(data)
@@ -353,7 +372,12 @@
                 # than that.  The returned data string is short lived
                 # as we copy it into a StringIO and free it.  This avoids
                 # fragmentation issues on many platforms.
-                data = self._sock.recv(left)
+                try:
+                    data = self._sock.recv(left)
+                except error, e:
+                    if e[0] == EINTR:
+                        continue
+                    raise
                 if not data:
                     break
                 n = len(data)
@@ -396,17 +420,31 @@
                 self._rbuf = StringIO()  # reset _rbuf.  we consume it via buf.
                 data = None
                 recv = self._sock.recv
-                while data != "\n":
-                    data = recv(1)
-                    if not data:
-                        break
-                    buffers.append(data)
+                while True:
+                    try:
+                        while data != "\n":
+                            data = recv(1)
+                            if not data:
+                                break
+                            buffers.append(data)
+                    except error, e:
+                        # The try..except to catch EINTR was moved outside the
+                        # recv loop to avoid the per byte overhead.
+                        if e[0] == EINTR:
+                            continue
+                        raise
+                    break
                 return "".join(buffers)
 
             buf.seek(0, 2)  # seek end
             self._rbuf = StringIO()  # reset _rbuf.  we consume it via buf.
             while True:
-                data = self._sock.recv(self._rbufsize)
+                try:
+                    data = self._sock.recv(self._rbufsize)
+                except error, e:
+                    if e[0] == EINTR:
+                        continue
+                    raise
                 if not data:
                     break
                 nl = data.find('\n')
@@ -430,7 +468,12 @@
                 return rv
             self._rbuf = StringIO()  # reset _rbuf.  we consume it via buf.
             while True:
-                data = self._sock.recv(self._rbufsize)
+                try:
+                    data = self._sock.recv(self._rbufsize)
+                except error, e:
+                    if e[0] == EINTR:
+                        continue
+                    raise
                 if not data:
                     break
                 left = size - buf_len