9. Directories
Contents:
Unix has its weak points but its file system is not one of them. - Chris Torek 9.0. IntroductionTo fully understand directories, you need to be acquainted with the underlying mechanics. The following explanation is slanted towards the Unix filesystem, for whose system calls and behavior Perl's directory access routines were designed, but it is applicable to some degree to most other platforms.
A
filesystem consists of two parts: a set of data blocks where the contents of files and directories are kept, and an index to those blocks. Each entity in the filesystem has an entry in the index, be it a plain file, a directory, a link, or a special file like those in A directory is a specially formatted file, whose inode entry marks it as a directory. A directory's data blocks contain a set of pairs. Each pair consists of the name of something in that directory and the inode number of that thing. The data blocks for /usr/bin might contain:
Every directory is like this, even the root directory ( / ). To read the file /usr/bin/vi , the operating system reads the inode for / , reads its data blocks to find the entry for /usr , reads /usr 's inode, reads its data block to find /usr/bin , reads /usr/bin 's inode, reads its data block to find /usr/bin/vi , reads /usr/bin/vi 's inode, and then reads the data from its data block. The name in a directory entry isn't fully qualified. The file /usr/bin/vi has an entry with the name vi in the /usr/bin directory. If you open the directory /usr/bin and read entries one by one, you get filenames like patch , rlogin , and vi instead of fully qualified names like /usr/bin/patch , /usr/bin/rlogin , and /usr/bin/vi . The inode has more than a pointer to the data blocks. Each inode also contains the type of thing it represents (directory, plain file, etc.), the size of the thing, a set of permissions bits, owner and group information, the time the thing was last modified, the number of directory entries that point to this inode, and so on. Some operations on files change the contents of the file's data blocks; some change just the inode. For instance, appending to or truncating a file updates its inode by changing the size field. Other operations change the directory entry that points to the file's inode. Changing a file's name changes only the directory entry; it updates neither the file's data nor its inode.
Three fields in the inode structure contain the last access, change, and modification times:
Reading a file changes its
We can access a file or directory's inode by calling the built-in function @entry = stat("/usr/bin/vi") or die "Couldn't stat /usr/bin/vi : $!"; To get the inode for the directory /usr/bin , say: @entry = stat("/usr/bin") or die "Couldn't stat /usr/bin : $!"; You can stat filehandles, too: @entry = stat(INFILE) or die "Couldn't stat INFILE : $!";
The
The values returned by
The standard
File::stat module provides a named interface to these values. It overrides the use File::stat; $inode = stat("/usr/bin/vi"); $ctime = $inode->ctime; $size = $inode->size;
In addition, Perl provides a set of operators that call
The open( F, "< $filename" ) or die "Opening $filename: $!\n"; unless (-s F && -T _) { die "$filename doesn't have text in it.\n"; }
The opendir(DIRHANDLE, "/usr/bin") or die "couldn't open /usr/bin : $!"; while ( defined ($filename = readdir(DIRHANDLE)) ) { print "Inside /usr/bin is something called $filename\n"; } closedir(DIRHANDLE);
These directory reading functions are designed to look like the file open and close functions. Where The filenames in a directory aren't necessarily stored alphabetically. If you want to get an alphabetical list of files, you'll have to read all the entries and sort them yourself. The separation of directory information from inode information can create some odd situations. Operations that change directory only require write permission on the directory, not on the file. Most operations that change information in the file's data require write permission to the file. Operations that alter the permissions of the file require that the caller be the file's owner or the superuser. This can lead to the interesting situation of being able to delete a file you can't read, or write to a file you can't remove.
Although these situations make the filesystem structure seem odd at first, they're actually the source of much of Unix's power. Links, two filenames that refer to the same file, are now extremely simple. The two directory entries just list the same inode number. The inode structure includes a count of the number of directory entries referring to the file (
Links come in two forms. The kind described above, where two directory entries list the same inode number (like
vi
and
nvi
in the earlier table), are called
hard links
. The operating system cannot tell the first directory entry of a file (the one created when the file was created) from any subsequent hard links to it. The other kind,
soft
or
symbolic links
, are very different. A soft link is a special type of file whose data block stores the filename the file is linked to. Soft links have a different Executive SummaryFilenames are kept in a directory, separate from the size, protections, and other metadata kept in an inode.
The
Directory handles look like filehandles, but they are not the same. In particular, you can't use < > on directory handles. The permissions on a directory determine whether you can read and write the list of filenames. The permissions on a file determine whether you can change the file's metadata or contents. Three different times are stored in an inode. None of them is the file's creation time. Copyright © 2001 O'Reilly & Associates. All rights reserved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|