Report 1904 Actions
Problem Report Number |
1904 |
Submitter's Classification |
Test Suite problem |
State |
Resolved |
Resolution |
Permanent Interpretation (PIN) |
Problem Resolution ID |
PIN.X.0223 |
Raised |
1998-03-27 08:00 |
Updated |
2003-03-13 08:00 |
Published |
1998-04-28 08:00 |
Product Standard |
Internationalised System Calls and Libraries Extended V2 (UNIX 98) |
Certification Program |
The Open Brand certification program |
Test Suite |
VSX5 version 5.1.4 |
Test Identification |
LFS.os/ioprim/fcntl 4 |
Specification |
System Interfaces and Headers Issue 5 |
Location in Spec |
See Problem Text |
Linked Problem Reports |
PG5R.002, (in, old, system) |
Problem Summary |
PIN5.003 This interpretation request is for the following assertions: LFS.os/ioprim/fcntl/T.fcntl 4 LFS.os/ioprim/lseek/T.lseek 2 LFS.os/streamio/fseek/T.fseek 3 LFS.os/streamio/fseeko/T.fseeko 17 LFS.os/strea... |
Problem Text |
This interpretation request is for the following assertions:
LFS.os/ioprim/fcntl/T.fcntl 4 LFS.os/ioprim/lseek/T.lseek 2 LFS.os/streamio/fseek/T.fseek 3 LFS.os/streamio/fseeko/T.fseeko 17 LFS.os/streamio/tmpfile/T.tmpfile 1
Reponse to Consultant's analysis in PG5R.002 follows:
Submitter agrees with the consultant that open() sets that to be the value of the largest value that can correctly fit in an off_t. Submitter also agrees with the Consultant about the definition of "offset maximum".
Submitter disgrees with the consultant's conclusions that are drawn from these two statements. open() makes the "offset maximum" anything that can fit in an off_t, while XBD5 on page 21 states that it is the largest value that can be used as a file offset.
"can be used as a file offset" does not guarantee sucessful use, as an off_t may be of one size but filesystem maximums may prevent actual use of certain ranges.
Submitter disagrees that the lseek() and associated failures that come from the current testing mechanism are improper:
1) lseek() must return EINVAL if the resulting file offset would be invalid. 2) It is possible for a file offset to be invalid even if the value *is* *less* than the offset maximum. There is no specification requirement that the maximum allowable offset must also be the allowable maximum filesize, and thus making certain ranges invalid on smaller filesystems with large off_t types.
3) Thus, it may not be possible to portably test for EOVERFLOW, or even test for it at all, as a UNIX conforming system is not required to have maximum filesizes equal to the maximum value storable in an off_t. a claim can be made that EOVERFLOW is detectable for read() in a 32-bit application (and thus the CSQ answers "yes"), but the detection will never happen in the 64-bit version of the same application running on the same system, given maximum filesizes smaller than 2**63 (regardless of off_t size).
|
Test Output |
************************************************************************ /tset/LFS.os/ioprim/fcntl/T.fcntl 4 Unresolved Test Description: When cmd is F_GETLK, FSETLK or F_SETLKW and l_len is zero and the smallest offset in the requested segment cannot be represented in an entity of type off_t, then a call to fcntl() returns -1 and sets errno to EOVERFLOW. Test Information: lseek() to 9223372036854775807 failed - errno 22 (EINVAL) lseek() to 9223372036854775807 failed - errno 22 (EINVAL) lseek() to 9223372036854775807 failed - errno 22 (EINVAL)
************************************************************************ ************************************************************************ /tset/LFS.os/ioprim/lseek/T.lseek 2 Unresolved Test Description: When the file position requested by a seek operation would be larger than the value that can be contained in an entity of type off_t, then a call to lseek() returns -1, sets errno to EOVERFLOW and the file pointer is unchanged. Test Information: lseek() failed when expecting to succeed. lseek() failed - errno 22 (EINVAL)
************************************************************************ ************************************************************************ /tset/LFS.os/streamio/fseek/T.fseek 3 Unresolved Test Description: When a call to fseek() attempts to set the file pointer to a position which cannot be represented in a value of type long, then the call returns -1 and sets errno to EOVERFLOW. Test Information: fseek() failed when expected to succeed- errno 22 (EINVAL)
************************************************************************ ************************************************************************ /tset/LFS.os/streamio/fseeko/T.fseeko 17 Unresolved Test Description: When a call to fseeko() attempts to set the file pointer to a position which cannot be represented in a value of type off_t, then the call returns -1 and sets errno to EOVERFLOW. Test Information: fseeko() failed when expected to succeed- errno 22 (EINVAL)
************************************************************************ ************************************************************************ /tset/LFS.os/streamio/tmpfile/T.tmpfile 1 Failed Test Description: A successful call to tmpfile() creates a file with an offset maximum that is equal to the largest value that can be contained in an entity of type off_t. Test Strategy: CALL tmpfile() to generate a temporary file and stream pointer VERIFY that tmpfile() has succeeded SEEK to the end of the file with lseek(stream, LFS_NORMAL_OFFMAX, SEEK_SET) VERIFY the success of the lseek() call WRITE one byte out to stream VERIFY that wrtie() returns -1 and sets errno to EFBIG
Test Information: lseek(tmpfile, LFS_NORMAL_OFFMAX, SEEK_SET) failed. got errno 22(EINVAL)
************************************************************************ ************************************************************************
|
Review Information
Review Type |
TSMA Review |
Start Date |
null |
Completed |
null |
Status |
Complete |
Review Recommendation |
No Resolution Given |
Review Response |
The submitter is reading something into page 21 of XBD5 that is not there. The text in question is an entry in the glossary - it is purely a definition of the term "offset maximum" and says nothing about its value.
If the term "offset maximum" in the XSH5 description of open() is expanded according to its definition, this produces the following equivalent text:
"The largest value that can be represented correctly in an object of type off_t will be established as [the largest value that can be used as a file offset] in the open file description."
It should be clear from this that applications are allowed to use file offsets up to the largest value of off_t in the process that opened the file. I.e. these offset values are valid, and should not produce an EINVAL error from lseek().
The submitter states "a UNIX conforming system is not required to have maximum filesizes equal to the maximum value storable in an off_t." This is correct. However, to try to use this in support of a claim that systems are not required to support file *offsets* equal to the maximum value of off_t shows that the submitter is making a false assumption that maximum file size and maximum file offset are somehow related. There is nothing in SUSv2 to suggest that such a relationship exists. Indeed there is good evidence to the contrary: the changes made in SUSv2 for large file support were adopted from the Large File Summit paper entitled `Adding Support for Arbitrary File Sizes to the Single UNIX Specification', and this paper contains the following note in section A.1.2.4:
"Different files may have different maximum permitted sizes even when they are on the same system, or are on the same type of file system, or are on the same file system. The maximum permitted file sizes are independent of the offset maximum."
The maximum file size is a limitation on file *size* and has no bearing on file *offsets*. Since lseek() does not change the size of the file, the maximum file size has no bearing on the behaviour of lseek().
Allowing lseek() to set the file offset to greater than the maximum file size means that applications can deal with reaching the maximum file size in the same way as reaching the process file size limit, through handling of the EFBIG error on write operations. This is important for portability of existing applications to UNIX98 systems, because EFBIG is often treated as a non-fatal error, whereas an EINVAL error from lseek() would typically be treated as fatal.
Finally, the submitter states that EOVERFLOW detection for read() will never happen in certain cases. This is correct, but the reason is not that the file offset cannot be set beyond the maximum file size, but because a read operation at such an offset will return an EOF indication. The test failures shown above do not include any tests of EOVERFLOW for read operations (which will all have produced "Unsupported" results in this case).
It is recommended that this waiver request is refused.
|
Review Type |
SA Review |
Start Date |
null |
Completed |
null |
Status |
Complete |
Review Resolution |
No Resolution Given |
Review Conclusion |
This request should go for a 14 day review.
|
Review Type |
Expert Group Review |
Start Date |
null |
Completed |
null |
Status |
Complete |
Review Resolution |
No Resolution Given |
Review Conclusion |
The Base WG agrees that the waiver should be granted.
A file offset that is greater than the maximum file size allowed by the system may be an invalid offset.
ANSI/IEEE std 1003.1, 1996 edition, page 162, states:
"..., the lseek function shall return -1 and set errno to the following value: ... [EINVAL] ... the resulting file offset would be invalid."
No definition of "invalid" is given, but in the rationale on page 473 says: "An invalid file offset that would cause [EINVAL] to be returned may be ... implementation defined ..."
The implementation defined condition which causes EINVAL to be returned here is that the file offset is beyond the maximum file size (for this particular file system). This is behavior which is clearly allowed by 1003.1 and should not be disallowed by XSH5.
The lseek() behavior can also be seen as protecting the read() and write() routines. write() in particular has no error described for handling "the offset I was expected to write to is already greater than the file is currently or can ever be". There is an EFBIG for "I cannot write beyond this point" and an EFBIG for "the starting position is at the offset maximum or beyond", but not this case. The lseek() EINVAL protects the process against this case. Since EFBIG can possibly be followed by a SIGXFSZ, EFBIG can be just as fatal as EINVAL.
The situation with read() can also be confusing without this. There are at least two different ways "0" can be returned from a read() and no error condition defined for either of them. The second is "starting point greater than end of file".
lseek() has a valid reason for returning EINVAL in this case.
|
Review Type |
SA Review |
Start Date |
null |
Completed |
null |
Status |
Complete |
Review Resolution |
Permanent Interpretation (PIN) |
Review Conclusion |
A Permanent Interpretation is granted.
|
Problem Reporting System Options:
|