21

I understand that -D_FILE_OFFSET_BITS=64 causes off_t to be 64bits. So what does -D_LARGEFILE_SOURCE do that isn't already done by -D_FILE_OFFSET_BITS=64? What do these definitions do exactly?

panzi
  • 7,517
  • 5
  • 42
  • 54

3 Answers3

10

The GLIBC Feature test macros documentation states:

_LARGEFILE_SOURCE
If this macro is defined some extra functions are available which rectify a few shortcomings in all previous standards. Specifically, the functions fseeko and ftello are available. Without these functions the difference between the ISO C interface (fseek, ftell) and the low-level POSIX interface (lseek) would lead to problems.

This macro was introduced as part of the Large File Support extension (LFS).

So that macro specifically makes fseeko and ftello available. _FILE_OFFSET_BITS settings alone don't make these functions available.

(Note that if you're using a GNU dialect of C, the default with GCC, you might not need to explicitly define _LARGEFILE_SOURCE. You do if you use -std=c99 for instance.)

Mat
  • 202,337
  • 40
  • 393
  • 406
9

The other answer is wrong, as the documentation for _LARGEFILE_SOURCE is misleading. _FILE_OFFSET_BITS=64 is sufficient to expose the fseeko and ftello functions, and so is a _POSIX_C_SOURCE macro defined to >= 200112L.

From the glibc documentation on _FILE_OFFSET_BITS

If the macro is defined to the value 64, the large file interface replaces the old interface. I.e., the functions are not made available under different names (as they are with _LARGEFILE64_SOURCE). Instead the old function names now reference the new functions, e.g., a call to fseeko now indeed calls fseeko64.

Always define _FILE_OFFSET_BITS=64 to switch over to the 64-bit types on 32-bit glibc-based systems. glibc should really make it the default...

nxbit
  • 145
  • 1
  • 5
0

LFS

Large File Support (LFS), provides extra functionality required +- to access large files

  • large file == On 32-bit architectures, file larger than 2GB

We can write applications requiring LFS functionality in one of two ways:

  • Define the _LARGEFILE64_SOURCE feature test macro when compiling our program. -- Use the transitional LFS API.

  • Define the _FILE_OFFSET_BITS macro with the value 64 ++ when compiling our programs.

_LARGEFILE64_SOURCE

Define the _LARGEFILE64_SOURCE feature test macro when compiling our program. -- Use the transitional LFS API.

This API provides functions capable of handling 64-bit file sizes and offsets.

  • These functions have the same names as their 32-bit counterparts,

    ++ but have the suffix 64 appended +- to the function name.

  • Among these functions are

    fopen64(), 
    open64(), 
    lseek64(), 
    truncate64(), 
    stat64(), 
    mmap64(), 
    setrlimit64(). 
    
  • @eg::

    fd = open64(name, O_CREAT | O_RDWR, mode);
    

_FILE_OFFSET_BITS

Define the _FILE_OFFSET_BITS macro with the value 64 ++ when compiling our programs.

This automatically converts all of the relevant 32-bit functions and data types into their 64-bit counterparts.

  • @eg:: for example,

    calls to open() are actually converted into calls to open64(), and

    the off_t data type is defined +- to be 64 bits long.

  • @ie:: In other words,

    we can recompile an existing program +- to handle large files without needing +- to make any changes +- to the source code.

vs

  • Using _FILE_OFFSET_BITS is clearly simpler than using the _LARGEFILE64_SOURCE (transitional LFS API).
  • _LARGEFILE64_SOURCE (transitional LFS API) is now obsolete.
  • _FILE_OFFSET_BITS is preferred.

reference

The Linux Programming Interface

  • (most content was directly copied from here)
paulsm4
  • 114,292
  • 17
  • 138
  • 190
Nor.Z
  • 555
  • 1
  • 5
  • 13