table of contents
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 указывает на отличный от обычного файл, то результат не определён.
ОШИБКИ¶
- EAGAIN
- Файловый дескриптор fd указывает на файл, не являющийся сокетом и помеченный как неблокирующий ввод/вывод (O_NONBLOCK), а запись вызовет блокировку.
- EAGAIN или EWOULDBLOCK
- Файловый дескриптор fd указывает на сокет, который помечен как неблокирующий ввод/вывод (O_NONBLOCK), а запись вызовет блокировку. По POSIX.1-2001 разрешено возвращать ошибку в обоих случая и не требуется, чтобы эти константы имели одно значение, поэтому переносимые приложения должны проверять обе причины.
- EBADF
- fd не является правильным файловым дескриптором или не открыт для записи.
- EDESTADDRREQ
- Значение fd ссылается на сокет датаграмм, у которого с помощью connect(2) не назначен адрес другой стороны.
- EFAULT
- buf находится за пределами доступного вам адресного пространства.
- EFBIG
- Попытка записать в файл, который превышает заданное при реализации ограничение на размер файла или ограничение на размер файла для текущего процесса, или запись в позицию после максимально разрешённого смещения.
- EINTR
- Этот вызов был прерван сигналом, перед тем как были записаны какие-либо данные; см signal(7).
- EINVAL
- fd присоединён к объекту, который не подходит для записи; или файл был открыт с указанием флага O_DIRECT, или неправильно выравнено адрес в buf, значение count или текущее файловое смещение.
- EIO
- Во время изменения индексного дескриптора (inode) возникла низкоуровневая ошибка ввода/вывода.
- ENOSPC
- На устройстве, содержащем файл, на который ссылается fd, нет свободного места.
- EPIPE
- 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 |