Search code examples
clinuxpipenamed-pipes

Why does opening a named pipe non-blockingly return an invalid file descriptor?


I'm trying to solidify my understanding of who blocks when and why wrt opening, writing to, and reading from named pipes.

The following code implies that it's invalid to open a named pipe with O_WRONLY | O_NONBLOCK, but I'm not sure whether there's just some bug in my code I don't understand, or if this is generally true.

// main.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int main( int argc, char* argv[] )
{
  int wfd = open( "/tmp/foo", O_WRONLY | O_NONBLOCK );
  printf( "wfd[%d]\n", wfd );
  if ( wfd >= 0 )
  {
    int res = write( wfd, "0", 1 );
    printf( "write: [%d], errno[%d(%s)]\n", res, errno, strerror( errno ) );
    sleep(3);
    printf( "writer ending!\n" );
  }
  return 0;
}
> ls -l /tmp/foo 
prwxrwxrwx. 1 user user 0 Sep  4 10:35 /tmp/foo
> 
> gcc -g main.c && ./a.out 
wfd[-1]

Question: Why does opening the named pipe with O_WRONLY | O_NONBLOCK return an invalid file descriptor?

I have a suspicion that this has to do with pipes requiring both read and write ends to be open simultaneously, and my hackneyed way of getting around this (by opening one end non-blockingly) fails for this reason. But I haven't been able to find any specific documentation that either backs up that hypothesis or otherwise explains this observation.


Solution

  • mkfifo(3) - Linux man page:

    See fifo(7) for nonblocking handling of FIFO special files.

    fifo(7) - Linux man page:

    A process can open a FIFO in nonblocking mode. In this case, opening for read only will succeed even if no-one has opened on the write side yet, opening for write only will fail with ENXIO (no such device or address) unless the other end has already been opened.