linux - poll() can't detect event when socket is closed locally? -


i'm working on project port tcp/ip client program onto embedded arm-linux controller board. client program written in epoll(). however, target platform quite old; kernel available 2.4.x, , epoll() not supported. decided rewrite i/o loop in poll().

but when i'm testing code, found poll() not act expected : won't return when tcp/ip client socket closed locally, thread. i've wrote simple codes test:

#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #include <pthread.h> #include <poll.h>  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",&(hostaddr.sin_addr));     hostaddr.sin_family = af_inet;     hostaddr.sin_port  = htons(12345);     connect(sockfd,(struct sockaddr *)&hostaddr,sizeof(struct sockaddr));      fdlist[0].fd = sockfd;     fdlist[0].events = pollout;      pthread_create(&handle,null,thread_runner,null);      while(1) {         if(poll(fdlist,1,-1) < 1) {             continue;         }         if(fdlist[0].revents & pollnval ) {             printf("pollnval\n");             exit(-1);         }         if(fdlist[0].revents & pollout) {             printf("connected\n");             fdlist[0].events = pollin;         }         if(fdlist[0].revents & pollhup ) {             printf("closed peer\n");             close(fdlist[0].fd);             exit(-1);         }         if(fdlist[0].revents & pollin) {             if( read(fdlist[0].fd, buf, sizeof(buf)) < 0) {                 printf("closed peer\n");                 close(fdlist[0].fd);                 exit(-1);             }         }     }     return 0; } 

in code first create tcp client socket, set non-blocking mode, add poll(), , close() socket in thread. , result is: "pollnval" never printed while socket closed.

is expected behavior of poll() ? if choose select() instead of poll() ?

yes, expected behavior. solve using shutdown() on socket instead of close().

see e.g. http://www.faqs.org/faqs/unix-faq/socket/ section 2.6

edit: reason expected poll() , select() reacts events happening on 1 of fd's. close() removes fd, not exist @ anymore, , can't have events associated it.


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -