繁体   English   中英

为什么 fseek 使用 read() 系统调用?

[英]Why does fseek use read() system call?

我试图了解fseek的 glibc 实现。 为此,我下载了 glibc 源代码并试图了解它的 function 执行顺序。

我在libio/fseek.c中找到了fseek实现。 基本上,它使用相同的参数调用 function(或更确切地说是宏) _IO_fseek() 该宏在libio/iolibio.h中实现。

它被定义为_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) (在libio/ioseekoff.c中实现)。 执行的下一步对我来说相当混乱:

_IO_seekoff_unlocked基本上返回_IO_SEEKOFF (fp, offset, dir, mode); ,它返回_IO_seekoff_unlocked (fp, offset, dir, mode); ,这应该创建一个调用循环。

此外,在示例程序( seek.c )上使用strace时:

#include <stdio.h>

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

    fseek(f, 0L, SEEK_END);
}

它表明fseek将调用read系统调用,即使我在 glibc 实现中找不到它。

...
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 +++

我的目标是了解 read 系统调用是如何在这里使用的。 我有自己的read系统调用实现,它适用于我编写的其他测试,但在通过fseek调用时会由于某种原因失败。

例如,我在 function 中使用fseek来获取文件的大小:

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;
}

这个 function 将通过“正常” read实现返回正确的大小,但我的会失败。 所以,如果有人能告诉我如何理解fseekread的使用(我在源代码中找不到),我将不胜感激。

_IO_seekoff_unlocked->_IO_SEEKOFF实际上扩展为JUMP3 (__seekoff, FP, OFF, DIR, MODE) JUMP3是一个从FILE "jump" table/vtable调用__seekoff的宏。

fopen默认分配_IO_file_jumps (或类似的东西,因为文件可以是 mmap 等)作为新FILE的跳转表。 它是FILE的跳转表/虚拟表的实现。

所以_IO_SEEKOFF调用_IO_file_jumps->__seekoff 它指向_IO_new_file_seekoff ,最后在 function 内部调用_IO_SYSREAD _IO_SYSREAD从跳转表调用_read ,后者又调用_IO_file_read ,后者调用__read最终执行SYSCALL_CANCEL (read)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM