.
Last update: 1997-05-20
9945-1-90 #58
_____________________________________________________________________________
Topic: fseek and ESPIPE
Relevant Sections: 8.1
Defect Report:
-----------------------
fseek() on a pipe or FIFO
A question arose during development of a ISO/IEC 9945-1:90 test
suite. This is related to the following assertion from Draft
13 of POSIX 1003.3.1:
When the underlying open file descriptor references a pipe
or FIFO, then a call to fseek() sets errno to ESPIPE,
returns a non-zero value and the value of the file pointer
is unchanged.
This particular issue has uncovered many ambiguities within
POSIX and within many implementations. The following is a
list of questions and some insights that may have a bearing
on the issue.
(1) Is a pipe or FIFO a device or a special file type?
There seems to be some sloppy wording in POSIX regarding
"devices which are incapable of seeking" and whether these
include pipes and FIFOs. The definition of a device is "A
computer peripheral or an object that appears to the
application as such" and that of a FIFO is "A FIFO special
file is a type of file". We understand from these
definitions that a pipe or a FIFO cannot be classified as a
device. If this is incorrect, then the behaviour of fseek()
on a pipe or FIFO is implementation defined and just about
any behaviour is acceptable after an attempt to perform a
file positioning operation on a pipe or FIFO. We understand
that the behaviour of a file positioning operation on a pipe
or FIFO is well defined to indicate an ESPIPE error.
(2) How does a file positioning operation on a pipe or FIFO
affect subsequent read operations?
POSIX states in the definition of file offset "There is no
file offset specified for a pipe or FIFO". In tests for
lseek() this has been understood by the various test suite
developers to mean that subsequent reads from the pipe or
FIFO are unaffected by the attempted lseek(), and this test
has not given any problems.
POSIX.3.1 Draft 13 has extrapolated this text for lseek()
into the equivalent assertion for fseek(). This
extrapolation has a further problem in that a stream does
not have file offset but has a file-position indicator. So
does the POSIX.3.1 assertion really refer to the file
position indicator or to the file pointer. The X/Open
ISO/IEC 9945-1:90 test suite understands this statement to be the
equivalent of the statement for lseek(), in that subsequent
reads from the stream are unaffected by the attempted
fseek(). This test, however, is exhibiting problems and is
the subject for this interpretation.
(3) Could the assertion be refering to the underlying file
descriptor?
If this were the case, then it would be necessary to access
the pipe and FIFO both from a stream (to undertake the
fseek()) and from a file descriptor (to undertake the
read()) to ensure that data loss did not occur at the file
descriptor level. Unfortunately, the synchronisation rules
for file handles does not provide a mechanism for handing
off file handles for buffered pipes. This makes it
impossible to produce a POSIX conforming application to test
this understanding of the assertion, though this doesn't
seem to deter all test suite authors! The fact that such an
assertion results in a pass is not entirely a surprise and
only serves to prove how well behaved implementations are
when the behavior is undefined.
(4) Could the assertion be refering to the continued ability
to read data from the stream without any side-effects?
The X/Open ISO/IEC 9945-1:90 test suite believes this to be the
case. While it is accepted that the POSIX does not
explicitly state that this is the case, it seems valid to
argue that side-effects that exhibit data loss after an
error condition has been raised should be documented. This
data loss seems particularly dangerous since there is no
means of recovery once an application has erroneously
undertaken an fseek() on a stream. However, these arguments
have to be balanced against the fact that there is no
explicit mention in the POSIX and in such cases the
implementation could be argued to have a degree of freedom.
The X/Open proposed resolution is:
An fseek() on a pipe or FIFO should return ESPIPE and
results in undefined behaviour to the stdio stream.
WG15 response for ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990)
-----------------------------------
An fseek() on a pipe or FIFO need not return an error. If the fseek()
detects the error, then it must fail with errno set to ESPIPE.
The POSIX.1 standard does not specify the state of the stream after
such an error occurs.
The language in POSIX.1 does not support the cited assertion from 13210
The language in POSIX.1 could be clearer, and this concern
over clarity has been forwarded to the sponsors.
Rationale for Interpretation:
-----------------------------
None.
_____________________________________________________________________________