title: poll() can't detect event when socket is closed locally?
body: <p>I'm working on a project that will port a TCP/IP client program onto an embedded ARM-Linux controller board. The client program was originally written in epoll(). However, the target platform is quite old; the only kernel available is 2.4.x, and epoll() is not supported. So I decided to rewrite the I/O loop in poll(). </p>
  
  <p>But when I'm testing code, I found that poll() does not act as I expected : it won't return when a TCP/IP client socket is closed locally, by another thread. I've wrote a very simple codes to do some test:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;poll.h&gt;
  
  struct pollfd   fdList[1];
  
  void *thread_runner(void *arg)
  {
      sleep(10);
      close(fdList[0].fd);
      printf("socket closed\n");
      pthread_exit(NULL);
  }
  
  int main(void)
  {
      struct  sockaddr_in hostAddr;
      int sockFD;
      char buf[32];
      pthread_t handle;
  
      sockFD = socket(AF_INET, SOCK_STREAM, 0);
      fcntl(sockFD,F_SETFL,O_NONBLOCK|fcntl(sockFD,F_GETFL,0));
  
      inet_aton("127.0.0.1",&amp;(hostAddr.sin_addr));
      hostAddr.sin_family = AF_INET;
      hostAddr.sin_port  = htons(12345);
      connect(sockFD,(struct sockaddr *)&amp;hostAddr,sizeof(struct sockaddr));
  
      fdList[0].fd = sockFD;
      fdList[0].events = POLLOUT;
  
      pthread_create(&amp;handle,NULL,thread_runner,NULL);
  
      while(1) {
          if(poll(fdList,1,-1) &lt; 1) {
              continue;
          }
          if(fdList[0].revents &amp; POLLNVAL ) {
              printf("POLLNVAL\n");
              exit(-1);
          }
          if(fdList[0].revents &amp; POLLOUT) {
              printf("connected\n");
              fdList[0].events = POLLIN;
          }
          if(fdList[0].revents &amp; POLLHUP ) {
              printf("closed by peer\n");
              close(fdList[0].fd);
              exit(-1);
          }
          if(fdList[0].revents &amp; POLLIN) {
              if( read(fdList[0].fd, buf, sizeof(buf)) &lt; 0) {
                  printf("closed by peer\n");
                  close(fdList[0].fd);
                  exit(-1);
              }
          }
      }
      return 0;
  }
  </code></pre>
  
  <p>In this code I first create a TCP client socket, set to non-blocking mode, add to poll(), and close() the socket in another thread. And the result is: "POLLNVAL" is never printed while the socket is closed.</p>
  
  <p>Is that an expected behavior of poll() ? Will it help if I choose select() instead of poll() ?</p>