如何解决lseek() 对目录文件描述符意味着什么?
根据strace
,lseek(fd,SEEK_END) = 9223372036854775807
当fd
指的是一个目录。为什么这个系统调用会成功? lseek()
对于 dir fd 意味着什么?
解决方法
在我的测试系统上,如果您对目录中的所有条目使用 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,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)
,但这只是实现细节)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。