FIFO issues
Ken Brown
kbrown@cornell.edu
Fri Sep 23 15:36:56 GMT 2022
On 9/20/2022 1:20 PM, Enrico Forestieri wrote:
> On Tue, Sep 20, 2022 at 06:18:54PM -0700, Ken Brown wrote:
>>
>> On 9/20/2022 2:54 AM, Enrico Forestieri wrote:
>>>
>>> I compared the behavior of read() and select() on 3 different platforms.
>>> My conclusion is that, actually, read() behaves the same on all of them,
>>> whereas cygwin differs in the way select() works.
>>
>> Then I'm even more confused than I was before. Are you saying that
>> there are situations in which read() reports EOF but select() does not
>> report read ready? Could you post the code you used for testing?
>
> I simply introduced a timeout for select() such that it returns on any
> platform. On cygwin, when using "O_RDONLY | O_NONBLOCK" for the input
> pipe, select() always returns 1, while on all other platforms it returns 0
> unless a client actually opens it for writing.
>
> As the "if (FD_ISSET(infd, &readfds))" block would not be entered on the
> other platforms, I replaced it with "if (TRUE)" so that the read() is
> always executed. In this conditions, the output is the same on all
> platforms, meaning that the issue is the select() and not the read() call.
>
> This is the attached fifocomm-test.c file.
I've just sent a patch to the cygwin-patches list that makes Cygwin behave the
same as Linux. Thanks for reporting this problem.
Ken
P.S. I'm attaching a simplified test case that I used for testing the patch.
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>
#include <errno.h>
#include <sys/stat.h>
#define FIFO_PATH "/tmp/myfifo"
int
main ()
{
int fd, tmpfd, nsel;
fd_set readfds;
struct timeval wait_tm = { 0l, 200000l }; /* 200 millisecs */
if (unlink (FIFO_PATH) < 0 && errno != ENOENT)
{
perror ("unlink");
exit (1);
}
if (mkfifo (FIFO_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
| S_IWOTH) < 0)
{
perror ("mkfifo");
exit (1);
}
printf ("Opening a FIFO for reading with O_NONBLOCK\n");
if ((fd = open (FIFO_PATH, O_RDONLY | O_NONBLOCK)) < 0)
{
perror ("open");
exit (1);
}
printf ("Testing for read ready...\n");
FD_ZERO (&readfds);
FD_SET (fd, &readfds);
nsel = select (fd + 1, &readfds, NULL, NULL, &wait_tm);
printf (" select returned %d\n", nsel);
printf ("Opening and closing FIFO for writing...\n");
if ((tmpfd = open (FIFO_PATH, O_WRONLY)) < 0)
{
perror ("open");
exit (1);
}
if (close (tmpfd) < 0)
{
perror ("close");
exit (1);
}
FD_ZERO (&readfds);
FD_SET (fd, &readfds);
nsel = select (fd + 1, &readfds, NULL, NULL, &wait_tm);
printf (" now select returned %d\n", nsel);
}
More information about the Cygwin
mailing list