Попробуйте передать "w"
в качестве режима для открытия. "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.
person
Tim
schedule
24.07.2012