Lab 6 Preparation
To prepare for Lab 6 on reading directories, you will become familiar with many of the concepts and functions in Chapter 4 of Stevens/Rago. You are going to use the stat(2) function which is described right at the start of the chapter (section 4.2) and the directory functions like readdir(2) (section 4.21). You should also carefully examine section 4.14 on filesystems including the important concept of the i-node.
There is a reference in K&R2 to a sample program in section 8.6 on pages 179 to 184. See also the sample programs in the lecture notes.
The filesystem usually includes the entire collection of devices on a system, held together by the single, integrated tree-like directory structure (see and try tree(1)). Perhaps confusingly, however, a filesystem also refers to the files (and directories, which are also files) in a partition on a disk or to a pseudo-filesystem like /proc. You can usually tell from context which is meant.
A directory contains entries for all the files (of whatever file type, including other directories) belonging to it, plus its own self-reference "." and its parent directory "..". The back-chain of parent directories ultimately extends to the root directory "/", which is its own parent directory ("." and ".." refer to the same i-node).
For our immediate purposes, a single directory entry referring to a single file, directory, or whatever contains only two useful pieces of data:
the i-node number (which we don't use directly);
the file name (which we do, carefully).
A possible directory entry might look more or less like this:
struct dirent {
__ino_t d_ino; /* don't use */
__off_t d_off; /* don't use */
unsigned short int d_reclen; /* don't use */
unsigned char d_type; /* don't use */
char d_name[256]; /* OK to use */ };
Only ever use the d_name field in a directory entry. It contains the bare filename, zero-terminated as a normal C string (note: the '\0' is not stored in the directory on disk, only in its memory representation).
To use the d_name for anything outside its own directory, you must prefix it with an absolute or relative path. If you're not sure what these are, see Stevens/Rago on page 5.
You will often use such a path-qualified filename in a call to stat(2) or lstat(2) to get the i-node information contained in the struct stat (use less(1) to look at both /usr/include/sys/stat.h and /usr/include/bits/stat.h; then go and read section A12 on Pre-Processing (pages 228 to 233 in K&R2) if you want to actually understand it). If you have correctly set struct dirent *dirp; and char path[MAX]; you can create a fully qualified pathname as char fqp[MAX]; and then sprintf(fqp, "%s/%s", path, dirp->d_name); (no '\n' here).
The i-node is an element of a list or array of "information nodes". Every disk file (and a directory is just a special disk file) has an i-node which completely defines the file - except for its name. The filename is only an entry in the directory structure that contains the i-node number for that file.
You cannot write to an i-node directly, but it can be created, changed, and removed by many shell commands such as touch(1) and cp(1) and by lots of system calls, like open(2) and unlink(2). The i-node is read by stat(1) or stat(2), and many others (open(2), ls(1), cat(1), and so on - anything that uses a file). Read the man pages and the textbooks for these, then try them all.
The ls(1) command combines information from both the directory entry and its i-node for its -l display. Be sure to compare it with stat(1), which shows some different information also from both sources. Try ls with its -l, -i, and -a options, both singly and in combinations, for both files and directories. While you're checking these out, also try file(1). Does it use the i-node information?
Information contained in the i-node includes:
Type of file (regular, directory, character or block device);
File access permissions;
File size (in bytes; sometimes also in blocks);
Number of links to the file (the number of names it has in various directories: the number of times its i-node number appears in the directory tree);
Several times and dates, including:
file creation time;
last file access time;
last i-node modification time;
Array of disk addresses to data blocks for the file on disk;
I-node numbers of other i-nodes if more data blocks need to be listed.
Now read over the instructions for Lab 6 and follow them carefully.