我正在尝试了解的glibc实现fseek
。为此,我下载了glibc源代码并尝试了解其功能执行顺序。
我在中找到了fseek
实现libio/fseek.c
。基本上,它_IO_fseek()
使用相同的参数调用函数(或宏)。该宏在中实现libio/iolibio.h
。
它定义为_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT)
(在中实现libio/ioseekoff.c
)。执行它的下一步对我来说很混乱:
_IO_seekoff_unlocked
基本上是return _IO_SEEKOFF (fp, offset, dir, mode);
,它返回_IO_seekoff_unlocked (fp, offset, dir, mode);
,这应该创建一个调用循环。
另外,在strace
示例程序(seek.c
)上使用时:
#includeint 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\n\nint main(voi"..., 146) = 146 exit_group(0) = ? +++ exited with 0 +++
我的目标是了解此处如何使用读取系统调用。我有自己的read
系统调用实现,该调用在我编写的其他测试中效果很好,但通过via调用由于某种原因会失败fseek
。
例如,我使用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; }
该函数将通过“正常” read
实现返回正确的大小,但由于我的失败。因此,如果有人可以告诉我如何理解read
内部使用fseek
(在源代码中找不到),我将不胜感激。