fixunix
Tags Register FAQ Members List Social Groups Calendar Search Today's Posts Mark Forums Read

use of select() on FIFO after it has closed - Unix

This is a discussion on use of select() on FIFO after it has closed - Unix ; Set up a fifo like this from bash: mkfifo /tmp/testfifo inside a program open it, which gets an fd, set that fd nonblocking (because of other stuff going on on other fd's which are not shown in this example) then ...


Fix Unix > Unix > use of select() on FIFO after it has closed

Reply
 
LinkBack Tools
  #1  
Old 02-23-2008, 06:54 PM
Junior Member
 
Join Date: Sep 2009
Posts: 0
Default use of select() on FIFO after it has closed

Set up a fifo like this from bash:

mkfifo /tmp/testfifo

inside a program open it, which gets an fd, set that fd nonblocking
(because of other stuff going on on other fd's which are not shown in
this example) then enter a program which has a loop containing
(simplified from the original):

FD_CLEAR(&read_set);
FD_SET(fd, &read_set);
select(fd+1,&read_set,NULL,NULL,NULL);
if(FD_ISSET(fd,&read_set)){
ret = read(fd, addr, n);
if(ret>0){
(void) fprintf(stdout,"Read %s\n",addr);
}
else if(ret < 0){
(void) fprintf(stdout,"Error %d\n",errno);
}
else {
(void) fprintf(stdout,"File closed\n");
}
}


Here is where it gets strange. At first this works as expected, it
gets to the select() and waits for input on the FIFO. If from another
shell one then does:

echo "word" >/tmp/testfifo

Select sees that data is available and returns, FD_ISSET is true,
read() gets the data, and finally fprintf emits

Read word

So far so good. However, then things go south. Because the echo
"closed" the fifo, select() sees it in End of File (which is an event)
and comes back immediately, FD_ISSET is true, and read returns 0 (== end
of file). So the program begins to spew

File closed
File closed
....

as fast as it can. If while this is going on from another shell
one does:

echo "another word" >/tmp/testfifo

the output will look like this

....
File closed
Read another word
File closed
File closed
....

In this case EOF does not indicate the end of input, that is
triggered by a particular "End of Stream" string sent to the fifo.

The question is, what is the most portable way to make the select() stop
coming back immediately? If the application closes and reopens the FIFO
it will go back to the original state where it will wait at the
select(). Is there a better way, perhaps using fcntl()?

Thanks,

David Mathog
Reply With Quote
  #2  
Old 02-23-2008, 08:26 PM
Junior Member
 
Join Date: Sep 2009
Posts: 0
Default Re: use of select() on FIFO after it has closed

"David Mathog" wrote in message
news:fppq52$ob4$1@naig.caltech.edu...
[snip]
> In this case EOF does not indicate the end of input, that is
> triggered by a particular "End of Stream" string sent to the fifo.
>
> The question is, what is the most portable way to make the select() stop
> coming back immediately? If the application closes and reopens the FIFO
> it will go back to the original state where it will wait at the select().
> Is there a better way, perhaps using fcntl()?


The potential problem with closing and reopening the FIFO is that there is a
window between read() == 0 and close() where data written will be thrown
away.

An alternative is to open the FIFO for writing immediately after opening it
for reading, and leave both descriptors open (opening it O_RDWR may work;
the behaviour is unspecified by POSIX). This means you will never see EOF
(useful in some cases).

Alex


Reply With Quote
  #3  
Old 02-25-2008, 08:52 PM
Junior Member
 
Join Date: Sep 2009
Posts: 0
Default Re: use of select() on FIFO after it has closed

Alex Fraser wrote:

> An alternative is to open the FIFO for writing immediately after opening it
> for reading, and leave both descriptors open (opening it O_RDWR may work;
> the behaviour is unspecified by POSIX). This means you will never see EOF
> (useful in some cases).


I went this route. Now it opens the file, checks the fd with fstat() to
see if it is a FIFO, and if it is, it opens the same file for write.

Unfortunately it (still) locks on the first open() of the FIFO unless
there is already data waiting there. I do not think there is a way
around that, since the program cannot set read nonblocking until it has
a read fd, and it cannot get a read fd until the file is opened. The
program could use stat() first to see if it is a FIFO before opening it
for read, and do the open for write first, then push a byte or two into
the FIFO so the open for read won't block. But that isn't safe, since
the program has no way of knowing if there is data in the FIFO at that
point. Better to live with the block on open for read I guess.

Thanks,

David Mathog
Reply With Quote
  #4  
Old 02-26-2008, 03:05 AM
Junior Member
 
Join Date: Sep 2009
Posts: 0
Default Re: use of select() on FIFO after it has closed

In article ,
David Mathog wrote:

> Alex Fraser wrote:
>
> > An alternative is to open the FIFO for writing immediately after opening it
> > for reading, and leave both descriptors open (opening it O_RDWR may work;
> > the behaviour is unspecified by POSIX). This means you will never see EOF
> > (useful in some cases).

>
> I went this route. Now it opens the file, checks the fd with fstat() to
> see if it is a FIFO, and if it is, it opens the same file for write.
>
> Unfortunately it (still) locks on the first open() of the FIFO unless
> there is already data waiting there. I do not think there is a way
> around that, since the program cannot set read nonblocking until it has
> a read fd, and it cannot get a read fd until the file is opened. The
> program could use stat() first to see if it is a FIFO before opening it
> for read, and do the open for write first, then push a byte or two into
> the FIFO so the open for read won't block. But that isn't safe, since
> the program has no way of knowing if there is data in the FIFO at that
> point. Better to live with the block on open for read I guess.


Does the O_NONBLOCK option to open(2) help?

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Reply With Quote
  #5  
Old 02-26-2008, 05:01 PM
Junior Member
 
Join Date: Sep 2009
Posts: 0
Default Re: use of select() on FIFO after it has closed

Barry Margolin wrote:
>
> Does the O_NONBLOCK option to open(2) help?


(Sheepishly) Yes, that did it.

Thanks,

David Mathog
Reply With Quote
  #6  
Old 02-27-2008, 07:29 AM
Junior Member
 
Join Date: Sep 2009
Posts: 0
Default Re: use of select() on FIFO after it has closed

"David Mathog" wrote in message
news:fq1gl6$11o$1@naig.caltech.edu...
> Barry Margolin wrote:
>>
>> Does the O_NONBLOCK option to open(2) help?

>
> (Sheepishly) Yes, that did it.


Ignoring O_RDWR (undefined by POSIX for a FIFO), open(fifo, O_RDONLY |
O_NONBLOCK) then open(fifo, O_WRONLY) is the only way because open(fifo,
O_WRONLY) blocks until the FIFO is open for reading and open(fifo, O_WRONLY
| O_NONBLOCK) returns an error (ENXIO) if the FIFO is not open for reading.

Alex


Reply With Quote
Reply

Tools


LinkBacks (?)
LinkBack to this Thread: http://fixunix.com/unix/350803-use-select-fifo-after-has-closed.html
Posted By For Type Date
codeblog This thread Refback 04-04-2008 08:37 PM
Graphics Planet This thread Refback 03-10-2008 05:50 PM
Planet Inkscape This thread Refback 03-10-2008 11:59 AM
Planet Ubuntu This thread Refback 03-10-2008 10:09 AM
Planet Ubuntu This thread Refback 03-10-2008 08:18 AM
The Linux Index » Kees Cook: using select on a fifo This thread Pingback 03-10-2008 02:07 AM
codeblog » using select on a fifo This thread Pingback 03-10-2008 01:00 AM

Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: fifo log problem unix FreeBSD 0 11-03-2008 04:34 PM
Re: fifo log problem unix FreeBSD 0 11-03-2008 03:28 PM
fifo log problem unix FreeBSD 0 11-03-2008 02:48 PM
Bug#486892: different behavior from debconf when noninteractively asking a select question with a default not in the select list unix Debian 0 06-19-2008 08:30 AM
Bug#419507: marked as done (bugs closed bu NMUs are really closed, not tagged fixed) unix Debian 0 02-28-2008 12:20 PM


All times are GMT. The time now is 09:34 AM.