|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? - off_t in headers

off_t in headers

If you still have some usage of off_t in the header files of your library then it is a good thing to mark that somewhere. Just compile your library with 64bit-off_t - and reject when software gets compiled with the wrong model than what your library was compiled as:

# if _FILE_OFFSET_BITS+0 != 64 && MYLIB_FILE_OFFSET_BITS+0 == 64
# error need to compile as largefile when using MYLIB
# endif

Another variant makes use of the AC_SYS_LARGEFILE_SENSITIVE macro - which is also a sanity check for the compilation of your library itself. That would simply use something like:

  # in configure.ac :
  AM_CONFIG_HEADER(config.h)
  AX_PREFIX_CONFIG_H(mylibconf.h,mylib)
  AC_SYS_LARGEFILE_SENSITIVE

  /* in mylibstruct.h */
  #include "mylibconf.h"
  #if defined MYLIB_LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 != 64
  #if defined __GNUC__
  #warning mylib requires largefile mode - use AC_SYS_LARGEFILE
  #else
  # error  mylib requires largefile mode - use AC_SYS_LARGEFILE
  #endif
  typedef struct {
     off_t off;
  } offstruct;

This scheme will keep your headers and sources `lean and mean` ;-) with your headers to actually take advantage of "off_t" as a native type that matches clean with standard filesystem functions. Just ensure to include "mylibconf.h" in every header file of your project that requires a check for a lib-create-time to lib-usage-time feature difference like off_t size - in other words, the library that uses an off_t and another program that takes advantage of that library.

Note also that the usage of AC_TYPE_OFF_T can be used to make "off_t" exist - and with the prefix macro this will also exist when the third-party software did forget to invoke this macro in its `configure.ac`. So just make all your api-calls dependent on that configured name, like `_mylib_off_t` everywhere.

 #include <mylibconf.h>

 #ifndef _mylib_off_t
 #define _mylib_off_t off_t
 #endif

_mylib_off_t     mylib_telldir(MYLIB_DIR * dir);
 void            mylib_seekdir(MYLIB_DIR * dir, _mylib_off_t offset);

That code is not just theory: have a look at http://zziplib.sf.net for a real-world and functional example.

One thing that I do not want to announce all too loud: if you find an improper usage of off_t in an older project, then you can add a quick hack by redefining those functions/structures to use int64_t instead of off_t. This will make structure-mismatch and callframe-mismatch problems to go away - but the seek problems will still exist and they might even hit you harder later since you've covered the usage of seek-offsets in a generic type instead of its dedicated off_t type, and basically forgot about to fix the problem for real. Therefore, if you did not add proper ifdefs to defend against improper usage in largefile-sensitive systems then better make a library typedef like `typedef int64_t mylib_off_t`. A later generation of that software may add proper check routines around this symbol.
(remember: UNIX98 systems are required to provide 64bit LFS).