Вы действительно должны проверять возвращаемое значение в вызовах функций на наличие ошибок, особенно mkfifo()
и open()
.
Ваш звонок на wait()
вызовет проблемы в его текущем местоположении. Открытие FIFO для чтения обычно блокирует, пока какой-то другой процесс не откроет тот же FIFO для записи, и наоборот 1 . Родитель ожидает завершения дочернего процесса, а ребенок ожидает, пока процесс чтения, то есть родитель, подключится к FIFO.
1 - см. Примечание на open()
ниже относительно использования O_NONBLOCK
с FIFO
Перемещение вызова wait()
непосредственно перед выходом из родительского процесса вместе с изменением режима вызова на mkfifo()
на 0666
, кажется, решает некоторые из ваших непосредственных проблем.
Хорошей практикой также является удаление FIFO, когда вы закончите с ним.
unlink("myfifo");
Из документации по функциям open()
в стандарте IEEE 1003.1-2004 :
При открытии FIFO с установленным O_RDONLY или O_WRONLY:
Если установлено O_NONBLOCK, open () только для чтения должен возвращаться без задержки. Функция open () только для записи должна возвращать ошибку, если ни один процесс не имеет файла, открытого для чтения.
Если O_NONBLOCK очищен, метод open () только для чтения должен блокировать вызывающий поток, пока поток не откроет файл для записи. Функция open () только для записи должна блокировать вызывающий поток, пока поток не откроет файл для чтения.
Следующий пример представляет собой комбинацию кода в исходном вопросе и страницы FIFO Руководства Beej по Unix IPC :
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#define FIFO_NAME "myfifo"
int main(void)
{
char buf[256];
int num, fd;
pid_t pid;
if (mkfifo(FIFO_NAME, 0666) < 0)
perror("mkfifo");
pid = fork();
if (pid == 0)
{
printf("child - waiting for readers...\n");
if ((fd = open(FIFO_NAME, O_WRONLY)) < 0)
perror("child - open");
printf("child - got a reader -- type some stuff\n");
while (fgets(buf, sizeof(buf), stdin), !feof(stdin))
{
if ((num = write(fd, buf, strlen(buf))) < 0)
perror("child - write");
else
printf("child - wrote %d bytes\n", num);
}
close(fd);
exit(0);
}
else
{
printf("parent - waiting for writers...\n");
if ((fd = open(FIFO_NAME, O_RDONLY)) < 0)
perror("parent - open");
printf("parent - got a writer\n");
do
{
if ((num = read(fd, buf, sizeof(buf))) < 0)
perror("parent - read");
else
{
buf[num] = '\0';
printf("parent - read %d bytes: \"%s\"\n", num, buf);
}
} while (num > 0);
close(fd);
wait(0);
}
unlink(FIFO_NAME);
return 0;
}
Этот пример был протестирован в Linux. Нажмите Ctrl - D , чтобы завершить программу.