Scroll to navigation

WRITE(2) Руководство программиста Linux WRITE(2)

ИМЯ

write - запись в файловый дескриптор

ОБЗОР

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

ОПИСАНИЕ

write() пишет до count байт из буфера, на который указывает buf, в файле, на который ссылается файловый дескриптор fd.

Количество записанных байт может быть меньше чем count если, например, недостаточно места на физическом носителе, или исчерпан отведённый лимит ресурса RLIMIT_FSIZE (см. setrlimit(2)), или вызов был прерван обработчиком сигналов после уже записанных меньше чем count байт. (См. также pipe(7).)

В случае с файлами, разрешающими позиционирование (т.е., к которым можно применить lseek(2), например, обычные файлы), запись производится по текущему файловому смещению, а смещение файла увеличивается на реальное число записанных байт. Если файл был открыт с помощью open(2) с аргументом O_APPEND, то перед записью файловое смещение устанавливается в конец файла. Согласование файлового смещения и операции записи выполняются атомарно.

По POSIX требуется, чтобы read(2), который может быть вызван сразу после write(), возвратил новые данные. Заметим, что не все файловые системы соответствуют стандарту POSIX.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

В случае успеха, возвращается количество записанных байт (ноль говорит о том, что ничего записано не было). В случае ошибки, возвращается -1 и значение errno устанавливается соответствующим образом.

Если count равен нулю и fd указывает на обычный файл, то write() может вернуть ошибку, если обнаружена одна из перечисленных ниже ошибок. Если ошибок не обнаружено, то возвращается 0 без каких-либо других последствий. Если count равен нулю и fd указывает на отличный от обычного файл, то результат не определён.

ОШИБКИ

Файловый дескриптор fd указывает на файл, не являющийся сокетом и помеченный как неблокирующий ввод/вывод (O_NONBLOCK), а запись вызовет блокировку.
Файловый дескриптор fd указывает на сокет, который помечен как неблокирующий ввод/вывод (O_NONBLOCK), а запись вызовет блокировку. По POSIX.1-2001 разрешено возвращать ошибку в обоих случая и не требуется, чтобы эти константы имели одно значение, поэтому переносимые приложения должны проверять обе причины.
fd не является правильным файловым дескриптором или не открыт для записи.
Значение fd ссылается на сокет датаграмм, у которого с помощью connect(2) не назначен адрес другой стороны.
buf находится за пределами доступного вам адресного пространства.
Попытка записать в файл, который превышает заданное при реализации ограничение на размер файла или ограничение на размер файла для текущего процесса, или запись в позицию после максимально разрешённого смещения.
Этот вызов был прерван сигналом, перед тем как были записаны какие-либо данные; см signal(7).
fd присоединён к объекту, который не подходит для записи; или файл был открыт с указанием флага O_DIRECT, или неправильно выравнено адрес в buf, значение count или текущее файловое смещение.
Во время изменения индексного дескриптора (inode) возникла низкоуровневая ошибка ввода/вывода.
На устройстве, содержащем файл, на который ссылается fd, нет свободного места.
fd ссылается на конвейер или сокет, у которого закрыто чтение. Когда такое случается, пишущий процесс также получит сигнал SIGPIPE. (Таким образом, возвращаемое значение можно будет увидеть только если программа перехватывает, блокирует или игнорирует этот сигнал.)

В зависимости от объекта, на который указывает fd, могут происходить и другие ошибки.

СООТВЕТСТВИЕ СТАНДАРТАМ

SVr4, 4.3BSD, POSIX.1-2001.

Согласно SVr4, запись может быть прервана в любом месте (с возвратом EINTR), а не только перед тем как будут записаны какие-либо данные.

ЗАМЕЧАНИЯ

Успешный возврат из вызова write() не даёт никаких гарантий, что данные сохранены на диске. Фактически, в некоторых ошибочных реализациях даже нет гарантии, что для данных было зарезервировано место. Единственный способ получить гарантированную запись — вызвать fsync(2) после записи всех данных.

Если write() прерван обработчиком сигналов до начала записи, то вызов возвращает ошибку EINTR; если он прерван после начала записи, то вызов считается успешным, и возвращается число записанных байт.

СМОТРИТЕ ТАКЖЕ

close(2), fcntl(2), fsync(2), ioctl(2), lseek(2), open(2), pwrite(2), read(2), select(2), writev(2), fwrite(3)

2010-08-29 Linux