FIFO issues

Norton Allen allen@huarp.harvard.edu
Mon Sep 19 19:53:11 GMT 2022


On 9/19/2022 3:50 PM, Norton Allen wrote:
>
> On 9/19/2022 3:15 PM, Ken Brown wrote:
>> On 9/18/2022 5:45 PM, Enrico Forestieri wrote:
>>> Hi,
>>>
>>> I think I am experiencing a problem with fifos on cygwin. The attached
>>> C source (fifocomm.c) creates two pipes (/tmp/pipe.{in,out}), expecting
>>> to receive inputs from /tmp/pipe.in and replying to /tmp/pipe.out.
>>>
>>> Compiling this source on linux and launching it produces on the 
>>> terminal
>>>
>>> 1) Opening pipes
>>>
>>> and then the program waits for someone to write to /tmp/pipe.in.
>>> Opening another terminal and launching the fifotest.sh script (also
>>> attached) produces on the first terminal
>>>
>>> 1) Closing pipes
>>> 2) Opening pipes
>>>
>>> and the program continues waiting for another input, while the other
>>> terminal shows "You sent: foo"
>>>
>>> Instead, on cygwin, after launching the program one gets:
>>>
>>> 1) Opening pipes
>>> 1) Closing pipes
>>> 2) Opening pipes
>>> 2) Closing pipes
>>> 3) Opening pipes
>>> 3) Closing pipes
>>> 4) Opening pipes
>>> ....
>>> ....
>>>
>>> meaning that the pipes are continually closed and reopened even if
>>> nobody is writing to /tmp/pipe.in.
>>>
>>> Seemingly, the problem is the return value of read() on line 55.
>>> As O_NONBLOCK is set, until no data is available for reading,
>>> read() shouldn't block but should return -1 and set errno to EAGAIN.
>>> After a client that opened the pipe for writing, closes it
>>> (and no other client is using the pipe), read() should return 0 and
>>> only at this point the pipes have to be closed and reopened.
>>>
>>> However, on cygwin, read() returns 0 also when nobody is writing to the
>>> input pipe causing the above ping pong. As already said, it works as it
>>> should on linux.
>>
>> I see what's happening, but I don't see why it's a bug, and I don't 
>> understand why the Linux behavior is different.
>>
>> On Cygwin, the call to 'select' in line 44 returns immediately with 
>> nsel == 1. This seems correct to me, since the man page for 'select' 
>> says, "A file descriptor is ready for reading if a read operation 
>> will not block; in particular, a file descriptor is also ready on 
>> end-of-file."  In the present case a read operation will not block 
>> for two reasons: first, O_NONBLOCK has been set; second, we're at EOF 
>> because no process has opened /tmp/pipe.in for writing.  Given that 
>> we're at EOF, the return value of 0 for the subsequent 'read' is also 
>> correct.
>>
>> On Linux, 'select' does not return immediately but instead waits for 
>> someone to write to the FIFO.
>>
>> Can someone explain why Linux is right and Cygwin is wrong here? I 
>> must be missing something obvious.
>>
>> Ken
>
> This is how I'm reading this, but I have not actually looked at or 
> tried the posted code yet:
>
> We use select() specifically when we are using non-blocking I/O. All 
> the blocking happens in select() so we can track multiple sockets. If 
> select() returns when there is no data available, it's not really 
> doing its job, i.e. waiting for data. There are of course particular 
> cases where something else (opening, closing) causes select() to 
> return, which is normal and expected, but just because the reader is 
> non-blocking is not a good reason for select() to return.
>
I should also mention that I use cygwin pipes extensively and have not 
encountered this behavior, so maybe I am doing things differently.




More information about the Cygwin mailing list