根据
strace
,当fd
指向一个目录时,lseek(fd, 0, SEEK_END) = 9223372036854775807
。为什么这个系统调用会成功呢?对于dir fd,lseek()
是什么意思?strace
,当fd
指向一个目录时,lseek(fd, 0, SEEK_END) = 9223372036854775807
。为什么这个系统调用会成功呢?对于dir fd,lseek()
是什么意思?在我的测试系统上,如果你使用opendir()
函数,并通过readdir()
遍历目录中的所有条目,则telldir()
函数将返回相同的值:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
int main(int argc, char *argv[]) {
int fd = open(".", O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
off_t o = lseek(fd, 0, SEEK_END);
if (o == (off_t)-1) {
perror("lseek");
return 1;
}
printf("Via lseek: %ld\n", (long)o);
close(fd);
DIR *d = opendir(".");
if (!d) {
perror("opendir");
return 1;
}
while (readdir(d)) {
}
printf("via telldir: %ld\n", telldir(d));
closedir(d);
return 0;
}
输出
Via lseek: 9223372036854775807
via telldir: 9223372036854775807
在早期的文件系统中,
telldir()
返回的值是目录内简单的文件偏移量。现代文件系统使用树形或哈希结构来表示目录,而不是平面表。在这种文件系统上,telldir()
(并由readdir(3)
在内部使用)返回的值是一个“cookie”,用于指导实现在目录中找到正确的位置。应用程序应该将此视为一个不透明的值,并对其内容不做任何假设。
这是一个神奇的数字,它表示目录内容的索引位于末尾。不要指望这个数字始终相同或可移植。它是一个黑盒子。除非你确切地知道自己在做什么,否则坚持使用dirent API遍历目录内容(在Linux和glibc下,opendir(3)
在目录上调用openat(2)
,readdir(3)
使用getdents(2)
获取有关其内容的信息,seekdir(3)
调用lseek(2)
,但这只是实现细节)