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