Tuesday, March 1, 2011

How do I read a directory as a file in Unix?

I understand that a directory is just a file in unix that contains the inode numbers and names of the files within. How do I take a look at this? I can't use cat or less on a directory, and opening it in vi just shows me a listing of the files...no inode numbers.

From stackoverflow
  • It looks like the stat command might be in order. From the article:

    stat /etc/passwd
    
        File: `/etc/passwd'
        Size: 2911                Blocks: 8 IO    Block: 4096 regular file
        Device: fd00h/64768d      Inode: 324438   Links: 1
        Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
        Access: 2008-08-11 05:24:17.000000000 -0400
        Modify: 2008-08-03 05:11:05.000000000 -0400
        Change: 2008-08-03 05:11:05.000000000 -0400
    
    Goose Bumper : The stat command gives basic info about the file or directory, but it doesn't tell me anything about the files inside. For example, using "stat" on the directory pointed to by /etc gives me: 234881026 2995 drwxr-xr-x 91 root wheel 0 3094 "Oct 29 11:27:39 2009" "Sep 26 23:09:45 2009" "Sep 26 23:09:45 2009" 4096 0 0 /private/etc
    Tim Post : statvfs() is the more preferable function to use, in general practice.
  • Since this is a programming question (it is a programming question, isn't it?), you should check out the opendir, readdir and closedir functions. These are part of the Single UNIX Spec.

    #include <sys/types.h>
    #include <dirent.h>
    
    DIR *opendir (const char *dirname);
    struct dirent *readdir(DIR *dirp);
    int closedir(DIR *dirp);
    

    The dirent.h file should have the structure you need, containing at least:

    char   d_name[]    name of entry
    ino_t  d_ino       file serial number
    

    See here for the readdir manpage - it contains links to the others.

    Keep in mind that the amount of information about a file stored in the directory entries for it is minimal. The inode itself contains the stuff you get from the stat function, things like times, size, owner, permissions and so on, along with the all-important pointers to the actual file content.

    Goose Bumper : Ah, I see. But is there any way to see the literal, actual contents of the file? Maybe this example will make it clearer: on my setup, I can enter "less /bin/ls" to see the contents of ls. It's not legible in any way, obviously, but I can still see it. Can I do the same for directories in some way? It's not a practical question, it's more that I'm curious whether Unix allows a user to do something like this.
    paxdiablo : I've never seen a user-level command capable of doing this (that doesn't mean it doesn't exist). However, with a bit of work, you could get the inode of the actual directory you're interested in (from the parent directory) and walk the actual structures on the hard disk, assuming you have the requisite permissions.
    Goose Bumper : Perfect, thank you. It looks like there's no easy solution, but a little googling showed that there are some C functions worth investigating.
  • In the old days - Version 7, System III, early System V - you could indeed open a directory and read the contents into memory, especially for the old Unix file system with 2-byte inode numbers and a limit of 14 bytes on the file name.

    As more exotic file systems became more prevalent, the opendir(), readdir(), closedir() family of function calls had to be used instead because parsing the contents of a directory became increasingly non-trivial.

    Finally, in the last decade or so, it has reached the point where on most systems, you cannot read the directory; you can open it (primarily so operations such as fchdir() can work), and you can use the opendir() family of calls to read it.

0 comments:

Post a Comment