|go text: || - index - [ problems ] - systems - libraries - converting - programming - old library - new library - links -
||topics: || - with callframes - with structures - [ largefile seeks ] - broken builds - LargeFile Seeks

LargeFile Seeks

This problem area is desribed in long words in the largefile specification under the topic of filedescriptor inheritance. However, we can boil it down to some other example to make you known what's wrong about it - but let's look at an expcerpt from the largefile specification first:

  A.1.1.4 Holes in the Protection Mechanism

  The following holes in the protection mechanism are discussed in other
  sections of this document:

    * While a "small" application has a file open another "large" application
      can extend the file (see A.1.2.1 Offset Maximum).
    * The fcntl() function may inadvertently clear O_LARGEFILE (see A.3.1.1.1
      fcntl()).
    * The lseek() failure may result in corruption of log file or database
      (see A.2.1.1.6 fgetpos(), fseek(), ftell(), lseek()).
    * An open file description with a "large" offset maximum may be inherited
      by a "small" application (see A.1.2.2 Inheritance).

  A.2.1.1.6 fgetpos(), fseek(), ftell(), lseek()

  These functions will fail if the resulting file offset would exceed the
  largest value that can be represented correctly in the related type which is
  in use for the call, and will set errno to EOVERFLOW (permitted by PASC
  Interpretation 1003.1-90 #75).

  Programs typically, but incorrectly, fail to check the return value of these
  functions, which renders the error return less useful. On the other hand,
  returning an incorrect offset can result in serious malfunction as well.

Oh yes, that's right - there are many many programs out there that will not check the return code of "lseek". And it does also have a simple reason that you'll know when you read the manual page of "lseek" and take note of the "ERRORS" section:

  ERRORS
     The lseek() function will fail if:
   [EBADF]
     The fildes argument is not an open file descriptor. 
   [EINVAL]
     The whence argument is not a proper value, or the resulting 
     file offset would be invalid. 
   [ESPIPE]
     The fildes argument is associated with a pipe or FIFO.

and therefore, when the file-stream had been opened correctly, and it did work just before with read/write and whatever, then the programmer will not assume the call can never fail. That was almost a correct assumptin, hower in a largefile system, in fact it can since a 64bit-filedescriptor can grow beyond the 2GiB boundary - and here we have it that the largefile group did ask to extend the "lseek" manual page with the following:

   [EOVERFLOW]
     The resulting file offset would be a value which cannot be 
     represented correctly in an object of type off_t. 

but wait - that can only hit if a 64bit-filedescriptor has been "lseek"ed within 32bit-off_t code. And those 32bit-off_t sources is surely written under ignorance of largefile since otherwise the maintainer of that software would have tried to compile the sources as "largefile" in the first place.

There are other such subtle problems - it must be seen as problematic to hand over filedescriptors from code being compiled under largefile mode to some other that isn't.