Попробуйте передать "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
с аргументом режима "r"
.
только для записи, без блоков O_NONBLOCK
: open
, пока другой процесс не откроет FIFO для чтения.Это поведение при использовании fopen
с аргументом режима "w"
.
только для чтения, с O_NONBLOCK
: open
немедленно возвращается.
только для записи, с O_NONBLOCK
: open
возвращает ошибку с errno
, установленным на ENXIO
, если только у другого процесса нет открытого FIFO для чтения.
Информация из "Расширенного программирования в среде UNIX" У. РичардаСтивенс.
Открытие FIFO для чтения и запись
Открытие FIFO для чтения и записи в одном и том же процессе также возможно в Linux.Справочная страница Linux FIFO гласит:
В Linux открытие FIFO для чтения и записи будет успешным как в режиме блокировки, так и в режиме неблокирования.POSIX оставляет это поведение неопределенным.Это может быть использовано для открытия 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.