Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
334 views
in Technique[技术] by (71.8m points)

c++ - Why does my program hang when opening a mkfifo-ed pipe?

I use mkfifo to create a named pipe. Then I use the following program to open it. However, the program hangs at the line "fopen". Is there something wrong here?

int main(int argc, char** argv) {
char* line = "hello, world!";
FILE* fp = fopen("/tmp/myFIFO", "rw");
fprintf(fp, line);
fclose(fp);
return 0;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Try passing "w" as the mode to fopen. "rw" is not a valid mode argument for fopen, and even if it was, you probably don't want to both read and write to the FIFO in the same process (although it is possible, see below).

As an aside, the correct mode argument for opening a file for both reading and writing is either "r+" or "w+" (see the answers to this question for the differences).

This program will correctly write to the FIFO:

#include <stdio.h>
int main(int argc, char** argv) {
    FILE* fp = fopen("/tmp/myFIFO", "w");
    fprintf(fp, "Hello, world!
");
    fclose(fp);
    return 0;
}

Note that fopen in the above program will block until the FIFO is opened for reading. When it blocks, run this in another terminal:

$ cat /tmp/myFIFO
Hello, world!
$ 

The reason why it blocks is because fopen does not pass O_NONBLOCK to open:

$ strace -P /tmp/myFIFO ./a.out
open("/tmp/myFIFO", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...

Some background on how FIFOs are opened

Read-only, without O_NONBLOCK: open blocks until another process opens the FIFO for writing. This is the behavior when using fopen with mode argument "r".

Write-only, without O_NONBLOCK: open blocks until another process opens the FIFO for reading. This is the behavior when using fopen with mode argument "w".

Read-only, with O_NONBLOCK: open returns immediately.

Write-only, with O_NONBLOCK: open returns an error with errno set to ENXIO unless another process has the FIFO open for reading.

Info from "Advanced Programming in the UNIX Environment" by W. Richard Stevens.

Opening a FIFO for read and write

Opening a FIFO for reading and writing within the same process is also possible with Linux. The Linux FIFO man page states:

Under Linux, opening a FIFO for read and write will succeed both in blocking and nonblocking mode. POSIX leaves this behavior undefined. This can be used to open a FIFO for writing while there are no readers available. A process that uses both ends of the connection in order to communicate with itself should be very careful to avoid deadlocks.

Here's a program which writes to and reads from the same FIFO:

#include <stdio.h>
int main(int argc, const char *argv[]) {
    char buf[100] = {0};
    FILE* fp = fopen("/tmp/myFIFO", "r+");
    fprintf(fp, "Hello, world!
");
    fgets(buf, sizeof(buf), fp);
    printf("%s", buf);
    fclose(fp);
    return 0;
}

It does not block, and returns immediately:

$ gcc fifo.c && ./a.out 
Hello, world!

Note that this is not portable and may not work on operating systems besides Linux.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...