lseek() 函数对于目录文件描述符意味着什么?

3
根据 strace,当fd指向一个目录时,lseek(fd, 0, SEEK_END) = 9223372036854775807。为什么这个系统调用会成功呢?对于dir fd,lseek()是什么意思?
1个回答

3

在我的测试系统上,如果你使用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(3)手册页

在早期的文件系统中,telldir()返回的值是目录内简单的文件偏移量。现代文件系统使用树形或哈希结构来表示目录,而不是平面表。在这种文件系统上,telldir()(并由readdir(3)在内部使用)返回的值是一个“cookie”,用于指导实现在目录中找到正确的位置。应用程序应该将此视为一个不透明的值,并对其内容不做任何假设。

这是一个神奇的数字,它表示目录内容的索引位于末尾。不要指望这个数字始终相同或可移植。它是一个黑盒子。除非你确切地知道自己在做什么,否则坚持使用dirent API遍历目录内容(在Linux和glibc下,opendir(3)在目录上调用openat(2)readdir(3)使用getdents(2)获取有关其内容的信息,seekdir(3)调用lseek(2),但这只是实现细节)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接