Search code examples
c32bit-64bitglibcfseeklarge-file-support

Why does fseeko() fail with EINVAL?


I need to add LFS to a C process which uses fseek(). gcc and glibc are of version 3.2.3 and 2.5, respectively.

I made the following alterations:

  1. added CFLAGS += -D_FILE_OFFSET_BITS=64 to the makefile.
  2. I replaced the call to fseek() with a call to fseeko() (I also need MSVC6 support, but one step at a time).
  3. I've changed the 2nd argument's type to off_t. sizeof() on the variable returns 8.

Here is as good a sample main() as I can get past our DLP and its output:

fd = fopen("large_file", "rb");
off_t offset = 1ULL << 32;
rc = fseeko(fd, offset, SEEK_SET);

rc = -1 sizeof(offset)=8 errno=22 offset=2147483648


Solution

  • The below program, compiled with CFLAGS = -g2 -Wall -D_LARGEFILE64_SOURCE works here (3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux)

    (compiling with CFLAGS = -g2 -Wall -D_FILE_OFFSET_BITS=64 and s/off64_t/off_t/ works equally well)

    #include <stdio.h>
    #include <strings.h>
    #include <unistd.h>
    
    int main(void)
    {
    off64_t offset ;
    int rc;
    FILE *fp;
    
    fp = fopen("testfile", "r+b");
    if (!fp) {
            perror("fopen" );
            return 1;
            }
    
    offset = 1ull << 32;
    rc = fseeko(fp, offset, 0);
    if (rc < 0) {
            perror("fseeko" );
            return 2;
            }
    rc = fwrite( "OMG!", 4, 1, fp);
    fprintf(stderr,"Write(4) : %d\n", rc);
    
    fclose(fp);
    
    return 0;
    }