Linux
2018-02-02
man-pages-ru
Russian man pages from the Linux Documentation Project
manpages-dev
Manual pages about using GNU/Linux for development
man-pages
Linux kernel and C library user-space interface documentation
ИМЯ
read - читает из файлового дескриптора
ОБЗОР
#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 и ничего не меняет.
В соответствие с POSIX.1, если count больше SSIZE_MAX, то результат зависит от реализации; смотрите ЗАМЕЧАНИЯ по верхнему пределу в Linux.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается количество прочитанных байт (ноль означает конец файла), а позиция в файле увеличивается на это значение. Если количество прочитанных байт меньше, чем количество запрошенных, то это не считается ошибкой: например, это могло произойти из-за того, что прямо сейчас доступно меньшее количество байт (может быть из-за того, что позиция ближе к концу файла, или потому что выполняется чтение из канала или терминала), или потому что работа 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, или же его группа процессов осталась без родителя. Это также может случиться, если произошла низкоуровневая ошибка ввода-вывода при чтении с диска или ленты. Также EIO может возникать у сетевых файловых систем, когда консультативная блокировка была убрана у дескриптора файла и потеряна. Подробности смотрите в абзаце Потерянные блокировки в fcntl(2). |
EISDIR | fd указывает на каталог. |
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, 4.3BSD, POSIX.1-2001.
ЗАМЕЧАНИЯ
Типы данных size_t и ssize_t представляющие собой, соответственно, беззнаковый и знаковый целочисленные типы, определены в POSIX.1.
В 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.
СМОТРИТЕ ТАКЖЕ
REFERENCED BY
epoll_ctl(2), eventfd(2), fanotify_init(2), fcntl(2), getrandom(2), inotify_add_watch(2), ioctl_tty(2), open(2), perf_event_open(2), perfmonctl(2), pipe(2), prctl(2), pread(2), ptrace(2), readahead(2), readv(2), recv(2), seccomp(2), select(2), select_tut(2), sendfile(2), setpgid(2), signalfd(2), socket(2), socketpair(2), timerfd_create(2), userfaultfd(2), write(2), aio_error(3), aio_read(3), aio_return(3), dbopen(3), fgetc(3), fread(3), getline(3), gets(3), mkfifo(3), mpool(3), readdir(3), rtime(3), stdin(3), stdio(3), termios(3), xdr(3), dsp56k(4), fuse(4), lirc(4), null(4), random(4), rtc(4), st(4), tty_ioctl(4), proc(5), aio(7), cpuset(7), epoll(7), fanotify(7), inotify(7), pipe(7), signal(7), socket(7), spufs(7), x25(7), inode(7), strace(1), xfs_io(8), xfsctl(3), atread(3), rmt-dump(8), hylafax-log(5), cpuset(4), firestring_estr_read(3), iv_fd_pump(3), libssh2_sftp_read(3), tar_append_file(3), tar_block_read(3), mknod(2), stat(2), grep(1), readv(3p), nfslogsum(8), telnet-probe(1), pv(1), since(1), tthsum(1), msocket(2viewos), pthread_cancel(3), rmt(1), hylafax-log(5f), rscsi(1), anysurrect-plugins(3), vsock(7), netsniff-ng(8), ermt(1), ast(3ast), libkeccak_generalised_sum_fd(3), libkeccak_keccaksum_fd(3), libkeccak_rawshakesum_fd(3), libkeccak_sha3sum_fd(3), libkeccak_shakesum_fd(3), fzopen(3), srmt(1), io_uring_enter(2), rmtclose(3), rmtioctl(3), rmtopen(3), rmtread(3), rmtseek(3), rmtwrite(3)