у меня есть следующий бит кода C, который читает из канала и затем должен заблокироваться, но он никогда блоки
int pipe_fd;
int res;
int open_mode = O_RDONLY;
char buf[100];
int bytes_read = 0;
memset (buf, '\0', sizeof(buf));
pipe_fd = open(FIFO_NAME, open_mode);
if (access(FIFO_NAME, F_OK) == -1)
{
res = mkfifo(FIFO_NAME, 0777);
if (res != 0)
{
fprintf (stderr, "Could not create fifo %s\n", FIFO_NAME);
exit (EXIT_FAILURE);
}
}
for(;;)
{
do
{
res = read(pipe_fd, buf, sizeof(buf));
bytes_read += res;
}while (res > 0);
// process data then go back and block
............
}
Это отправляется простой буфер некоторым кодом в сценарии удара как этот './test 1'
#!/bin/bash
pipe=/tmp/pipe
if [[ ! -p $pipe ]]; then
echo "Reader not running"
exit 1
fi
if [[ "$1" ]]; then
echo "some string" >$pipe
else
echo "q" >$pipe
fi
Я запускаю программу кода C в gdb, и первоначально это действительно блокируется на чтении, но как только я звоню, удар не пишут сценарий кода C больше блоки, это действительно успешно считывает данные с буфера и затем каждый раз, когда это читает существует 0-байтовое чтение, таким образом, не уверенное почему его больше блокирование. 'Некоторая строка' данные правильно получена в другой стороне.
Мне просто нужен он для нахождения, там ожидая данных, обрабатывают его и затем возвращаются и ожидают больше
Я запускаю программу на C-коде в gdb и сначала она блокируется при чтении, но как только я вызываю bash-скрипт, C-код больше не блокируется, он успешно считывает данные из буфера, а затем при каждом чтении считывается 0 байт, так что не уверен, почему он больше не блокируется. Данные 'some string' правильно получены на другой стороне.
0
означает EOF. FIFO может быть прочитан или записан только тогда, когда есть процессы, подключенные к нему как для чтения, так и для записи. Когда писателей больше нет (ваши shell-скрипты завершены), читатели уведомляются об этом через read()
, возвращающую EOF.
FIFO ведут себя таким образом, чтобы быть совместимыми с логикой shell pipe, например:
$ mkfifo ./tmp1
$ cat < input > ./tmp1 &
$ cat < ./tmp1 > /dev/null
Если read()
не вернет EOF, то второй cat
будет блокироваться вечно.
Мне нужно, чтобы он просто сидел и ждал данных, обрабатывал их, а затем возвращался и ждал еще
В вашей программе на C вы должны повторно открыть()
FIFO после того, как read()
вернул EOF в первый раз.
P.S. Нашел неплохую сводку по FIFO для вас. Посмотрите таблицу на второй странице.
ваш сценарий bash закрывает канал, поэтому C получает условие "eof"