|go text: || - index - problems - systems - libraries - converting - [ programming ] - old library - new library - links -
||topics: || - largefile default - off_t in headers - make export64 - find mismatch - the autowrappers - environ changes - [ best practice? ] -

Best Practice

Given all the problems about the different types of off_t one can try to figure out what the best solution might be. In a way that is a trade-off question as making your library a twinlibs installation is about easy for the library developer but it can be a real burden for the users of your library. The libc has gone the path of a dualmode library which is easiest for the libary user since there is only one library that is binary compatible for everything at the expense of the library maker who has to clutter ifdefs all over the header files. Which is a pain to maintain.

One way to lower the maintaince burden is what the developers of "gpgme" have done - they only ship a single library and it is always largefile64. In their Largefile Support For GpgMe statement they said "GPGME is compiled with largefile support by default, [..] For you as the user of the library, this means that your program must be compiled in the same file size mode as the library. Luckily, there is absolutely no valid reason for new programs to not enable largefile support by default and just use that. [..] If you do not want to do either of the above, you probably know enough about the issue to invent your own solution. [...] In particular, we do not support dual mode (_LARGEFILE64_SOURCE)."

That is not entirely true however since there are many many programs out there that have been started in the good old world of long32 file offsets and they to retain binary compatibility. Without further support they are basically left in the rain. Actually, in order to allow those developers to use the fopen64 functions the LFS-standard had invented the _LARGEFILE64_SOURCE variant which keeps "off_t" equal "long" and only "off64_t" is ensured to be largefile64. However the traditional "long" offers another way to allow 32bit applications to access a largefile64-compiled library.

In the following sections I like to provide you with template code to get to update your library to one of the preferred solutions. For old libraries this means to keep the function layout completely compatible with 32bit off_t by going into dualmode where the 64bit off_t variations of the functions are renamed to suffix64 ones. Essentially the libarary is left binary compatible as if being a long/32bit implementation with add-on implementations for the largefile64 case.

For a newer library design you can make the off_t/largefile64 function calls the default. In order to allow non-largefile64 code to access the library you will write a second series of functions that does not use off_t at all but which refers to "long" seek values. This has actually been the datatype for seek values before "off_t" was introduced. The advantage is that the ifdef-djungle is lowered considerable and you ensure that you can maintain the library code under the assumption of a 64-bit off_t being used everywhere by default.

This is also the biggest argument against using twinlibs as it happens that the Linux distributions will only compile any library with its defaults and they will only ship one version. Essentially they will provide binaries in non-largefile mode and the application makers will adapt their code to it. The amount of work that you have consumed while testing your library in largefile64 mode, well, quite nobody will use it. Only very few people who depend on largefiles will care to bind to a separate largefile library that is shipped via third parties. Addtionally, having two libraries in the system makes for a complication in loading a library via "dlopen" - the application would need to check what mode it is in and if the system is 64on32 and after all, quite no application will do it for real.

Last not least, if you define a library design where you do not need to have a reference to "off_t" then you can just as well employ "off64_t" directly. You do not need to invent your own position datatype like the GNOME library "glib" has done (they define the datatype "goffset" to be based on "gint64" on all platforms). Instead you can choose to use a header like largefile64_source.h (including largefiles on win32) to ensure this datatype is defined on all platforms. Still this variant offers the option to add a compat32 companion library later in the development process.