Читать «UNIX: взаимодействие процессов» онлайн - страница 44
Уильям Ричард Стивенс
int flags;
if ((flags = fcntl(fd, F_GETFL, 0)) < 0) err_sys("F_GETFL error");
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0) err_sys("F_SETFL error");
Будьте аккуратны с программами, которые просто устанавливают требуемый флаг, поскольку при этом сбрасываются все прочие флаги состояния:
/* Неправильное отключение блокировки */
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) err_sys("F_SETFL error");
Таблица 4.1 иллюстрирует действие флага, отключающего блокировку, при открытии очереди и при чтении данных из пустого программного канала или канала FIFO.
Таблица 4.1. Действие флага O_NONBLOCK на именованные и неименованные каналы
Операция | Наличие открытых каналов | Блокировка включена (по умолчанию) | Флаг O_NONBLOCK установлен |
---|---|---|---|
Открытие (open) FIFO только для чтения | FIFO открыт на запись | Возвращается код успешного завершения операции | Возвращается код успешного завершения операции |
Открытие (open) FIFO только для чтения | FIFO не открыт на запись | Процесс блокируется, пока FIFO не будет открыт на запись | Возвращается код успешного завершения операции |
Открытие (open) FIFO только для записи | FIFO открыт на чтение | Возвращает код успешного завершения операции | Возвращает код успешного завершения операции |
Открытие (open) FIFO только для записи | FIFO не открыт на чтение | Блокируется до тех пор, пока FIFO не будет открыт на чтение | Возвращает ошибку с кодом ENXIO |
Чтение (read) из пустого программного канала или FIFO | Программный канал или FIFO открыт на запись | Блокируется до тех пор, пока в программный канал или FIFO не будут помещены данные или они не будут закрыты всеми процессами, которыми они были открыты на запись | Возвращает ошибку с кодом EAGAIN |
Чтение (read) из пустого программного канала или FIFO | Программный канал или FIFO не открыт на запись | read возвращает 0 (конец файла) | read возвращает 0 (конец файла) |
Запись (write) в программный канал или FIFO | Программный канал или FIFO открыт на чтение | (См. в тексте) | (См. в тексте) |
Запись (write) в программный канал или FIFO | Программный канал или FIFO не открыт на чтение | Программному потоку посылается сигнал SIGPIPE | Программному потоку посылается сигнал SIGPIPE |
Запомните несколько дополнительных правил, действующих при чтении и записи данных в программные каналы и FIFO.
■ При попытке считать больше данных, чем в данный момент содержится в программном канале или FIFO, возвращается только имеющийся объем данных. Нужно предусмотреть обработку ситуации, в которой функция read возвращает меньше данных, чем было запрошено.