читать из файла (read from a file)
Обоснование (Rationale)
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 offset should
not change. After an interrupt or hardware error, however, an
updated value would be very useful and is the behavior of many
implementations.
Note that a read() of zero bytes does not modify the last data
access timestamp. A read() that requests more than zero bytes,
but returns zero, is required to modify the last data access
timestamp.
Implementations are allowed, but not required, to perform error
checking for read() requests of zero bytes.
Input and Output
The use of I/O with large byte counts has always presented
problems. Ideas such as lread() and lwrite() (using and
returning long
s) were considered at one time. The current
solution is to use abstract types on the ISO C standard function
to read() and write(). The abstract types can be declared so
that existing functions work, but can also be declared so that
larger types can be represented in future implementations. It is
presumed that whatever constraints limit the maximum range of
size_t
also limit portable I/O requests to the same range. This
volume of POSIX.1‐2017 also limits the range further by requiring
that the byte count be limited so that a signed return value
remains meaningful. Since the return type is also a (signed)
abstract type, the byte count can be defined by the
implementation to be larger than an int
can hold.
The standard developers considered adding atomicity requirements
to a pipe or FIFO, but recognized that due to the nature of pipes
and FIFOs there could be no guarantee of atomicity of reads of
{PIPE_BUF} or any other size that would be an aid to applications
portability.
This volume of POSIX.1‐2017 requires that no action be taken for
read() or write() when nbyte is zero. This is not intended to
take precedence over detection of errors (such as invalid buffer
pointers or file descriptors). This is consistent with the rest
of this volume of POSIX.1‐2017, but the phrasing here could be
misread to require detection of the zero case before any other
errors. A value of zero is to be considered a correct value, for
which the semantics are a no-op.
I/O is intended to be atomic to ordinary files and pipes and
FIFOs. Atomic means that all the bytes from a single operation
that started out together end up together, without interleaving
from other I/O operations. It is a known attribute of terminals
that this is not honored, and terminals are explicitly (and
implicitly permanently) excepted, making the behavior
unspecified. The behavior for other device types is also left
unspecified, but the wording is intended to imply that future
standards might choose to specify atomicity (or not).
There were recommendations to add format parameters to read() and
write() in order to handle networked transfers among
heterogeneous file system and base hardware types. Such a
facility may be required for support by the OSI presentation of
layer services. However, it was determined that this should
correspond with similar C-language facilities, and that is beyond
the scope of this volume of POSIX.1‐2017. The concept was
suggested to the developers of the ISO C standard for their
consideration as a possible area for future work.
In 4.3 BSD, a read() or write() that is interrupted by a signal
before transferring any data does not by default return an
[EINTR]
error, but is restarted. In 4.2 BSD, 4.3 BSD, and the
Eighth Edition, there is an additional function, select(), whose
purpose is to pause until specified activity (data to read, space
to write, and so on) is detected on specified file descriptors.
It is common in applications written for those systems for
select() to be used before read() in situations (such as keyboard
input) where interruption of I/O due to a signal is desired.
The issue of which files or file types are interruptible is
considered an implementation design issue. This is often affected
primarily by hardware and reliability issues.
There are no references to actions taken following an
``unrecoverable error''. It is considered beyond the scope of
this volume of POSIX.1‐2017 to describe what happens in the case
of hardware errors.
Earlier versions of this standard allowed two very different
behaviors with regard to the handling of interrupts. In order to
minimize the resulting confusion, it was decided that
POSIX.1‐2008 should support only one of these behaviors.
Historical practice on AT&T-derived systems was to have read()
and write() return -1 and set errno to [EINTR]
when interrupted
after some, but not all, of the data requested had been
transferred. However, the US Department of Commerce FIPS 151‐1
and FIPS 151‐2 require the historical BSD behavior, in which
read() and write() return the number of bytes actually
transferred before the interrupt. If -1 is returned when any
data is transferred, it is difficult to recover from the error on
a seekable device and impossible on a non-seekable device. Most
new implementations support this behavior. The behavior required
by POSIX.1‐2008 is to return the number of bytes transferred.
POSIX.1‐2008 does not specify when an implementation that buffers
read()s actually moves the data into the user-supplied buffer, so
an implementation may choose to do this at the latest possible
moment. Therefore, an interrupt arriving earlier may not cause
read() to return a partial byte count, but rather to return -1
and set errno to [EINTR]
.
Consideration was also given to combining the two previous
options, and setting errno to [EINTR]
while returning a short
count. However, not only is there no existing practice that
implements this, it is also contradictory to the idea that when
errno is set, the function responsible shall return -1.
This volume of POSIX.1‐2017 intentionally does not specify any
pread() errors related to pipes, FIFOs, and sockets other than
[ESPIPE]
.