index -summary -history -testscript perl / python problems -with callframes -with structures -largefile seeks -broken builds systems -freeBSD/darwin -linux/solaris -64on32 mix -distro makers -win32/other (2) libraries - libc ..(3264)
- zlib ..(-32-)
- gtk2 ..(-64-)
converting -old non-off_t code -going largefile -longlong default -face dualmode -make twinlibs -and defend (it) programming -largefile default -off_t in headers -make export64 -find mismatch -the autowrappers -environ changes -best practice? old library -dualmode renames -the extra function -largefile64_source -glibc headers -libgz example *** new library -dual export -largefiles win32 -compat32 calls -compat32 library -long32 dualmode links -some quotes -sitemap / mpl -large.file Group* -ac-archive Site*
(C) 2003-12-20 Guido U. Draheim |
Step 5: defending against improper usage on 64on32With installing your library into a 64on32 and allowing third party code to compile and link with it, you have to face the fact that the third party code might later happily be compiled in just a different off_t mode than your own code at build time. Whatever variant of largefile resistance you chose, you have to make your header files aware of the problem, and perhaps warn improper usage or just disallow it. The easiest way is with twinlibs. Actually, you don't need anything, if you want to be nice then you can remember if a second twin has been built and note the fact in the installed header files. Or even easier, remember the sizeof(off_t) in some installed lib-config.h file (ax_prefix_config_h), and upon inclusion by third party code check the _FILE_OFFSET_BITS to match, i.e. #if _FILE_OFFSET_BITS+0 == 64 && MYLIB_SIZEOF_OFF_T == 4 #ifdef __GNUC__ #warning mylib has been compiled with 32bit off_t, expect problems #else #error mylib has been compiled with 32bit off_t, your's is 64bit #endif #endif or perhaps, do not warn and instead hide all API entries that are off_t sensitive which makes for nice compile-time errors but only for those sources that actually use one of the API entries that are off_t sensitive. Consider to hide entries as well that might be subject to non-matching file descriptor inheritance. #if _FILE_OFFSET_BITS+0 == 64 && MYLIB_SIZEOF_OFF_T == 4 #define MYLIB_HIDE_OFF_T_API 1 #endif ... #ifndef MYLIB_HIDE_OFF_T_API off_t mylib_seek(int, off_t); #endif That header file defense does not prevent another problem - the runtime mismatch. Consider a system where your library has been compiled and installed as a largefile variant. Then some third party code gets compiled on top of it and as a largefile variant as well. The third party code gets packaged and moved as binary code to another system. The other system does already have your library installed as well - but in a non-largefile variant. A dualmode library does not have that problem, it is internally largefile always and supports both application variants being 32bit or 64bit off_t. It can mostly resist even a mixture of third party code sitting on top of it. There it is the duty of the library maker to implant enough logic into the library source to defend at runtime to problems of a mixture of code towering above it. In parts, we can try to defend with a twinlibs approach as well, simply by taking over a trick from the dualmode approach: to rename API calls that are off_t-sensitive with a *64 suffix. Any third party code being compiled non-largefile will then fail ldso runtime linkage with a largefile-compiled variant of your library and only in the case that it makes use of off_t-sensitive API entries. In all these cases, remember that off_t-sensitive can mean a lot, be cautious about any fdreopen-style file descriptor inheritance, and check whether some 'struct' contains an off_t member or file descriptor handle that might be pushed down into a library code of yours unnoticed by any ldso-rename defence. Or rename these as well, perhaps even rename all entries which makes it even sometimes easier to have both variants linked at the same time into a party group on top of it.
Now, these are only parts of the measures you can take, some other
variants are explained in the next section that is a little harder
to navigate to on this site - for good reason. It's called |