在目录上使用`read`系统调用 [英] Using `read` system call on a directory

查看:118
本文介绍了在目录上使用`read`系统调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看 K& R 2 中的示例(8.6示例-列表目录) .它是Linux命令ls或Windows的dir的精简版本.该示例显示了opendirreaddir之类的功能的实现.我已经尝试过逐字键入代码,但仍然无法正常工作.它所做的就是打印一个点(表示当前目录)并退出.

I was looking at an example in K&R 2 (8.6 Example - Listing Directories). It is a stripped down version of Linux command ls or Windows' dir. The example shows an implementation of functions like opendir, readdir. I've tried and typed the code word-by-word but it still doesn't work. All it does is that it prints the a dot (for the current directory) and exits.

我在代码中(在readdir的实现中)发现一个有趣的事情是它正在调用目录上的openread之类的系统调用.像-

One interesting thing I found in the code (in the implementation of readdir) was that it was calling the system calls like open and read on directory. Something like -

int fd, n;
char buf[1000], *bufp;

bufp = buf;
fd = open("dirname", O_RDONLY, 0);
n = read(fd, bufp, 1000);
write(fd, bufp, n);

运行此代码时,即使文件夹名称"dirname"中包含一些文件,我也没有输出.

When I run this code I get no output even when the folder name "dirname" has some files in it.

这本书还说,该实现是针对版本7和System V UNIX系统的.那是为什么它不能在Linux上运行的原因吗?

Also, the book says, that the implementation is for Version 7 and System V UNIX systems. Is that the reason why it is not working on Linux?

这是代码- http://ideone.com/tw8ouX .

那么Linux不允许目录上的read系统调用吗?还是其他原因导致了这种情况?

So does Linux not allow read system calls on directories? Or something else is causing this?

推荐答案

在版本7 UNIX中,只有一个unix文件系统,其目录具有简单的磁盘格式:struct direct数组.阅读并解释结果是微不足道的.系统调用将是多余的.

In Version 7 UNIX, there was only one unix filesystem, and its directories had a simple on-disk format: array of struct direct. Reading it and interpreting the result was trivial. A syscall would have been redundant.

在现代,Linux和其他类似Unix的系统(ext4,ZFS,NTFS!)可以挂载许多类型的文件系统,其中一些具有复杂的目录格式.您不能对任意目录的原始字节做任何有意义的事情.因此,内核承担了为目录提供通用接口作为抽象对象的责任. readdir是该界面的中心部分.

In modern times there are many kinds of filesystems that can be mounted by Linux and other unix-like systems (ext4, ZFS, NTFS!), some of which have complex directory formats. You can't do anything sensible with the raw bytes of an arbitrary directory. So the kernel has taken on the responsibility of providing a generic interface to directories as abstract objects. readdir is the central piece of that interface.

某些现代的unice仍然允许read()在目录中,因为它是其历史的一部分. Linux的历史始于90年代,当时很明显,目录上的read()永远都不会有用,因此Linux从未允许它.

Some modern unices still allow read() on a directory, because it's part of their history. Linux history began in the 90's, when it was already obvious that read() on a directory was never going to be useful, so Linux has never allowed it.

Linux确实提供了readdir syscall,但由于使用了更好的东西,所以不再使用它了:getdents. readdir一次仅返回一个目录条目,因此,如果您在循环中使用readdir syscall来获取目录中的文件列表,则每次循环迭代时都要输入内核. getdents将多个条目返回到缓冲区中.

Linux does provide a readdir syscall, but it's not used very much anymore, because something better has come along: getdents. readdir only returns one directory entry at a time, so if you use the readdir syscall in a loop to get a list of files in a directory, you enter the kernel on every loop iteration. getdents returns multiple entries into a buffer.

readdir是标准接口,因此glibc提供了一个readdir函数,该函数调用getdents syscall而不是readdir syscall.在普通程序中,您将在源代码中看到readdir,但在strace中看到getdents. C库通过缓冲来帮助提高性能,就像在调用getchar()的常规文件的stdio中所做的那样,并且它一次执行几千字节的read()而不是一堆单字节的read()

readdir is, however, the standard interface, so glibc provides a readdir function that calls the getdents syscall instead of the readdir syscall. In an ordinary program you'll see readdir in the source code, but getdents in the strace. The C library is helping performance by buffering, just like it does in stdio for regular files when you call getchar() and it does a read() of a few kilobytes at a time instead of a bunch of single-byte read()s.

除非运行运行很久以前编译的可执行文件,否则您将永远不会在现代Linux系统上使用原始的无缓冲readdir syscall.

You'll never use the original unbuffered readdir syscall on a modern Linux system unless you run an executable that was compiled a long time ago, or go out of your way to bypass the C library.

这篇关于在目录上使用`read`系统调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆