Mac OS X Internals: A Systems Approach

11.5. Files and File Descriptors

At the system call level, Mac OS X represents open files in a process by using integral file descriptors, each of which is an index into the process's file descriptor table in the kernel. When a user program uses a file descriptor in a system call, the kernel uses the file descriptor to find the corresponding file data structure, which in turn contains informationsuch as a function-pointer tableusing which I/O can be performed on the file. This scenario is conceptually the same across Unix and Unix-like systems. However, the specific data structures involved are often different. Figure 1111 shows the primary file-related kernel data structures in Mac OS X.

Figure 1111. How a file descriptor leads to a file in Mac OS X

Let us assume there is a file descriptor called fd in a process with ID pid. Each process structure (struct proc) contains a pointer (p_fd) to a filedesc structure, which holds information about the process's open files. In particular, it contains pointers to two arrays: an array of fileproc structures (fd_ofiles) and an array of open file flags (fd_ofileflags). In the case of our file descriptor fd, the elements with index fd in both these arrays will correspond to the file fd represents. If a descriptor is released (because it has no remaining references), that index in both arrays becomes free. The fd_freefile field of the filedesc structure is used to store a hint that the kernel uses while searching for a free file descriptor.

As Figure 1111 shows, each entry of the fd_ofiles array is a fileproc structure. The fg_ops and fg_data fields of this structure point to data structures whose contents depend on the file descriptor's type. Besides files, the kernel uses file descriptors to represent several types of entities, which are listed in Table 111. Figure 1111 assumes that fd corresponds to a file. Therefore, fg_ops points to a table of vnode operations[6] (the global data structure vnops), whereas fg_data points to a vnode structure. If the descriptor represented a socket instead, fg_ops would point to a table of socket operations, and fg_data would point to a socket structure.

[6] There are far more vnode operations than are contained in a fileops structure, which is more relevant for "nonfile" file descriptorsvnode operations can be accessed through the vnode structure itself.

Table 111. Types of File Descriptors in Mac OS X

File Type

fg_data Points to an Instance of This Structure

fg_ops Points to This Operation Table

DTYPE_VNODE

struct vnode

vnops

DTYPE_SOCKET

struct socket

socketops

DTYPE_PSXSHM

struct pshmnode

pshmops

DTYPE_PSXSEM

struct psemnode

psemops

DTYPE_KQUEUE

struct kqueue

kqueueops

DTYPE_PIPE

struct pipe

pipeops

DTYPE_FSEVENTS

struct fsevent_handle

fsevents_ops

Категории