Polling () on a named pipe returns with POLLHUP continuously and immediately

I open a named pipe (fifo created by mkfifo), with a non-blocking flag (open (... O_NONBLOCK)), then run a poll ( poll (...)). So far, so good. Then from the command line I make a couple

echo 123 > /tmp/fifo

They are all read from the pipe as expected (at least I expect them to work fine).

My problem is that after the first echo, POLLHUP is installed , and it is stuck, the poll returns immediately from this point.

How can I clean / get rid of POLHUPA ?

He begins to drive me crazy :(

Yes, the other end of the pipe is closed (after it was opened earlier), so it has become half closed, but my end is still open and lively, and I like it. This is not dead, I can still receive new echoes through the pipe, it’s just a poll crying by the POLLHUP river (which I didn’t even ask for in the first place, but the poll can just mark them anyway [people poll: because this can be any of those indicated in the events, or one of the values ​​POLLERR, POLLHUP "]) and is almost useless.

Obviously, I cannot get this fd from the set, because I still want to receive notifications of new data on it.

, - , , ... , ( fd ... )...

Linux ( / ).

, .

( ):

    int newfd = dup(fds[i].fd);
    close(fds[i].fd);
    dup2(newfd, fds[i].fd);
    close(newfd);

? - ?

( ( ), , , , ...)

( , , , 1 , ...)

#include <stdio.h>

#include <sys/types.h>  // mkfifo
#include <sys/stat.h>   // mkfifo

#include <unistd.h>
#include <fcntl.h>

#include <errno.h>
#include <string.h>

#include <poll.h>


int main(int argc, char **argv) {
    char* pipename = "/tmp/fifo";
    mkfifo(pipename, S_IWUSR | S_IRUSR | S_IRGRP);
    int fd = open(pipename, O_RDONLY | O_NONBLOCK); /// O_ASYNC, O_SYNC

    struct pollfd fds[1];
        fds[0].fd = fd;
        fds[0].events = POLLIN;
        fds[0].revents = 0;

    while (1) {
        int res = poll(fds, 1, 1000);
        if (res<0)  { perror("poll");  return 1; }
        if (res==0) { printf(".\n"); continue; }
        printf("Poll [%d]: 0x%04x on %d\n", 0, fds[0].revents, fds[0].fd);

        char buff[512];
        int count = (int)read(fds[0].fd, buff, (size_t)(sizeof(buff)-1));
        if (count>=0) {
            buff[count] = 0;
            printf("Pipe read %d bytes: '%s'\n", count, buff);
            usleep(1000*100); /// cpu protector sleep for POLLHUP :)
        }   
    }
    return 0;
}

:

gcc (4.6.3) Linux (lubuntu) (x64). .

, , , - , ...

/:

  • №1, mark4o, , O_RDWR O_RDONLY. , POLLHUP -s (, , , ). ( ).
+4
1

( , , ), , , . , POLLHUP () , , .

, , , PIPE_BUF 512 . , , , , . , , , , - , ( ) .

POLLHUP , , . , O_RDWR O_RDONLY, . , ( ), .

+6

Source: https://habr.com/ru/post/1528799/


All Articles