Ответ 1
Попробуйте передать "w"
в качестве режима fopen. "rw"
не является аргументом действительного режима для fopen
, и даже если бы это было так, вы, вероятно, не хотели бы читать и писать в FIFO в том же процессе (хотя это возможно, см. ниже).
В стороне, аргумент правильного режима для открытия файла для чтения и записи - это "r+"
или "w+"
(см. Ответы на этот вопрос для различий).
Эта программа будет правильно записывать в FIFO:
#include <stdio.h>
int main(int argc, char** argv) {
FILE* fp = fopen("/tmp/myFIFO", "w");
fprintf(fp, "Hello, world!\n");
fclose(fp);
return 0;
}
Обратите внимание, что fopen
в указанной выше программе будет блокироваться до тех пор, пока FIFO не откроется для чтения. Когда он блокируется, запустите его в другом терминале:
$ cat /tmp/myFIFO
Hello, world!
$
Причина, по которой он блокируется, состоит в том, что fopen
не передает O_NONBLOCK
в open
:
$ strace -P /tmp/myFIFO ./a.out
open("/tmp/myFIFO", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...
Некоторые сведения о том, как открываются FIFO
Только для чтения, без O_NONBLOCK
: open
блокируется до тех пор, пока другой процесс не откроет FIFO для записи. Это поведение при использовании fopen
с аргументом mode "r"
.
Только запись, без O_NONBLOCK
: open
блокирует, пока другой процесс не откроет FIFO для чтения. Это поведение при использовании fopen
с аргументом mode "w"
.
Только для чтения, с O_NONBLOCK
: open
немедленно возвращается.
Только для записи с O_NONBLOCK
: open
возвращает ошибку с errno
, установленную в ENXIO
, если другой процесс не имеет открытого FIFO для чтения.
Информация из "Расширенного программирования в среде UNIX" У. Ричарда Стивенса.
Открытие FIFO для чтения и записи
Открытие FIFO для чтения и записи в рамках одного процесса также возможно с Linux. В странице руководства FIFO Linux указано:
В Linux, открытие FIFO для чтения и записи будет успешным как в блокирующий и неблокирующий режим. POSIX оставляет это поведение undefined. Это можно использовать для открытия FIFO для записи, пока нет читателей доступный. Процесс, который использует оба конца соединения для того, чтобы общаться с собой должно быть очень осторожным, чтобы избежать тупиков.
Здесь программа, которая записывает и считывает из одного и того же 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!\n");
fgets(buf, sizeof(buf), fp);
printf("%s", buf);
fclose(fp);
return 0;
}
Он не блокируется и немедленно возвращается:
$ gcc fifo.c && ./a.out
Hello, world!
Обратите внимание, что это не переносимо и может не работать в операционных системах, кроме Linux.