Как обнаружить сломанную трубу на входе?
У меня есть программа, которая подает данные на стандартный ввод через канал; someapp | myprogram
Я надеялся, что read
возвращает отрицательное значение на сломанной трубе; кажется, это не так. Основной цикл выглядит примерно так:
int rdsum = 0;
int rdsize = 0;
do
{
rdsize = read(STDIN_FILENO, buf, BUFSIZE);
if(rdsize > 0)
{
//[operations on the buffer]
rdsum += rdsize;
}
else if(rdsize == 0)
{
usleep(100000);
}
else return 0;
}
while(rdsum < blocksize);
на return 0;
, программа направляется прямо к выходу. Или, по крайней мере, если бы это случилось...
Если someapp
в someapp | myprogram
заканчивается или убит, myprog
еще жив, появляется в ps
список. Как правильно определить, что приложение для кормления умерло / закончилось / было убито, и выйти из него в таком случае?
1 ответ
От man 2 read
:
В случае успеха возвращается число прочитанных байтов (ноль указывает на конец файла)
Таким образом, правильное поведение для вас будет возвращаться на rdsize == 0
,
Возвращаемое значение -1
для ошибок (или errno == EAGAIN
только если дескриптор файла установлен на неблокирование) и когда это произойдет, вам следует
perror("read"); // print an error message
abort(); // abort the process or do other error handling
Как это:
int rdsum = 0;
int rdsize = 0;
do
{
rdsize = read(STDIN_FILENO, buf, BUFSIZE);
if(rdsize > 0)
{
//[operations on the buffer]
rdsum += rdsize;
}
else if(rdsize == 0)
{
return 0;
}
else if (errno == EAGAIN || errno == EWOULDBLOCK) { // #include <errno.h>
usleep(100000);
} else {
perror("read"); // print an error message
abort(); // exit and core dump
}
}
while(rdsum < blocksize);