Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

linux - What does lseek() mean for a directory file descriptor?

According to strace, lseek(fd, 0, SEEK_END) = 9223372036854775807 when fd refers to a directory. Why is this syscall succeeding at all? What does lseek() mean for a dir fd?

question from:https://stackoverflow.com/questions/65911066/what-does-lseek-mean-for-a-directory-file-descriptor

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

On my test system, if you use opendir(), and readdir() through all the entries in the directory, telldir() then returns the same value:

#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
", (long)o);
  close(fd);

  DIR *d = opendir(".");
  if (!d) {
    perror("opendir");
    return 1;
  }
  while (readdir(d)) {
  }

  printf("via telldir: %ld
", telldir(d));
  closedir(d);

  return 0;
}

outputs

Via lseek: 9223372036854775807
via telldir: 9223372036854775807

Quoting from the telldir(3) man page:

In early filesystems, the value returned by telldir() was a simple file offset within a directory. Modern filesystems use tree or hash structures, rather than flat tables, to represent directories. On such filesystems, the value returned by telldir() (and used internally by readdir(3)) is a "cookie" that is used by the implementation to derive a position within a directory. Application programs should treat this strictly as an opaque value, making no assumptions about its contents.

It's a magic number that indicates that the index into the directory's contents is at the end. Don't count on the number always being the same, or being portable. It's a black box. And stick with the dirent API for traversing directory contents unless you really know exactly what you're doing (Under the hood on Linux + glibc, opendir(3) calls openat(2) on the directory, readdir(3) fetches information about its contents with getdents(2), and seekdir(3) calls lseek(2), but that's just implementation details)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...