1.5.21: Problems with fifos

Holger Kiehl Holger.Kiehl@dwd.de
Sat Sep 16 11:02:00 GMT 2006


On Tue, 5 Sep 2006, Dave Korn wrote:

> On 05 September 2006 09:39, Holger Kiehl wrote:
>
>>
>> Attached I have the cygcheck.out file. Please tell me if I forget to mention
>> any information that could be usefull or what I can do to solve this.
>
>  The single most valuable thing you could do would be try and extract a
> simple testcase that demonstrates the problem.  AFD is a huge project and
> there may be many confounding factors; if you can write a little
> self-contained program that opens and uses fifos in the same fashion as AFD
> and shows the same effects, the problem would be a lot more tractable.
>
I have managed to write a little test program that shows that the fifos
do not work as I expected it. The attached program can be compiled simply
by 'cc fifot.c'. When called without any argument it opens the fifo fifot.fifo
and does a select on it to wait for some data to arrive. When called with
an argument it opens the fifo for writting and writes "Hallo Ballo!".

Calling this program under cygwin as follows:


    ./a.exe 1

will cause it to block. Under linux it does not block and I would expect under
any other unix like system it will not block either (which I have not tested).

My understanding of fifos was that when I open a fifo for both reading and
writting, I could write to a fifo without it blocking.

Is cygwin handling fifos correct here and my understanding wrong?

Regards,
Holger
-------------- next part --------------
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#define FIFOT_NAME  "fifot.fifo"

int
main(int argc, char *argv[])
{
   int         readfd,
               val,
               writefd;
   struct stat stat_buf;

   if (stat(FIFOT_NAME, &stat_buf) == -1)
   {
      if (errno == ENOENT)
      {
         if (mkfifo(FIFOT_NAME, S_IRUSR | S_IWUSR) == -1)
         {
            (void)fprintf(stderr, "mkfifo() error : %s\n", strerror(errno));
            exit(1);
         }
      }
      else
      {
         (void)fprintf(stderr, "stat() error : %s\n", strerror(errno));
         exit(1);
      }
   }

   if ((readfd = open(FIFOT_NAME, O_RDONLY | O_NONBLOCK)) == -1)
   {
      (void)fprintf(stderr, "open() error : %s\n", strerror(errno));
      exit(1);
   }
   if ((writefd = open(FIFOT_NAME, O_WRONLY)) == -1)
   {
      (void)fprintf(stderr, "open() error : %s\n", strerror(errno));
      exit(1);
   }
   if ((val = fcntl(readfd, F_GETFD, 0)) == -1)
   {
      (void)fprintf(stderr, "fcntl() error : %s\n", strerror(errno));
      exit(1);
   }
   val &= ~O_NONBLOCK;
   if (fcntl(readfd, F_SETFD, val) == -1)
   {
      (void)fprintf(stderr, "fcntl() error : %s\n", strerror(errno));
      exit(1);
   }
   if (argc == 1)
   {
      int    ret;
      char   buffer[13];
      fd_set rset;

      FD_ZERO(&rset);
      FD_SET(readfd, &rset);
      ret = select(readfd + 1, &rset, NULL, NULL, NULL);
      if (FD_ISSET(readfd, &rset))
      {
         if ((ret = read(readfd, &buffer, 12)) != 12)
         {
            (void)fprintf(stderr, "read() error (%d) : %s\n", ret, strerror(errno));
            exit(1);
         }
         buffer[12] = '\0';
         (void)fprintf(stdout, "Have received `%s'\n", buffer);
      }
      else
      {
         (void)fprintf(stderr, "select() error : %s\n", strerror(errno));
         exit(1);
      }
   }
   else
   {
      if (write(writefd, "Hallo Ballo!", 12) != 12)
      {
         (void)fprintf(stderr, "write() error : %s\n", strerror(errno));
         exit(1);
      }
   }
   exit(0);
}
-------------- next part --------------
--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


More information about the Cygwin mailing list