Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   write.3p    ( 3 )

написать в файл (write on a file)

Обоснование (Rationale)

See also the RATIONALE section in read().

An attempt to write to a pipe or FIFO has several major characteristics:

* Atomic/non-atomic: A write is atomic if the whole amount written in one operation is not interleaved with data from any other process. This is useful when there are multiple writers sending data to a single reader. Applications need to know how large a write request can be expected to be performed atomically. This maximum is called {PIPE_BUF}. This volume of POSIX.1‐2017 does not say whether write requests for more than {PIPE_BUF} bytes are atomic, but requires that writes of {PIPE_BUF} or fewer bytes shall be atomic.

* Blocking/immediate: Blocking is only possible with O_NONBLOCK clear. If there is enough space for all the data requested to be written immediately, the implementation should do so. Otherwise, the calling thread may block; that is, pause until enough space is available for writing. The effective size of a pipe or FIFO (the maximum amount that can be written in one operation without blocking) may vary dynamically, depending on the implementation, so it is not possible to specify a fixed value for it.

* Complete/partial/deferred: A write request:

int fildes; size_t nbyte; ssize_t ret; char *buf;

ret = write(fildes, buf, nbyte);

may return:

Complete ret=nbyte

Partial ret<nbyte

This shall never happen if nbyte≤{PIPE_BUF}. If it does happen (with nbyte>{PIPE_BUF}), this volume of POSIX.1‐2017 does not guarantee atomicity, even if ret≤{PIPE_BUF}, because atomicity is guaranteed according to the amount requested, not the amount written.

Deferred: ret=-1, errno=[EAGAIN]

This error indicates that a later request may succeed. It does not indicate that it shall succeed, even if nbyte≤{PIPE_BUF}, because if no process reads from the pipe or FIFO, the write never succeeds. An application could usefully count the number of times [EAGAIN] is caused by a particular value of nbyte>{PIPE_BUF} and perhaps do later writes with a smaller value, on the assumption that the effective size of the pipe may have decreased.

Partial and deferred writes are only possible with O_NONBLOCK set.

The relations of these properties are shown in the following tables:

┌───────────────────────────────────────────────────────────────────────┐ │ Write to a Pipe or FIFO with O_NONBLOCK clear │ ├─────────────────────┬─────────────────────────────────────────────────┤ │Immediately Writable:None Some nbyte │ ├─────────────────────┼─────────────────────────────────────────────────┤ │nbyte≤{PIPE_BUF} │Atomic blocking Atomic blocking Atomic immediate │ │ │nbyte nbyte nbyte │ ├─────────────────────┼─────────────────────────────────────────────────┤ │nbyte>{PIPE_BUF} │Blocking nbyte Blocking nbyte Blocking nbyte │ └─────────────────────┴─────────────────────────────────────────────────┘ If the O_NONBLOCK flag is clear, a write request shall block if the amount writable immediately is less than that requested. If the flag is set (by fcntl()), a write request shall never block.

┌───────────────────────────────────────────────────────────────┐ │ Write to a Pipe or FIFO with O_NONBLOCK set │ ├─────────────────────┬─────────────────────────────────────────┤ │Immediately Writable:None Some nbyte │ ├─────────────────────┼─────────────────────────────────────────┤ │nbyte≤{PIPE_BUF} │-1, [EAGAIN] -1, [EAGAIN] Atomic nbyte │ ├─────────────────────┼─────────────────────────────────────────┤ │nbyte>{PIPE_BUF} │-1, [EAGAIN] <nbyte or -1, ≤nbyte or -1, │ │ │ [EAGAIN] [EAGAIN] │ └─────────────────────┴─────────────────────────────────────────┘ There is no exception regarding partial writes when O_NONBLOCK is set. With the exception of writing to an empty pipe, this volume of POSIX.1‐2017 does not specify exactly when a partial write is performed since that would require specifying internal details of the implementation. Every application should be prepared to handle partial writes when O_NONBLOCK is set and the requested amount is greater than {PIPE_BUF}, just as every application should be prepared to handle partial writes on other kinds of file descriptors.

The intent of forcing writing at least one byte if any can be written is to assure that each write makes progress if there is any room in the pipe. If the pipe is empty, {PIPE_BUF} bytes must be written; if not, at least some progress must have been made.

Where this volume of POSIX.1‐2017 requires -1 to be returned and errno set to [EAGAIN], most historical implementations return zero (with the O_NDELAY flag set, which is the historical predecessor of O_NONBLOCK, but is not itself in this volume of POSIX.1‐2017). The error indications in this volume of POSIX.1‐2017 were chosen so that an application can distinguish these cases from end-of-file. While write() cannot receive an indication of end-of-file, read() can, and the two functions have similar return values. Also, some existing systems (for example, Eighth Edition) permit a write of zero bytes to mean that the reader should get an end-of-file indication; for those systems, a return value of zero from write() indicates a successful write of an end-of-file indication.

Implementations are allowed, but not required, to perform error checking for write() requests of zero bytes.

The concept of a {PIPE_MAX} limit (indicating the maximum number of bytes that can be written to a pipe in a single operation) was considered, but rejected, because this concept would unnecessarily limit application writing.

See also the discussion of O_NONBLOCK in read().

Writes can be serialized with respect to other reads and writes. If a read() of file data can be proven (by any means) to occur after a write() of the data, it must reflect that write(), even if the calls are made by different processes. A similar requirement applies to multiple write operations to the same file position. This is needed to guarantee the propagation of data from write() calls to subsequent read() calls. This requirement is particularly significant for networked file systems, where some caching schemes violate these semantics.

Note that this is specified in terms of read() and write(). The XSI extensions readv() and writev() also obey these semantics. A new ``high-performance'' write analog that did not follow these serialization requirements would also be permitted by this wording. This volume of POSIX.1‐2017 is also silent about any effects of application-level caching (such as that done by stdio).

This volume of POSIX.1‐2017 does not specify the value of the file offset after an error is returned; there are too many cases. For programming errors, such as [EBADF], the concept is meaningless since no file is involved. For errors that are detected immediately, such as [EAGAIN], clearly the pointer should not change. After an interrupt or hardware error, however, an updated value would be very useful and is the behavior of many implementations.

This volume of POSIX.1‐2017 does not specify the behavior of concurrent writes to a regular file from multiple threads, except that each write is atomic (see Section 2.9.7, Thread Interactions with Regular File Operations). Applications should use some form of concurrency control.

This volume of POSIX.1‐2017 intentionally does not specify any pwrite() errors related to pipes, FIFOs, and sockets other than [ESPIPE].