I'm going to propose fixing apr_off_t at 64 bits regardless of the
system off_t.  This is not about getting large-file support in APR,
although that could come as a side-effect; this is about helping
APR-using libraries to be compatible with two different universes of
libraries, and making APR itself compatible with those two universes.

I'll start at the beginning.  32-bit operating systems wanted to add
large-file support.  The *BSDs did this by accepting a little bit of
pain, revving their libc ABI major versions, and winding up with off_t
being 64 bits.  Other platforms, notably Linux/x86, did not want to
accept this pain, so they did two things:

  * They introduced an explicit API for 64-bit offset support, with a
    new offset type (loff_t) and new functions (llseek) to use it.

  * They introduced magic compiler flags (-D_LARGEFILE_SOURCE
    -D_FILE_OFFSET_BITS=64) which cause off_t itself to become 64
    bits.  Code compiled with these magic flags is ABI-incompatible
    with normal code, but it means you can compile old, standard,
    portable code unchanged and get large file support as long as you
    don't care about ABI issues.

The details may vary once you get into X/Open's involvement, but the
general idea is the same.  I think, though I can't verify, that the
idea is that packages would be changed to use the explicit API (when
available), while end builders could use the magic compiler flags as a
crutch in the meantime.

Okay, now enter Perl.  Perl, which has always had a certain myopia
when it comes to ABI issues, compiles itself with the magic 64-bit
off_t flags on the relevant platforms.  As a consequence, any code
which interfaces to perl (either as bindings or by embedding a perl
interpreter) potentially also needs to compile itself with those
flags, and any code which interfaces to that code (as caller or
callee), and so on.  It was a mistake, but not a mistake that Perl can
easily undo.  Possibly other packages have made the same error.  There
are two non-empty universes of libraries and it hurts when they
collide.

How can we minimize the fallout from these two colliding universes?
By not using off_t in library APIs.  If an API does not make use of
off_t, then it is ABI-compatible with both universes regardless of how
its implementation is compiled.

By fixing apr_off_t at 64 bits, we make APR and all APR-using
libraries compatible with both universes.  APR could get itself
large-file support by using the explicit 64-bit API under the cover,
or by compiling itself with the large-file support flags, or it could
just not bother; the point here is not to get large file support, but
to be more compatible.

Now, the down sides:

  * APR 1.0 would be incompatible with APR 0.9.  If any httpd APIs use
    apr_off_t (and I'm pretty sure that some do), then httpd 2.x
    becomes stuck at APR 0.9.  Similarly, if any svn 1.0 APIs use
    apr_off_t (currently a matter of debate), then svn 1.x becomes
    stuck at APR 0.9.  (Subversion developers who are reading this
    should take note: regardless of whether APR accepts my proposal,
    svn 1.x will experience less pain if it avoids using apr_off_t in
    its API.  The redundant svn_offset_t type would be much less of a
    headache than being stuck at APR 0.9.)

  * If, in the future, people find it necessary to break the
    9-quintillion-byte barrier and desire 128-bit file offsets, APR
    may find itself in an uncomfortable situation by having fixed
    apr_off_t at 64 bits.  (Though, perhaps no more uncomfortable than
    it will in the default situation of using the platform's off_t.)

Reply via email to