ОБЗОР
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
ОПИСАНИЕ
Вызов read() пытается прочитать count байт из файлового дескриптора fd в буфер, начинающийся по адресу buf.Для файлов, поддерживающих смещения, операция чтения начинается с текущего файлового смещения, и файловое смещение увеличивается на количество прочитанных байт. Если текущее файловое смещение находится за концом файла, то ничего не читается и read() возвращает ноль.
Если значение count равно 0, то read() может обнаружить ошибки, описанные далее. При отсутствии ошибок, или если read() не выполняет проверки, то read() с count равным 0 возвращает 0 и ничего не меняет.
Если значение count больше SSIZE_MAX, то результат не определён.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается количество прочитанных байт (ноль означает конец файла), а позиция в файле увеличивается на это значение. Если количество прочитанных байт меньше, чем количество запрошенных, то это не считается ошибкой: например, это могло произойти из-за того, что прямо сейчас доступно меньшее количество байт (может быть из-за того, что позиция ближе к концу файла, или потому что выполняется чтение из канала или терминала), или потому что работа read() была прервана сигналом. См. также ЗАМЕЧАНИЯ.В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение. В этом случае изменение позиции файла остаётся неопределённым (если это вообще происходило).
ОШИБКИ
- EAGAIN
- Файловый дескриптор fd указывает на файл, не являющийся сокетом и помеченный как неблокирующий ввод/вывод (O_NONBLOCK), а чтение вызовет блокировку. См. open(2) для дальнейшей информации по флагу O_NONBLOCK.
- EAGAIN или EWOULDBLOCK
- Файловый дескриптор fd указывает на сокет и он помечен как неблокирующий (O_NONBLOCK), а чтение вызвало бы блокировку. POSIX.1-2001 позволяет вернуть любую ошибку в этом случае и не требует, чтобы эти константы имели одинаковое значение, поэтому переносимое приложение должно проверять обе эти возможности.
- EBADF
- fd не является допустимым файловым дескриптором или не открыт на чтение.
- EFAULT
- buf находится за пределами доступного вам адресного пространства.
- EINTR
- Вызов был прерван сигналом до того как были прочитаны данные; см. signal(7).
- EINVAL
- fd связан с объектом, не приспособленным для чтения; или файл был открыт с использованием флага O_DIRECT, и адрес, указанный в buf, значение, указанное в count или текущее смещение в файле, имеет недопустимое выравнивание.
- EINVAL
- fd был создан вызовом timerfd_create(2), а в read() был передан неверный размер буфера; подробней см. в timerfd_create(2).
- EIO
- Ошибка ввода/вывода. Например, это происходит когда процесс, находящийся в фоновой группе процессов, пытается выполнить чтение из своего управляющего терминала, и игнорирует или блокирует сигнал SIGTTIN или же его группа процессов осталась без родителя. Это также может случиться, если произошла низкоуровневая ошибка ввода-вывода при чтения с диска или ленты.
- EISDIR
- fd указывает на каталог.
Могут также возникнуть другие ошибки, в зависимости от объекта, связанного с fd. POSIX позволяет системному вызову read(), который был прерван после чтения первого куска запрошенных данных, возвращать -1 (с errno, установленной в EINTR) или количество уже прочитанных байт.
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, 4.3BSD, POSIX.1-2001.ЗАМЕЧАНИЯ
В Linux read() (и похожие системные вызовы) передаст не больше 0x7ffff000 (2 147 479 552) байт, возвращая число байт, переданных на самом деле (это утверждение справедливо как к 32-битным, так и к 64-битным системам).На файловых системах NFS чтение небольших порций данных обновляет отметки времени только в первый раз, последующие вызовы не делают этого. Это вызвано кэшированием атрибутов с клиентской стороны, потому что большинство (если не все) клиентов NFS предоставляют серверу обновлять st_atime (время последнего доступа), а запросы на чтение, которые удовлетворяются из клиентского кэша, не вызывают обновления st_atime, потому что данные не читаются с сервера. Семантика UNIX может быть достигнута запретом кэширования атрибутов на стороне клиента, но в большинстве случаев это увеличит нагрузку на сервер и снизит производительность.
ДЕФЕКТЫ
Согласно POSIX.1-2008/SUSv4 раздел XSI 2.9.7 («Thread Interactions with Regular File Operations»):
- Следующие функции должны выполняться атомарно по отношению друг к другу, чтобы работать с обычными файлами или символическими ссылками так, как указано в POSIX.1-2008: …
Среди перечисленных в программном интерфейсе есть read() и readv(2). И среди действий, которые должны выполняться атомарно между нитями (и процессами), если обновление файлового смещения. Однако в Linux до версии 3.14 это было не так: если два процесса с общим открытым файловым описанием (смотрите open(2)) выполняют read() (или readv(2)) одновременно, то операции ввода-вывода не атомарны при обновлении файлового смещения; в результате прочитанные двумя процессами блоки данных могут (некорректно) перекрываться. Эта ошибка исправлена в Linux 3.14.