Reputation: 2857
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?
Upvotes: 0
Views: 2917
Reputation: 241931
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.
Upvotes: 4
Reputation: 239341
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.
Upvotes: 2