Системные вызовы linux write

ОПИСАНИЕ

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

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

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

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

В соответствие с POSIX.1, если count больше SSIZE_MAX, то результат зависит от реализации; смотрите ЗАМЕЧАНИЯ по верхнему пределу в Linux.

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

On success, the number of bytes written is returned. On error, -1 is returned, and errno is set to indicate the error.

Заметим, что при успешном выполнении write() может передать меньше чем count байт. Такая частичная запись может возникать по нескольким причинам; например, из-за недостаточного количества места на диске, на который пишутся все запрошенные байты или из-за прерывания блокировки write() сокета, канала или подобного обработчиком сигнала после частичной передачи, но до того, как были переданы все запрашиваемый байты. При даже частичной записи вызывающий может запустить другой вызов write() для передачи оставшихся байт. Последующий вызов или передаст остальные байты, или может завершиться ошибкой (например, если переполнен диск).

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

ОШИБКИ

EAGAIN Файловый дескриптор fd указывает на файл, не являющийся сокетом и помеченный как неблокирующий ввод/вывод (O_NONBLOCK), а запись вызовет блокировку. См. open(2) для дальнейшей информации по флагу O_NONBLOCK. EAGAIN или EWOULDBLOCK Файловый дескриптор fd указывает на сокет, который помечен как неблокирующий ввод/вывод (O_NONBLOCK), а запись вызовет блокировку. По POSIX.1-2001 разрешено возвращать ошибку в обоих случая и не требуется, чтобы эти константы имели одно значение, поэтому переносимые приложения должны проверять обе причины. EBADF Значение fd не является правильным файловым дескриптором или он не открыт для записи. EDESTADDRREQ Значение fd ссылается на сокет дейтаграмм, у которого с помощью connect(2) не назначен адрес другой стороны. EDQUOT Исчерпана пользовательская квота на дисковые блоки файловой системы с файлом, на который указывает fd. EFAULT buf находится за пределами доступного вам адресного пространства. EFBIG Попытка записать в файл, который превышает заданное при реализации ограничение на размер файла или ограничение на размер файла для текущего процесса, или запись в позицию после максимально разрешённого смещения. EINTR Этот вызов был прерван сигналом, перед тем как были записаны какие-либо данные; см signal(7). EINVAL fd присоединён к объекту, который не подходит для записи; или файл был открыт с указанием флага O_DIRECT, или неправильно выравнено адрес в buf, значение count или файловое смещение. EIO Во время изменения иноды возникла низкоуровневая ошибка ввода/вывода. Эта ошибка может относится к отложенным (write-back) данным предыдущего вызова write(), который выполнялся с другим файловым дескриптором для этого же файла. Начиная с Linux 4.13 ошибки отложенных данных поступают с обещанием, что о них может быть сообщено следующему вызову. Результаты запросов write() будут переданы последующему fsync(2) (независимо от того, сообщалось ли об этом write()). Также EIO может возникать у сетевых файловых систем, когда консультативная блокировка была убрана у дескриптора файла и потеряна. Подробности смотрите в абзаце Потерянные блокировки в fcntl(2). ENOSPC На устройстве, содержащем файл, на который ссылается fd, нет свободного места. EPERM Выполнение операции предотвращено опечатыванием (file seal); смотрите fcntl(2). EPIPE fd ссылается на конвейер или сокет, у которого закрыто чтение. Когда такое случается, пишущий процесс также получит сигнал SIGPIPE. (Таким образом, возвращаемое значение можно будет увидеть только если программа перехватывает, блокирует или игнорирует этот сигнал.)

Читайте также:  Установка линукс разбивка дисков

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

СТАНДАРТЫ

HISTORY

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

ЗАМЕЧАНИЯ

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

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

В Linux write() (и похожие системные вызовы) передаст не больше 0x7ffff000 (2 147 479 552) байт, возвращая число байт, переданных на самом деле (это утверждение справедливо как к 32-битным, так и к 64-битным системам).

Возвращаемое значение ошибки при выполнении write() прямого ввода-вывода не означает ошибки записи целиком. Данные могут быть записаны частично, а по смещению в файле, на котором write() остановился, данные должны считаться некорректными.

ДЕФЕКТЫ

В соответствие с POSIX.1-2008/SUSv4 раздел XSI 2.9.7 («Thread Interactions with Regular File Operations»):

Следующие функции должны выполняться атомарно по отношению друг к другу, чтобы работать с обычными файлами или символическими ссылками так, как указано в POSIX.1-2008: …

Among the APIs subsequently listed are write() and writev(2). And among the effects that should be atomic across threads (and processes) are updates of the file offset. However, before Linux 3.14, this was not the case: if two processes that share an open file description (see open(2)) perform a write() (or writev(2)) at the same time, then the I/O operations were not atomic with respect to updating the file offset, with the result that the blocks of data output by the two processes might (incorrectly) overlap. This problem was fixed in Linux 3.14.

Читайте также:  Как удалить содержимое директории linux

СМ. ТАКЖЕ

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Azamat Hackimov и Yuri Kozlov

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

Powered by archmanweb, using mandoc for the conversion of manual pages.

The website is available under the terms of the GPL-3.0 license, except for the contents of the manual pages, which have their own license specified in the corresponding Arch Linux package.

Источник

Системные вызовы linux write

#include
#include
#include
ssize_t write (int d const void *buf size_t nbytes);
ssize_t pwrite (int d const void *buf size_t nbytes off_t offset);
ssize_t writev (int d const struct iovec *iov int iovcnt);
ssize_t pwritev (int d const struct iovec *iov int iovcnt off_t offset);

DESCRIPTION

The write ();
system call attempts to write Fa nbytes of data to the object referenced by the descriptor Fa d from the buffer pointed to by Fa buf . The writev ();
system call performs the same action, but gathers the output data from the Fa iovcnt buffers specified by the members of the Fa iov array: iov[0], iov[1], . iov[iovcnt-1]. The pwrite ();
and pwritev ();
system calls perform the same functions, but write to the specified position in the file without modifying the file pointer.

For writev ();
and pwritev (,);
the Fa iovec structure is defined as:

Each Fa iovec entry specifies the base address and length of an area in memory from which data should be written. The writev ();
system call will always write a complete area before proceeding to the next.

On objects capable of seeking, the write ();
starts at a position given by the pointer associated with Fa d , see lseek(2). Upon return from write (,);
the pointer is incremented by the number of bytes which were written.

Objects that are not capable of seeking always write from the current position. The value of the pointer associated with such an object is undefined.

If the real user is not the super-user, then write ();
clears the set-user-id bit on a file. This prevents penetration of system security by a user who «captures» a writable set-user-id file owned by the super-user.

When using non-blocking I/O on objects such as sockets that are subject to flow control, write ();
and writev ();
may write fewer bytes than requested; the return value must be noted, and the remainder of the operation should be retried when possible.

RETURN VALUES

Upon successful completion the number of bytes which were written is returned. Otherwise a -1 is returned and the global variable errno is set to indicate the error.

Читайте также:  Astra linux зависает при установке

ERRORS

The write (,);
writev (,);
pwrite ();
and pwritev ();
system calls will fail and the file pointer will remain unchanged if:

Bq Er EBADF The Fa d argument is not a valid descriptor open for writing. Bq Er EPIPE An attempt is made to write to a pipe that is not open for reading by any process. Bq Er EPIPE An attempt is made to write to a socket of type SOCK_STREAM that is not connected to a peer socket. Bq Er EFBIG An attempt was made to write a file that exceeds the process’s file size limit or the maximum file size. Bq Er EFAULT Part of Fa iov or data to be written to the file points outside the process’s allocated address space. Bq Er EINVAL The pointer associated with Fa d was negative. Bq Er ENOSPC There is no free space remaining on the file system containing the file. Bq Er EDQUOT The user’s quota of disk blocks on the file system containing the file has been exhausted. Bq Er EIO An I/O error occurred while reading from or writing to the file system. Bq Er EINTR A signal interrupted the write before it could be completed. Bq Er EAGAIN The file was marked for non-blocking I/O, and no data could be written immediately. Bq Er EROFS An attempt was made to write over a disk label area at the beginning of a slice. Use disklabel(8) — W to enable writing on the disk label area. Bq Er EINVAL The value Fa nbytes is greater than INT_MAX

In addition, writev ();
and pwritev ();
may return one of the following errors:

Bq Er EDESTADDRREQ The destination is no longer available when writing to a UNIX domain datagram socket on which connect(2) had been used to set a destination address. Bq Er EINVAL The Fa iovcnt argument was less than or equal to 0, or greater than IOV_MAX Bq Er EINVAL One of the Fa iov_len values in the Fa iov array was negative. Bq Er EINVAL The sum of the Fa iov_len values in the Fa iov array overflowed a 32-bit integer. Bq Er ENOBUFS The mbuf pool has been completely exhausted when writing to a socket.

The pwrite ();
and pwritev ();
system calls may also return the following errors:

Bq Er EINVAL The Fa offset value was negative. Bq Er ESPIPE The file descriptor is associated with a pipe, socket, or FIFO.

SEE ALSO


STANDARDS

The write ();
system call is expected to conform to St -p1003.1-90 . The writev ();
and pwrite ();
system calls are expected to conform to St -xpg4.2 .

HISTORY

The pwritev ();
system call appeared in Fx 6.0 . The pwrite ();
function appeared in AT&T System V.4 . The writev ();
system call appeared in BSD 4.2 The write ();
function appeared in AT&T System v6 .

Источник

Оцените статью
Adblock
detector