简体   繁体   中英

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 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 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.

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.

John's answer is correct, but to address your specific question, it's not "returning an invalid file descriptor". open returns -1 to indicate an error. In that case you can check errno (like you're doing for write ) to see the cause of the error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM