title: Blocking socket returns EAGAIN
body: <p>One of my projects on Linux uses blocking sockets. Things happen very serially so non-blocking would just make things more complicated. Anyway, I am finding that often a <code>recv()</code> call is returning <code>-1</code> with <code>errno</code> set to <code>EAGAIN</code>.</p>
  
  <p>The <code>man</code> page only really mentions this happening for non-blocking sockets, which makes sense. With non-blocking, the socket may or may not be available so you might need to try again.</p>
  
  <p><strong>What would cause it to happen for a blocking socket? Can I do anything to avoid it?</strong></p>
  
  <p>At the moment, my code to deal with it looks something like this (I have it throw an exception on error, but beyond that it is a very simple wrapper around <code>recv()</code>):</p>
  
  <pre><code>int ret;
  do {
      ret = ::recv(socket, buf, len, flags | MSG_NOSIGNAL);
  } while(ret == -1 &amp;&amp; errno == EAGAIN);
  
  
  if(ret == -1) {
      throw socket_error(strerror(errno));
  }
  return ret;
  </code></pre>
  
  <p><strong>Is this even correct?</strong> The <code>EAGAIN</code> condition gets hit pretty often.</p>
  
  <p><strong>EDIT:</strong> some things which I've noticed which may be relevant.</p>
  
  <ol>
  <li><p>I do set a read timeout on the socket using <code>setsockopts()</code>, but it is set to 30 seconds. the <code>EAGAIN</code>'s happen way more often than once every 30 secs. <strong>CORRECTION</strong> my debugging was flawed, <code>EAGAIN</code>'s don't happen as often as I thought they did. Perhaps it is the timeout triggering.</p></li>
  <li><p>For connecting, I want to be able to have connect timeout, so I temporarily set the socket to non-blocking. That code looks like this:</p>
  
  <pre><code>int      error = 0;
  fd_set   rset;
  fd_set   wset;
  int      n;
  const SOCKET sock = m_Socket;
  
  // set the socket as nonblocking IO
  const int flags = fcntl (sock, F_GETFL, 0);
  fcntl(sock, F_SETFL, flags | O_NONBLOCK);
  
  errno = 0;
  
  // we connect, but it will return soon
  n = ::connect(sock, addr, size_addr);
  
  if(n &lt; 0) { 
      if (errno != EINPROGRESS) {
          return -1;
      }
  } else if (n == 0) {
      goto done;
  }
  
  FD_ZERO(&amp;rset);
  FD_ZERO(&amp;wset);
  FD_SET(sock, &amp;rset);
  FD_SET(sock, &amp;wset);
  
  struct timeval tval;
  tval.tv_sec = timeout;
  tval.tv_usec = 0;
  
  // We "select()" until connect() returns its result or timeout
  n = select(sock + 1, &amp;rset, &amp;wset, 0, timeout ? &amp;tval : 0);
  if(n == 0) {    
      errno = ETIMEDOUT;
      return -1;
  }
  
  if (FD_ISSET(sock, &amp;rset) || FD_ISSET(sock, &amp;wset)) {
      socklen_t len = sizeof(error);
      if (getsockopt(SOL_SOCKET, SO_ERROR, &amp;error, &amp;len) &lt; 0) {
          return -1;
      }
  } else {
      return -1;
  }
  
  done:
  // We change the socket options back to blocking IO
  if (fcntl(sock, F_SETFL, flags) == -1) {
      return -1;
  }
  return 0;
  </code></pre></li>
  </ol>
  
  <p>The idea is that I set it to non-blocking, attempt a connect and select on the socket so I can enforce a timeout. Both the set and restore <code>fcntl()</code> calls return successfully, so the socket should end up in blocking mode again when this function completes.</p>