diff --git a/lib/http/__init__.py b/lib/http/__init__.py
index d0db1ce3beb89570bf07e2c0d40dc07aadb4e5b2..f8872514750386b59aee06d88e116b88d492ddfb 100644
--- a/lib/http/__init__.py
+++ b/lib/http/__init__.py
@@ -361,7 +361,7 @@ def SocketOperation(sock, op, arg1, timeout):
       else:
         wait_for_event = event_poll
 
-      event = utils.WaitForSocketCondition(sock, wait_for_event, timeout)
+      event = utils.WaitForFdCondition(sock, wait_for_event, timeout)
       if event is None:
         raise HttpSocketTimeout()
 
diff --git a/lib/http/client.py b/lib/http/client.py
index 6b70a0499849407e62c29c041ae14b105a881474..655a209b20c62acedce53355741aa4ecd62782ad 100644
--- a/lib/http/client.py
+++ b/lib/http/client.py
@@ -250,8 +250,8 @@ class HttpClientRequestExecutor(http.HttpBase):
 
     if not connected:
       # Wait for connection
-      event = utils.WaitForSocketCondition(self.sock, select.POLLOUT,
-                                           self.CONNECT_TIMEOUT)
+      event = utils.WaitForFdCondition(self.sock, select.POLLOUT,
+                                       self.CONNECT_TIMEOUT)
       if event is None:
         raise http.HttpError("Timeout while connecting to server")
 
diff --git a/lib/utils.py b/lib/utils.py
index 7f2c8612c5a851319595a3f93a1ce99b267e5c1c..ee85f946e2e23c61e6cc479204bcc5f6c02356c3 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -1497,12 +1497,14 @@ except NameError:
     return False
 
 
-def WaitForSocketCondition(sock, event, timeout):
+def SingleWaitForFdCondition(fdobj, event, timeout):
   """Waits for a condition to occur on the socket.
 
-  @type sock: socket
-  @param sock: Wait for events on this socket
-  @type event: int
+  Immediately returns at the first interruption.
+
+  @type fdobj: integer or object supporting a fileno() method
+  @param fdobj: entity to wait for events on
+  @type event: integer
   @param event: ORed condition (see select module)
   @type timeout: float or None
   @param timeout: Timeout in seconds
@@ -1518,21 +1520,69 @@ def WaitForSocketCondition(sock, event, timeout):
     timeout *= 1000
 
   poller = select.poll()
-  poller.register(sock, event)
+  poller.register(fdobj, event)
   try:
-    while True:
-      # TODO: If the main thread receives a signal and we have no timeout, we
-      # could wait forever. This should check a global "quit" flag or
-      # something every so often.
-      io_events = poller.poll(timeout)
-      if not io_events:
-        # Timeout
-        return None
-      for (_, evcond) in io_events:
-        if evcond & check:
-          return evcond
-  finally:
-    poller.unregister(sock)
+    # TODO: If the main thread receives a signal and we have no timeout, we
+    # could wait forever. This should check a global "quit" flag or something
+    # every so often.
+    io_events = poller.poll(timeout)
+  except select.error, err:
+    if err[0] != errno.EINTR:
+      raise
+    io_events = []
+  if io_events and io_events[0][1] & check:
+    return io_events[0][1]
+  else:
+    return None
+
+
+class FdConditionWaiterHelper(object):
+  """Retry helper for WaitForFdCondition.
+
+  This class contains the retried and wait functions that make sure
+  WaitForFdCondition can continue waiting until the timeout is actually
+  expired.
+
+  """
+
+  def __init__(self, timeout):
+    self.timeout = timeout
+
+  def Poll(self, fdobj, event):
+    result = SingleWaitForFdCondition(fdobj, event, self.timeout)
+    if result is None:
+      raise RetryAgain()
+    else:
+      return result
+
+  def UpdateTimeout(self, timeout):
+    self.timeout = timeout
+
+
+def WaitForFdCondition(fdobj, event, timeout):
+  """Waits for a condition to occur on the socket.
+
+  Retries until the timeout is expired, even if interrupted.
+
+  @type fdobj: integer or object supporting a fileno() method
+  @param fdobj: entity to wait for events on
+  @type event: integer
+  @param event: ORed condition (see select module)
+  @type timeout: float or None
+  @param timeout: Timeout in seconds
+  @rtype: int or None
+  @return: None for timeout, otherwise occured conditions
+
+  """
+  if timeout is not None:
+    retrywaiter = FdConditionWaiterHelper(timeout)
+    result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout,
+                   args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout)
+  else:
+    result = None
+    while result is None:
+      result = SingleWaitForFdCondition(fdobj, event, timeout)
+  return result
 
 
 def partition(seq, pred=bool): # # pylint: disable-msg=W0622