We’ll now look at additional features of the file system and the properties of a file.

1 stat, fstat, fstatat, and lstat Functions

1
2
3
4
int stat(const char *restrict pathname, struct stat *restrict buf );
int fstat(int fd, struct stat *buf);
int lstat(const char *restrict pathname, struct stat *restrict buf );
int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);

Given a pathname, the stat function returns a structure of information about the named file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct stat {
mode_t st_mode; /* file type & mode (permissions) */
ino_t st_ino; /* i-node number (serial number) */
dev_t st_dev; /* device number (file system) */
dev_t st_rdev; /* device number for special files */
nlink_t st_nlink; /* number of links */
uid_t st_uid; /* user ID of the owner */
gid_t st_gid; /* group ID of the owner */
off_t st_size; /* size in bytes, for regular files */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last file status change */
blksize_t st_blksize; /* best I/O block size*/
blkcnt_t st_blocks; /* number of disk blocks allocated */
};

2 File Types

The types are:

  1. Regular file.
  2. Directory file.
  3. Block special file. A type of file providing buffered I/O access in fixed-size units to devices such as disk drives.
  4. Character special file. A type of file providing unbuffered I/O access in variable-sized units to devices. All devices on a system are either block special files or character special files.
  5. FIFO. A type of file used for communication between processes.
  6. Socket.
  7. Symbolic link. A type of file that points to another file.

The type of a file is encoded in the st_mode member of the stat structure.

3 Set-User-ID and Set-Group-ID

Every process has six or more IDs associated with it. These are shown in Figure 4.5.

  • The real user ID and real group ID identify who we really are. These two fields are taken from our entry in the password file when we log in. Normally, these values don’t change during a login session, although there are ways for a superuser process to change them.
  • The effective user ID, effective group ID, and supplementary group IDs determine our file access permissions.
  • The saved set-user-ID and saved set-group-ID contain copies of the effective user ID and the effective group ID, respectively, when a program is executed.

Normally, the effective user ID equals the real user ID, and the effective group ID equals the real group ID.

When we execute a program file, the effective user ID of the process is usually the real user ID, and the effective group ID is usually the real group ID. However, we can also set a special flag in the file’s mode word (st_mode) that says, ‘‘When this file is executed, set the effective user ID of the process to be the owner of the file (st_uid).’’ Similarly, we can set another bit in the file’s mode word that causes the effective group ID to be the group owner of the file (st_gid). These two bits in the file’s mode word are called the set-user-ID bit and the set-group-ID bit.

4 File Access Permissions

The st_mode value also encodes the access permission bits for the file.

There are nine permission bits for each file, divided into three categories. They are shown in Figure 4.6.

The term user in the first three rows in Figure 4.6 refers to the owner of the file. The chmod command, which is typically used to modify these nine permission bit.

5 Ownership of New Files and Directories

The user ID of a new file is set to the effective user ID of the process.

6 access and faccessat Functions

As we described earlier, when we open a file, the kernel performs its access tests based on the effective user and group IDs. Sometimes, however, a process wants to test accessibility based on the real user and group IDs.

7 umask Function

Now that we’ve described the nine permission bits associated with every file, we can describe the file mode creation mask that is associated with every process.
The umask function sets the file mode creation mask for the process and returns the previous value.

For example, if we want to ensure that anyone can read a file, we should set the umask to 0.

8 chmod, fchmod, and fchmodat Functions

The chmod, fchmod, and fchmodat functions allow us to change the file access permissions for an existing file.

9 chown, fchown, fchownat, and lchown Functions

The chown functions allow us to change a file’s user ID and group ID.

10 File Size

The st_size member of the stat structure contains the size of the file in bytes. This field is meaningful only for regular files, directories, and symbolic links.

11 File Truncation

Sometimes we would like to truncate a file by chopping off data at the end of the file.

12 File Systems

We can think of a disk drive being divided into one or more partitions. Each partition can contain a file system, as shown in Figure 4.13. The i-nodes are fixed-length entries that contain most of the information about a file.

If we examine the i-node and data block portion of a cylinder group in more detail, we could have the arrangement shown in Figure 4.14.

Assume that we make a new directory in the working directory, as in:

1
mkdir testdir

Figure 4.15 shows the result. Note that in this figure, we explicitly show the entries for dot and dot-dot.

A file can have multiple directory entries pointing to its i-node. We can use either the link function or the linkat function to create a link to an existing file. To remove an existing directory entry, we call the unlink function.

14 rename and renameat Functions

A file or a directory is renamed with either the rename or renameat function.

A symbolic link is an indirect pointer to a file, unlike the hard links, which pointed directly to the i-node of the file.

17 File Times

18 futimens, utimensat, and utimes Functions

Several functions are available to change the access time and the modification time of a file.

19 mkdir, mkdirat, and rmdir Functions

Directories are created with the mkdir and mkdirat functions, and deleted with the rmdir function.

20 Reading Directories

21 chdir, fchdir, and getcwd Functions

Every process has a current working directory. This directory is where the search for all relative pathnames starts (i.e., with all pathnames that do not begin with a slash). When a user logs in to a UNIX system, the current working directory normally starts at the directory specified by the sixth field in the /etc/passwd file—the user’s home directory. The current working directory is an attribute of a process; the home directory is an attribute of a login name.

We can change the current working directory of the calling process by calling the chdir or fchdir function.

22 Device Special Files

The two fields st_dev and st_rdev are often confused.The rules for their use are simple.

  • Every file system is known by its major and minor device numbers, which are encoded in the primitive system data type dev_t. The major number identifies the device driver and sometimes encodes which peripheral board to communicate with; the minor number identifies the specific subdevice. Recall from Figure 4.13 that a disk drive often contains several file systems. Each file system on the same disk drive would usually have the same major number, but a different minor number.
  • We can usually access the major and minor device numbers through two macros defined by most implementations: major and minor.
  • The st_dev value for every filename on a system is the device number of the file system containing that filename and its corresponding i-node.
  • Only character special files and block special files have an st_rdev value. This value contains the device number for the actual device.

23 Summary of File Access Permission Bits

We’ve covered all the file access permission bits, some of which serve multiple purposes. Figure 4.26 summarizes these permission bits and their interpretation when applied to a regular file and a directory.

The final nine constants can also be grouped into threes, as follows:

1
2
3
S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR
S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP
S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH