0

I want to konw:

When a pipe close , what status poll will set for the pipe's file descriptor?

I try the code below, After child process close all file descriptor , the poll just think all file descriptor can read! Is that right? Or just I make some mistake in this code?

I use SUSE and gcc .

#include <stdio.h>
#include <unistd.h>
#include "../../../myInclude/apue.h"// this is ok

#include <sys/poll.h>

int main(int argc, char **argv)
{
    int fd1[2]; int fd2[2]; int fd3[2];
    pid_t pid;
    if(pipe(fd1)<0 ||pipe(fd2)<0 ||pipe(fd3) <0)
        err_sys("pipe error");//this is a error deal function .it will exit the program and print error message.
    if((pid = fork()) <0)
        err_sys("fork() error");
    else if(pid == 0)
    {
        close(fd1[0]);
        close(fd2[0]);
        close(fd3[0]);

        if(write(fd1[1],"hello fd1 write!",17)!= 17)
            err_sys("write 1error ");
        sleep(2);
        if(write(fd2[1],"hello fd2 write!",17)!=17)
            err_sys("write 2error");
        sleep(2);
        if(write(fd3[1],"hello fd3 write!",17)!= 17)
            err_sys("write 3error");
        sleep(2);
        close(fd1[1]);
        close(fd2[1]);
        close(fd3[1]);
    }
    else
    {
        close(fd1[1]);
        close(fd2[1]);
        close(fd3[1]);
        struct pollfd fd[3];
        fd[0].fd = fd1[0];
        fd[1].fd = fd2[0];
        fd[2].fd = fd3[0];
        fd[0].events = POLLIN;
        fd[1].events = POLLIN;
        fd[2].events = POLLIN;
        while(poll(fd,3,3000) >0)
        {
            printf("now I come \n");
            int i = 0,n;
            char line[MAXLINE];
            for(; i< 3; i++)
            {
                if(fd[i].revents = POLLIN)
                        if ((n =read(fd[i].fd,line,MAXLINE))< 0)
                            err_sys("read error : %d",i);
                        else
                        {
                            line[n] = 0;
                            printf("read from pipe %d : %s\n",i,line);
                        }
            }
        }
        close(fd1[0]);
        close(fd2[0]);
        close(fd3[0]);
    }

    return 0;
}

I think after the child process close all write file descriptor , the poll will set the revents POLLHUP .But it just set it POLLIN !

I am reading the book .I know this an old book. So I want to know how poll works now? Is it set POLLIN for close pipe ? Or just because Linux? Or my code is wrong?

Lidong Guo
  • 2,817
  • 2
  • 19
  • 31

2 Answers2

4

You should always compile your programs with the -Wall option (at least). That would have told you about this problem:

if(fd[i].revents = POLLIN)

The condition will always be true because that is an assignment, not a comparison, and POLLIN is non-zero. The following would not be correct either, although it's better:

if(fd[i].revents == POLLIN)

That will be true if POLLIN is the only flag set in revents. Perhaps that's what you thought you wanted to check, but the normal test would be:

if(fd[i].revents & POLLIN)

which will check if the POLLIN bit is set, indicating that a read won't block.

The error cases can be detected after the read fails, so it's not really necessary to check if, for example, POLLHUP is set. It's not a good idea to test POLLHUP on input sockets because the flag may be set even if data is available to read, and it's usually desirable to read the data.

rici
  • 234,347
  • 28
  • 237
  • 341
  • +1 for spotting the 'obvious once spotted' typo. (I was relooking at the code in light of your comment, and saw it, and then saw you'd seen it too.) And compiling without `-Wall` is like driving without a seat belt — dangerous but doable, but sane people don't take the risk. This would also explain why POLLIN is always set. (And, if I could, another +1 for the `if (fd[i].revents & POLLIN)` fix-up too). – Jonathan Leffler Aug 18 '13 at 17:14
2

When the writing end of the pipe is closed, the reading end will appear "readable" to select() and poll() - this is because a read() will not block.

When you call read(), the return value will be zero, which indicates end-of-file.

caf
  • 233,326
  • 40
  • 323
  • 462
  • The book said `select` is readable while poll is **POLLHUP**. Can you explain more or give me a authority link? – Lidong Guo Aug 18 '13 at 14:34
  • Can you give us a reference to the book so we know why we should treat it as more authoritative than the POSIX standard for [`poll()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html)? – Jonathan Leffler Aug 18 '13 at 15:03
  • @JonathanLeffler (and caf): I might be wrong but I think you're misunderstanding the question. He's not surprised that the `poll` returns the `fd`; he's surprised that it appears that `POLLHUP` is not set. However, we don't know whether that's true or not because of the coding error. – rici Aug 18 '13 at 17:02
  • @rici: Maybe I am misunderstanding...I was mainly seeking information about which book he is using to know what it says. However, given the typo you've identified in your answer, I think we can leave that to be fixed and it will likely sort things out. – Jonathan Leffler Aug 18 '13 at 17:18