views:

221

answers:

3

A library using off_t as a parameter for one function (seek). Library and application are compiled differently, one with large file support switched off, the other with large file support. This situation results in strange runtime errors, because both interpret off_t differently. How can the library check at runtime the size of off_t for the app? Or is there another solution, so that at least the user gets a meaningful error?

EDIT: The library (programmed in c and with autoconf) already exists and some third-party application use it. The library can be compiled with large file support (by default via AC_SYS_LARGEFILE). It is multiplatform, not only linux. How can be detected/prevented that installed applications will be broken by the change in LFS?

+2  A: 

You could add an API to the library to return the sizeof(off_t) and then check it from the client. Alternatively the library could require every app to provide the API in order to successfully link:

library.c:

size_t lib_get_off_t_size (void)
{
    return (sizeof(off_t));
}

client.c (init_function):

if (lib_get_off_t_size() != sizeof(off_t) {
    printf("Oh no!\n");
    exit();
}

If the library has an init function then you could put the check there, but then the client would have to supply the API to get the size of its off_t, which generally isn't how libraries work.

Andrew Johnson
A: 

As said before, the library will not be able to know how the application (being client to the library) is compiled, but the other way round has to work. Besides, I think you are talking about dynamic linking, since static linking certainly would not have different switches at same build time.

Similar to the already given answer by "Andrew Johnson", the library could provide a method for finding out whether it was compiled with large file support or not. Knowing that such build-time switches are mostly done with defines in C, this could be looking like this:

//in library:
BOOL isLargeFileSupport (void)
{
#ifdef LARGE_FILE_SUPPORT
    return TRUE;
#else
    return FALSE;
#endif
}

The application then knows how to handle file sizes reported by that lib, or can refuse to work when incompatible:

//in application
BOOL bLibLFS = lib_isLargeFileSupport();
BOOL bAppLFS = FALSE;
#ifdef LARGE_FILE_SUPPORT
    bAppLFS = TRUE;
#endif

if (bLibLFS != bAppLFS)
    //incompatible versions, bail out
    exit(0);
lImbus
+1  A: 

On Linux, when the library is compiled with large file support switched on, off_t is defined to be the same as off64_t. So, if the library is the one compiled with large file support, you could change its interface to always use off64_t instead of off_t (this might need _LARGEFILE64_SOURCE) and completely avoid the problem.

You can also check whether the application is being compiled with large file support or not (by seeing if _FILE_OFFSET_BITS is not defined or 32) and refuse compiling (with #error) if it's being compiled the wrong way; see /usr/include/features.h and Feature Test Macros.

CesarB