Program 5.1, page 149, outputs the pathname of the current working directory.
It uses PATH_MAX to determine the size of the buffer needed.
Program 5.2, page 150, determines the implementation's maximum pathname length
relative to the root directory using pathconf.
#include <unistd.h>
long fpathconf(int filedes, int name);
long pathconf(const char *path, int name);
long sysconf(int name);
Directory Access
#include <dirent.h>
DIR *opendir(const char *filename);
struct dirent *readdir(DIR *dirp);
void rewinddir(DIR *dirp);
int closedir(DIR *dirp);
opendir provides a handle for the other functions. readdir gets the next entry in the directory. rewinddir restarts from the beginning. closedir closes the handle.
Note that like strtok these are not reentrant.
Program 5.3 (page 153) lists the files in a directory.
Directory and Inode
Accessing file status information
#include <sys/stat.h>
int lstat(const char *restrict path, struct stat *restrict buf);
int stat(const char *restrict path, struct stat *restrict buf);
int fstat(int fildes, struct stat *buf);
stat is given the name of a file. fstat is used for open files. lstat does the same thing as stat except that if the file
is a symbolic link, it gives information about the link, rather than the
file it is linked to.
The contents of the struct stat are system dependent, but the
standard says that it must contain at least the following fields:
dev_t st_dev; /* device ID of device containing file */
ino_t st_ino; /* file serial number */
mode_t st_mode; /* file mode */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of file */
gid_t st_gid; /* group ID of file */
off_t st_size; /* file size in bytes (regular files) */
/* path size (symbolic links) */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last data modification */
time_t st_ctime; /* time of last file status change */
Example 5.8, printaccess, page 155, displays the time that a file
was last accessed.
Exercise 5.9, printaccessmodbad, page 156 shows an incorrect way of printing
two times.
A correct solution is shown in printaccessmod, page 156.
Use the following macros to test the st_mode field for the file type.
S_ISBLK(m)
block special file
S_ISCHR(m)
character special file
S_ISDIR(m)
directory
S_ISFIFO(m)
pipe or FIFO special file
S_ISLNK(m)
symbolic link
S_ISREG(m)
regular file
S_ISSOCK(m)
socket
Example 5.10, isdirectory, page 157, shows how to determine whether a file
is a directory.
Unix File System Implementation
Figure 5.2 (page 159):
Structure of a typical UNIX file system.
Inodes
A directory entry contains only a name and an index into a table
giving information about a file. The table and the index are both
referred to as an inode.
This is what an inode looks like:
Figure 5.3 (page 160):
Schematic structure of a traditional UNIX inide.
Exercise 5.12, page 160 (in part):
Suppose that the block size is 8K and pointers are 4 bytes.
How large a file can be represented using
single indirect pointers, double indirect pointers, and triple indirect pointers?
A block contains 2K pointers. A single indirect block can address 2K x 8K =
16 megabytes.
A double indirect block will contain 2K pointers to single
indirect blocks for a total of 2K x 16 megabytes, or 32 gigabytes.
A triple indirect block can reference 2K times this, or 64 terabytes,
however, this number is 233, so for 4-byte pointers we would be
restricted to 32 terabytes.
Links
A link is an association between a filename and an inode.
UNIX has two types of links: hard and symbolic (also called soft).
Directory entries are called hard links because they directly link filenames
to inodes.
Each inode contains a count of the number of hard links to the inode.
When a file is created, a new directory entry is created an a new inode is assigned.
Additional hard links can be created with ln oldname newname
or with the link system call.
A new hard link to an existing file creates a new directory entry but assigns no other additional disk space.
A new hard link increments the link count in the inode.
A hard link can be removed with the rm command or the
unlink system call.
These decrement the link count.
The inode and associated disk space are freed when the count is decremented
to 0.
Figure 5.4 (page 91) shows a simple hard link and the associated inode.
Figure 5.5 (page 92) shows two hard links to the same file.
Figure 5.4 (page 163):
A directory entry, inode, and data block for a simple file.
Figure 5.5 (page 165):
Two hard links to the same file as in Figure 5.4.
Exercise 5.17, page 166
What would happen to Figure 5.5 after the following sequence of operations:
open("/dirA/name1");
read
close
modify memory image of the file
unlink("/dirA/name1");
open("/dirA/name1");
write
close
Answer: The result is Figure 5.6 (page 167).
Figure 5.5 (page 165):
Two hard links to the same file as in Figure 5.4.
Figure 5.6 (page 167):
The situation after editing the file. The original file had inode 12345
and two hard links prior to being edited.
Some editors make a backup copy of the file being edited. One way to
do this is with the following:
open("/dirA/name1");
read
close
modify memory image file file
rename("/dirA/name1","dirA/name1.bak");
open("/dirA/name1");
write
close
The result is in Figure 5.7 (page 168).
Figure 5.5 (page 165):
Two hard links to the same file as in Figure 5.4.
Figure 5.7 (page 168):
The situation after editing the file with an editor that makes a backup copy.
How to do it right:
open("/dirA/name1");
read
close
modify memory image file file
open("/dirA/name1",O_WRONLY | O_TRUNC);
write
close
Symbolic Links
A symbolic link is a special type of file that contains the name of
another file.
A reference to the name of a symbolic link causes the operating system to
use the name stored in the file, rather than the name itself.
Symbolic lines are created with the command: ln -s oldname newname
Symbolic links do not affect the link count in the inode.
Unlike hard links, symbolic links can span filesystems.
Figure 5.8 (page 170) shows a file with a symbolic link.
Figure 5.8 (page 170):
An ordinary file with a symbolic link to it.
Figure 5.9 (page 171) shows the result of making an editing change in the
file /dirB/name2 when the editor changes the inode associated with the
file read in.
Figure 5.9 (page 171):
The situation after editing a file that has a symbolic link.
Differences between hard and symbolic links
A count of the hard links is kept in the inode.
Hard links are relative to a given filesystem.
Removing the last hard link frees the physical file.
Removing a symbolic link cannot free a physical file.
You can make a symbolic link to a file that does not exist.
Even if it did exist once, a symbolic link might not reference anything.
A hard link always references a physical file (unless the filesystem is corrupt).