Search code examples
cunixlseek

Unexpected behaviour of lseek


I am using lseek just to find the size of a file and lseek returns less bytes than the file's actual size. I think the code is right and I can't explain why that happens.

When i ran the program for the first time it worked well. Then I added some data to the file so it changed its size. Since then, when I run the program again with the new file, the result is always the size of the old file.

Any help appreciated!

int main(int argc,char* argv[]){
    int out_file_size=0;
    int fd_prognameout;

    fd_prognameout=open(argv[1],O_RDWR | O_CREAT,00700);

    if(fd_prognameout == -1){
        perror("Error:");
        return(0);
    }

    lseek(fd_prognameout,0,SEEK_SET);
    out_file_size = lseek(fd_prognameout,0,SEEK_END);
    lseek(fd_prognameout,0,SEEK_SET);

    printf("The size of out file is: %d\n",out_file_size);
    
    close(fd_prognameout);

    return(0);
}

Solution

  • First, lets change these lines

    lseek(fd_prognameout,0,SEEK_SET);
    out_file_size = lseek(fd_prognameout,0,SEEK_END);
    lseek(fd_prognameout,0,SEEK_SET);
    

    to

    //get the current file position
    off_t current_pos = lseek(fd_prognameout,0,SEEK_CUR);
    //get the last position (size of file)
    off_t out_file_size = lseek(fd_prognameout,0,SEEK_END);
    //reset to the previous position
    lseek(fd_prognameout,current_pos,SEEK_SET);
    

    Now to your problem. Modifications to a file might not be immediately visible (due to caching/buffering by the kernel). After modifying a file, either run the command sync or call in your code the functions fsync() or fdatasync().