Next: , Previous: , Up: Preparation   [Contents][Index]

2.3 Largefile Support (LFS)

GPGME is compiled with largefile support by default, if it is available on the system. This means that GPGME supports files larger than two gigabyte in size, if the underlying operating system can. On some systems, largefile support is already the default. On such systems, nothing special is required. However, some systems provide only support for files up to two gigabyte in size by default. Support for larger file sizes has to be specifically enabled.

To make a difficult situation even more complex, such systems provide two different types of largefile support. You can either get all relevant functions replaced with alternatives that are largefile capable, or you can get new functions and data types for largefile support added. Those new functions have the same name as their smallfile counterparts, but with a suffix of 64.

An example: The data type off_t is 32 bit wide on GNU/Linux PC systems. To address offsets in large files, you can either enable largefile support add-on. Then a new data type off64_t is provided, which is 64 bit wide. Or you can replace the existing off_t data type with its 64 bit wide counterpart. All occurrences of off_t are then automagically replaced.

As if matters were not complex enough, there are also two different types of file descriptors in such systems. This is important because if file descriptors are exchanged between programs that use a different maximum file size, certain errors must be produced on some file descriptors to prevent subtle overflow bugs from occurring.

As you can see, supporting two different maximum file sizes at the same time is not at all an easy task. However, the maximum file size does matter for GPGME, because some data types it uses in its interfaces are affected by that. For example, the off_t data type is used in the gpgme_data_seek function, to match its POSIX counterpart. This affects the call-frame of the function, and thus the ABI of the library. Furthermore, file descriptors can be exchanged between GPGME and the application.

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. The compatibility modes (small file sizes or dual mode) can be considered an historic artefact, only useful to allow for a transitional period.

On POSIX platforms GPGME is compiled using largefile support by default. This means that your application must do the same, at least as far as it is relevant for using the gpgme.h header file. All types in this header files refer to their largefile counterparts, if they are different from any default types on the system.

On 32 and 64 bit Windows platforms off_t is declared as 32 bit signed integer. There is no specific support for LFS in the C library. The recommendation from Microsoft is to use the native interface (CreateFile et al.) for large files. Released binary versions of GPGME (libgpgme-11.dll) have always been build with a 32 bit off_t. To avoid an ABI break we stick to this convention for 32 bit Windows by using long there. GPGME versions for 64 bit Windows have never been released and thus we are able to use int64_t instead of off_t there. For easier migration the typedef gpgme_off_t has been defined. The reason we cannot use off_t directly is that some toolchains (e.g., mingw64) introduce a POSIX compatible hack for off_t. Some widely used toolkits make use of this hack and in turn GPGME would need to use it also. However, this would introduce an ABI break and existing software making use of libgpgme might suffer from a severe break. Thus with version 1.4.2 we redefined all functions using off_t to use gpgme_off_t which is defined as explained above. This way we keep the ABI well defined and independent of any toolchain hacks. The bottom line is that LFS support in GPGME is only available on 64 bit versions of Windows.

On POSIX platforms you can enable largefile support, if it is different from the default on the system the application is compiled on, by using the Autoconf macro AC_SYS_LARGEFILE. If you do this, then you don’t need to worry about anything else: It will just work. In this case you might also want to use AC_FUNC_FSEEKO to take advantage of some new interfaces, and AC_TYPE_OFF_T (just in case).

If you do not use Autoconf, you can define the preprocessor symbol _FILE_OFFSET_BITS to 64 before including any header files, for example by specifying the option -D_FILE_OFFSET_BITS=64 on the compiler command line. You will also want to define the preprocessor symbol LARGEFILE_SOURCE to 1 in this case, to take advantage of some new interfaces.

If you do not want to do either of the above, you probably know enough about the issue to invent your own solution. Just keep in mind that the GPGME header file expects that largefile support is enabled, if it is available. In particular, we do not support dual mode (_LARGEFILE64_SOURCE).

Next: Using Automake, Previous: Building the Source, Up: Preparation   [Contents][Index]