用于阅读目录的K&R界面:多余的DIR结构?

qfa*_*fab 5 c unix

在Kernighan和Ritchie 的第二版"The C Programming Language"中,他们实现了UNIX命令的简化版本ls(第8.6节"示例 - 列表目录",第179页).为此,它们创建以下接口,该接口提供对存储在目录中的文件的名称和inode编号的系统无关的访问.

#define NAME_MAX 14   /* longest filename component; */
                              /* system dependent */

typedef struct {      /* portable director-entry */
    long ino;                 /* inode number */
    char name[NAME_MAX+1];    /* name + '\0' terminator */
} Dirent;

typedef struct {      /* minimal DIR: no buffering, etc. */
    int fd;                   /* file descriptor for directory */
    Dirent d;                 /* the directory entry */
} DIR;

DIR *opendir(char *dirname);
Dirent *readdir(DIR *dfd);
void closedir(DIR *dfd);
Run Code Online (Sandbox Code Playgroud)

然后,他们为V7和System V UNIX系统实现此接口.

  • opendir()基本上使用系统调用open()来打开目录并 malloc()DIR结构分配空间 .然后返回的文件描述符open()存储在该变量fdDIR.Dirent 组件中没有存储任何内容.

  • readdir()使用系统调用 read()获取打开目录的下一个(系统相关的)目录条目,并将如此获得的inode编号和文件名复制到静态Dirent结构(返回指针).所需的唯一信息 readdir()是存储在DIR结构中的文件描述符.

现在我的问题是:拥有一个DIR结构有什么意义?如果我的这个计划的理解是正确的,Dirent分量DIR从未使用过,那么为什么不使用文件描述符代替整体的结构,直接使用open()close()

谢谢.

Ps:我知道在现代UNIX系统read()上不能再在目录上使用了(我已经在Ubuntu 10.04上试过了这个程序),但是我仍然想确保我没有忽略这个例子中的重要内容.

nmi*_*els 5

来自 K&R:

遗憾的是,在所有版本的系统上,目录的格式和精确内容并不相同。所以我们将任务分成两部分,尝试隔离不可移植的部分。外层定义了一个称为Dirent的结构和三个例程opendirreaddirclosedir以提供对目录条目中的名称和 inode 编号的独立于系统的访问。

所以原因是便携性。他们想要定义一个可以在具有不同统计结构或非标准open()close(). 他们继续围绕它构建一堆可重用的工具,甚至不在乎他们是否在类 Unix 系统上。这就是包装的重点。

也许它没有被使用,因为他们开始定义他们的数据结构(在 DIR 中使用 Dirent)但最终没有使用它。保持这样的数据结构分组是很好的设计。