>Подскажите пожалуйста, в чём же ошибка. Почему я не могу перехватить POLLHUP
> POLLERR ??
>Программа должна при обрыве или завершении связи вызвать return 0;
>
>
>#include <stdio.h>
>#include <unistd.h>
>#include <sys/socket.h>
>#include <resolv.h>
>#include <sys/poll.h>
>#include <fcntl.h>
>#include <netinet/in.h>
>
>#define PORT 6666
>#define TIME_OUT 300
>struct pollfd fds[1];
>int main(void)
>{
>struct sockaddr_in addr;
>int value=1;int cl=1,result,k,addr_len=sizeof(addr),sd;
>char buffer[256];
>int bytes;
>sd = socket(PF_INET, SOCK_STREAM, 0);
>bzero(&addr, sizeof(addr));
Тут советую юзать memset (но это так, просто не по теме)
>addr.sin_family = AF_INET;
>addr.sin_port = htons(PORT);
>addr.sin_addr.s_addr = INADDR_ANY;
>setsockopt(sd,SOL_SOCKET,SO_REUSEADDR, &value,sizeof(value));
>if ( bind(sd, (struct sockaddr *)&addr, sizeof(addr)) == 0 )
>{
>
> listen(sd,5);
>fds[0].fd=accept(sd,0,0);
>fcntl(fds[0].fd,F_SETFL,O_NONBLOCK);
А это-то зачем? У тебя же есть мультиплексор в лице POLL. Не надо играцца с разблокированными сокетами, тока гемору огребешь, да и POLL в классическом варианте юзают на блокированном сокете
>fds[0].events=POLLIN|POLLHUP;
>for (;;)
>{
>if ( (result = poll(fds, 1, 500)) > 0 )
>{
> if(((fds[0].revents&POLLHUP) == POLLHUP) ||
>
> ((fds[0].revents&POLLERR)
>== POLLERR) ||
> ((fds[0].revents&POLLNVAL)
>== POLLNVAL))
Тут не совсем верно. Р-евенты заполняются тоже мультиплексорно, т.е. вполне реальна ситуация, что у тебя будет промаскирована и POLLIN и POLLHUP одновременно (тогда условие (fds[0].revents&POLLHUP) == POLLHUP не проканает). Т.е. лучше делать просто if (fds[0].revents&POLLERR || fds[0].revents&POLLHUP || fds[0].revents&POLLNVAL) {}
> {puts("POLLHUP");return 0;}
>
>if ( (fds[0].revents & POLLIN)==POLLIN )
>{
>recv(fds[0].fd,buffer,sizeof(buffer),0);
Ну и судя по оформлению вот этого ресива, он ошибки раньше словит, чем poll-мультиплексор. При нормальном разрыве соединения он вернет 0 (странно что ты возврат не проверяешь) а потом только придет р-евент POLLHUP, а при аварийном у тебя прога ваще упадет с SIGPIPE (ибо в ресиве нету флага MSG_NOSIGNAL). Т.е. тут можно классический перехват сделать вроде
if (recv(fds[0].fd,buffer,sizeof(buffer),MSG_NOSIGNAL)<=0) {Типа наелись}
И еще, как раз изза мультимаскирования р-евентов лучше сначала проверять полезные флаги (POLLIN POLLOUT) а потом уже ошибочные. Ибо тебе может придти мультисет POLLIN+POLLHUP, к примеру, а ты по POLLHUP'у сразу все прибъешь и похоронишь хвостик данных.
>puts(buffer);
>printf("POLLIN\n");
>}
>}
>else if ( result < 0 )
>{perror("poll() error");exit(0);}
>}
>}
>return 0;
>}