CS604 - Operating Systems - Lecture Handout 09

User Rating:  / 0
PoorBest 

Related Content: CS604 - VU Lectures, Handouts, PPT Slides, Assignments, Quizzes, Papers & Books of Operating Systems

Summary

  • UNIX/Linux interprocess communication (IPC) tools and associated system calls
  • UNIX/Linux standard files and kernel’s mechanism for file access
  • Use of pipe in a program and at the command line

Unix/Linux IPC Tools

The UNIX and Linux operating systems provide many tools for interprocess communication (IPC). The three most commonly used tools are:

  • Pipe: Pipes are used for communication between related processes on a system, as shown in Figure 9.1. The communicating processes are typically related by sibling or parent-child relationship.Pipe
  • Named pipe (FIFO): FIFOs (also known as named pipes) are used for communication between related or unrelated processes on a UNIX/Linux system, as shown in Figure 9.2.Named pipe (FIFO)
  • BSD Socket: The BSD sockets are used for communication between related or unrelated processes on the same system or unrelated processes on different systems, as shown in Figure 9.3.BSD Socket

The open() System call
The open() system call is used to open or create a file. Its synopsis is as follows:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char pathname, int oflag, /* mode_t mode */);

The call converts a pathname into a file descriptor (a small, non-negative integer for use in subsequent I/O as with read, write, etc.). When the call is successful, the file descriptor returned will be the lowest file descriptor not currently open for the process.
This system call can also specify whether read or write will be blocking or non-blocking.
The ‘oflag’ argument specifies the purpose of opening the file and ‘mode’ specifies permission on the file if it is to be created. ‘oflag’ value is constructed by ORing various flags: O_RDONLY, O_WRONLY, O_RDWR, O_NDELAY (or O_NONBLOCK), O_APPEND, O_CREAT, etc.

The open() system call can fail for many reasons, some of which are:

  • Non-existent file
  • Operation specified is not allowed due to file permissions
  • Search not allowed on a component of pathname
  • User’s disk quota on the file system has been exhausted

The file descriptor returned by the open() system call is used in the read() and write() calls for file (or pipe) I/O.

The read() system call

We discussed the read() system call in the notes for lecture 8. The call may fail for various reasons, including the following:

  • Invalid ‘fildes’, ‘buf’, or ‘nbyte’
  • Signal caught during read

The write() system call

The call may fail for various reasons, including the following:

  • Invalid argument
  • File size limit for process or for system would exceed
  • Disk is full

The close() system call

As discussed in the notes for lecture 8, the close() system call is used to close a file descriptor. It takes a file (or pipe) descriptor as an argument and closes the corresponding file (or pipe end).

Kernel Mapping of File Descriptors

Figure 9.4 shows the kernel mapping of a file descriptor to the corresponding file. The system-wide File Table contains entries for all of the open files on the system.
UNIX/Linux allocates an inode to every (unique) file on the system to store most of the attributes, including file’s location. On a read or write call, kernel traverses this mapping to reach the corresponding file.

Kernel Mapping of File Descriptors

Standard Descriptors in Unix/Linux

Three files are automatically opened by the kernel for every process for the process to read its input from and send its output and error messages to. These files are called standard files: standard input, standard output, and standard error. By default, standar d files are attached to the terminal on which a process runs. The descriptors for standard files are known as standard file descriptors. Standard files, their descriptors, and their default attachments are:

  • Standard input: 0 (keyboard)
  • Standard output: 1 (display screen)
  • Standard error: 2 (display screen)

The pipe() System Call

We discussed the pipe() system call in the notes for lecture 8. The pipe() system call fails for many reasons, including the following:

  • At least two slots are not empty in the PPFDT—too many files or pipes are open in the process
  • Buffer space not available in the kernel
  • File table is full

Sample Code for IPC with a UNIX/Linux Pipe

We discussed in the notes for lecture 8 a simple protocol for communication between a parent and its child process using a pipe. Figure 9.5 shows the protocol. Code is reproduced in Figure 9.6.

Sample Code for IPC with a UNIX-Linux Pipe

UNIX-Linux pipe for IPC

UNIX-Linux pipe for IPC 1

Command Line Use of UNIX/Linux Pipes

Pipes can also be used on the command line to connect the standard input of one process to the standard input of another. This is done by using the pipe operator which is | and the syntax is as follows:

cmd1 | cmd2 | ... | cmdN

The semantics of this command line are shown in Figure 9.7.

Command Line Use of UNIX-Linux Pipes

Figure 9.7 Semantics of the command line that connects cmd1 through cmdN via pipes.

The following example shows the use of the pipe operator in a shell command.

cat /etc/passwd | grep zaheer

The effect of this command is that grep command displays lines in the /etc/passwd file that contain the string “zaheer”. Figure 9.8 illustrates the semantics of this command.

Semantics of the cat -etc-passwd

The work performed by the above command can be performed by the following sequence of commands without using the pipe operator. The first command saves the /etc/passwd file in the temp1 file and the second command displays those lines in temp1 which contain the string “zaheer”. After the temp1 file has been used for the desired work, it is deleted.

$ cat /etc/passwd > temp1
$ grep “zaheer” temp1
$ rm temp1