readcond()

Считать данные с оконечного устройства

Прототип:

#include <unistd.h>
int readcond( int fd,
void *buf,
int n,
int min,
int time,
int timeout );

Аргументы:

fd
Дескриптор файла, связанный с оконечным устройством, с которого вы хотите читать.
buf
Указатель на буфер, в который readcond() может поместить данные.
n
Максимальное количество байтов для чтения.
min
time
timeout
При использовании в режиме RAW эти аргументы переопределяют поведение членов структуры MIN и TIME termios.

Библиотека:

libc

Описание:

Функция readcond() считывает до n байтов данных с оконечного устройства fd в буфер, на который указывает buf.

Эта функция является альтернативой функции read() для оконечных устройств, предоставляя дополнительные аргументы для операций чтения по времени. Эти дополнительные аргументы можно использовать для минимизации накладных расходов при работе с оконечными устройствами.

Три аргумента (min, time, и timeout),при использовании на оконечных устройствах в режиме RAW переопределяют поведение полей MIN и TIME только что определенной структуры termios (только на время вызова). Структура termios также определяет forwarding символ (в c_cc[VFWD]), который можно использовать для обхода min, time и timeout.

Обычный случай простого чтения приложением блокируется до тех пор, пока не будет доступен хотя бы один символ.

condread.jpg
Рисунок 1. Условия, удовлетворяющие запросу на ввод

В случае, если указано несколько условий, чтение будет выполнено, когда будет выполнено любое из них.

MIN

Квалификатор MIN полезен, когда приложению известно количество символов, которое оно ожидает получить.

Любой протокол, который знает количество символов в наборе данных, может использовать MIN чтобы дождаться прибытия всего набора. Это значительно упрощает IPC и планирование процессов. MIN часто используется вместе с TIME или TIMEOUT. MIN является частью стандарта POSIX.

TIME

Квалификатор TIME полезен, когда приложение получает потоковые данные и желает получать уведомления, когда данные останавливаются или приостанавливаются. Время паузы составляет 1/10 секунды. TIME является частью стандарта POSIX.

TIMEOUT

Квалификатор TIMEOUT полезен, когда приложение знает, как долго ему следует ждать данных до истечения времени ожидания. Тайм-аут составляет «1/10» секунды.

Любой протокол, который знает количество символов в наборе данных, который он ожидает получить, может использовать TIMEOUT. Благодаря этому, в сочетании со скоростью передачи, можно предположить, когда данные должны быть доступны. Квалификатор действует как таймер для обнаружения недостающих символов. Его также можно использовать в интерактивных программах с вводом пользователя для отложенного чтения, если в течение заданного времени нет ответа.

TIMEOUT является расширением ЗОСРВ «Нейтрино» и не является частью стандарта POSIX.

FORWARD

Квалификатор FORWARD полезен, когда протокол имеет специальный разделительный символ. Например, протокол PPP, используемый для TCP/IP по последовательному каналу связи, начинает и заканчивает свои пакеты с помощью разделяюещего символа. При использовании в сочетании с TIMEOUT, символ FORWARD может значительно повысить эффективность реализации протокола. Процесс протокола будет получать полные наборы данных, а не символ за символом. В случае пропуска разделительного символа, для быстрого восстановления можно использовать TIMEOUT или TIME.

Это значительно сводит к минимуму объем работы IPC для ОС и приводит к гораздо более низкому использованию процессора при заданной скорости передачи данных TCP/IP. Интересно отметить, что PPP не содержит счетчика символов для своих фреймов. Без разделяющего символа, пришлось бы читать данные по одному символу за раз.

FORWARD является расширением ЗОСРВ «Нейтрино» и не явлется частью стандарта POSIX.

Чтобы использовать символ FORWARD, необходимо установить символ VFWD в поле c_cc структуры termios:

/* PPP forwarding character */
const char fwd_char = 0x7e;
#include <termios.h>
...
int fd;
struct termios termio;
...
tcgetattr( fd, &termio );
termio.c_cc[VFWD] = fwd_char;
tcsetattr( fd, TCSANOW, &termio );

Следующая таблица объясняет взаимодействие min, time, и timeout:

min time timeout Описание
0 0 0 Немедленно возвращает столько байтов, сколько доступно в данный момент (до n байтов).
M 0 0 Возвращает до n байтов, только если доступно не менее M байтов.
0 T 0 Возвращает до n байтов, если доступен хотя бы один байт или истекло время T * 0.1 сек.
M T 0 Возвращает до n байтов, если доступны либо M байтов, или был получен хотя бы один байт, а время между получением двух соседних символов превышает T * 0.1 сек.
0 0 t Для внутреннего использования.
M 0 t Возвращает до n байтов, когда истекло t * 0.1 сек, или доступно M байтов.
0 T t Для внутреннего использования.
M T t Возвращает до n байтов, когда доступны M байтов, или истекло время t * 0.1, а символы не получены, или был получен хотя бы один байт, а время между получением двух соседних символов превышает T * 0.1 сек.

Обратите внимание, что когда timeout равен нулю, поведение min и time точно такое же, как поведение параметров MIN и TIME для контролирующей структуры termios. Таким образом, readcond() может использоваться как более высокоскоростная альтернатива последовательным вызовам tcgetattr(), tcsetattr() и read() при работе с терминалом RAW ввода/вывода.

Случай (M, 0, t) полезен для протоколов связи, которые не могут позволить себе блокироваться в ожидании данных, которые могут никогда не поступить.

Случай (M, T, ) предназначен для того, чтобы функция readcond() могла возвращаться при завершении пакета данных (как в случае (M, T, 0)) , но также и завершиться, если в течение некоторого периода времени пакет не был обнаружен.

Возвращаемое значение:

Количество прочитанных байтов.

Если возникла ошибка функция возвращает -1, код ошибки записывается в errno.

Коды ошибок:

EAGAIN
Флаг O_NONBLOCK установлен в этом fd, и процесс был бы заблокирован при попытке выполнить эту операцию.
EBADF
Аргумент fd недействителен или файл не открыт для чтения.
EINTR
Вызов readcond() был прерван сигнализируемым процессом.
EIO
Этот процесс в настоящее время не может читать данные из этого fd.
ENOSYS
Эта функция не поддерживается для этого fd.

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

errno, read(), tcgetattr(), tcsetattr(), struct termios




Предыдущий раздел: Описание API системной библиотеки