Pipes and FIFOs

Pipes form a basic unidirectional, self-synchronous means of communication between processes. As the name suggests, they have two ends: one where a process writes and the opposite end from where another process reads the data. Presumably what goes in first will be read out first in this kind of a setup. Pipes innately result in communication synchronization due to their limited capacity: if the writing process writes much faster than the reading process reads, the pipe’s capacity will fail to hold excess data and invariably block the writing process until the reader reads and frees up data. Similarly, if the reader reads data faster than the writer, it will be left with no data to read, thus being blocked until data becomes available.

Pipes can be used as a messaging resource for both cases of communication: between related processes and between unrelated processes. When applied between related processes, pipes are referred to as unnamed pipes, since they are not enumerated as files under the rootfs tree. An unnamed pipe can be allocated through the pipe() API.

int pipe2(int pipefd[2], int flags);

API invokes a corresponding system call, which allocates appropriate data structures and sets up pipe buffers. It maps a pair of file descriptors, one for reading on the pipe buffer and another for writing on the pipe buffer. These descriptors are returned to the caller. The caller process normally forks the child process, which inherits the pipe file descriptors that can be used for messaging.

The following code excerpt shows the pipe system call implementation:

SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
{
struct file *files[2];
int fd[2];
int error;

error = __do_pipe_flags(fd, files, flags);
if (!error) {
if (unlikely(copy_to_user(fildes, fd, sizeof(fd)))) {
fput(files[0]);
fput(files[1]);
put_unused_fd(fd[0]);
put_unused_fd(fd[1]);
error = -EFAULT;
} else {
fd_install(fd[0], files[0]);
fd_install(fd[1], files[1]);
}
}
return error;
}

Communication between unrelated processes requires the pipe file to be enumerated into rootfs. Such pipes are often called named pipes, and can be created either from the command line (mkfifo) or from a process using the mkfifo API.

int mkfifo(const char *pathname, mode_t mode);

A named pipe is created with the name specified and with appropriate permissions as specified by the mode argument. The mknod system call is invoked for creating a FIFO, which internally invokes VFS routines to set up the named pipe. Processes with access permissions can initiate operations on FIFOs through common VFS file APIs open, read, write, and close.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.66.206