IEEE Standards Interpretation for IEEE Std 1003.1™-1990 IEEE Standard for Information Technology--Portable Operating System Interfaces (POSIX®)
Copyright © 2001 by the Institute of Electrical and Electronics Engineers, Inc. 3 Park Avenue New York, New York 10016-5997 USA All Rights Reserved.
Interpretations are issued to explain and clarify the intent of a standard and do not constitute an alteration to the original standard. In addition, interpretations are not intended to supply consulting information. Permission is hereby granted to download and print one copy of this document. Individuals seeking permission to reproduce and/or distribute this document in its entirety or portions of this document must contact the IEEE Standards Department for the appropriate license. Use of the information contained in this document is at your own risk.
IEEE Standards Department Copyrights and Permissions 445 Hoes Lane, Piscataway, New Jersey 08855-1331, USA
Interpretation Request #58
Topic: fseek and ESPIPE Relevant Sections: 8.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 POSIX.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
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 POSIX.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.
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 2003.1. The language in POSIX.1 could be clearer, and this concern over clarity has been forwarded to the sponsors.
Rationale for Interpretation