30

I have the 1st edition of The Unix Programming Environment book. In chapter 2, the authors state that directories are readable as files, and mention some facts about the format of these files. They give some usage examples such as cat . (in exercise 2-2).

At least in Darwin, directories are no longer readable as files. At least, they appear to be zero-length files when read.

When did this change occur, and is there any official documentation about it?

  • 1
    I remember it working some time 1991sep-1995jun on sun solaris. I think it stopped working for me somewhere in that time period as well. When we upgraded to sparc machines with system V. (can not remember to well). It probably depends on the file-system. If the file-system does not store the data exactly as described then it will break unless a compatibility layer is added. Also does not work today using Debian Gnu+Linux. – ctrl-alt-delor Sep 6 '14 at 21:25
  • 1
    I know that reading a directory as a file worked under Unix System V in the late 80s - early 90s. It worked under SunOS. It worked under some versions of Irix. I think that going to virtual file system and allowing many underlying disk organizations means that you can't really support this efficiently. – Bruce Ediger Sep 6 '14 at 22:44
  • 8
    More (non-authoritative) info can be found here: utcc.utoronto.ca/~cks/space/blog/unix/ReaddirHistory – camh Sep 6 '14 at 23:19
  • I checked on AIX and Solaris - indeed, on AIX you can still cat . while on Solaris 11 (as in Linux) you can't. Cool. – gena2x Sep 17 '14 at 9:13
14

The error number reference from the latest POSIX specification (POSIX.1-2008) states:

[EISDIR]

Is a directory. An attempt was made to open a directory with write mode specified.

This means that, on a POSIX compliant OS, you should be able to read() a directory if you opened it read only (O_RDONLY).

I've just tried this on a NetBSD (which really cares about POSIX) box, and works as expected, while it fails on GNU/Linux with EISDIR (which shouldn't happen).

A quick look at Linux shows this is intended (http://lxr.free-electrons.com/source/fs/libfs.c#L189):

ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
{
        return -EISDIR;
}

While a concrete filesystem implementation can override it (like CEPH does: http://lxr.free-electrons.com/source/fs/ceph/dir.c#L1142), the default behavior is to return EISDIR whenever someone is trying to read() a directory, even if it's open read only.

I've traced this change back to 2.0.x, and at least for the ext2 filesystem, this was still the case.

So, yes, on a POSIX compliant OS you should be able to read a directory, but some kernels (like Linux and, apparently, others) just ignore this condition and break the standard.

| improve this answer | |
  • 7
    According to the Open Group, Linux's behavior here is legal under an XSI extension to the standard. readdir(2) is more portable. That suggests to me the correct answer to OP's question is "When XSI became popular." – Kevin Apr 21 '15 at 3:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.