Home:ALL Converter>Why does fseek use read() system call?

Why does fseek use read() system call?

Ask Time:2019-11-20T19:07:17         Author:MajorasKid

Json Formatter

I'm trying to understand the glibc implementation of fseek. To do so, I downloaded the glibc source code and tried to understand its function execution order.

I found the fseek implementation in libio/fseek.c. Basically, it calls the function (or rather the macro) _IO_fseek() using the same parameters. This macro is implemented in libio/iolibio.h.

It is defined as _IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) (implemented in libio/ioseekoff.c). The next step in its execution is rather confusing for me:

_IO_seekoff_unlocked basically returns _IO_SEEKOFF (fp, offset, dir, mode);, which returns _IO_seekoff_unlocked (fp, offset, dir, mode);, which should create a call loop.

Also, when using strace on an example program (seek.c):

#include <stdio.h>

int main(void) {
    printf("[Fseek] Executing fseek\n");
    FILE *f = fopen("./seek.c", "rb");

    fseek(f, 0L, SEEK_END);
}

it shows that fseek will call the read system call, even though I could not find it in the glibc implementation.

...
write(1, "[Fseek] Executing fseek\n", 24[Fseek] Executing fseek
) = 24
openat(AT_FDCWD, "./seek.c", O_RDONLY)  = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
lseek(3, 0, SEEK_SET)                   = 0
read(3, "#include <stdio.h>\n\nint main(voi"..., 146) = 146
exit_group(0)                           = ?
+++ exited with 0 +++

My goal is to understand how the read system call is used here. I have my own implementation of the read system call, which works well for other tests I wrote but will fail for some reason when it is called via fseek.

As an example, I use fseek in a function to get the size of a file:

long get_file_size(const char *name)
{
    FILE *temp_file = fopen(name, "rb");
    if (temp_file == NULL)
    {
        return -1;
    }

    fseek(temp_file, 0L, SEEK_END);
    long sz =  ftell(temp_file);
    fclose(temp_file);
    return sz;
}

This function will return the correct size with the "normal" read implementation but will fail with mine. So, if anybody can tell me how I can understand the use of read within fseek (which I could not find in the source), I would highly appreciate it.

Author:MajorasKid,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/58952893/why-does-fseek-use-read-system-call
yy