CS604 - Operating Systems - Lecture Handout 10

User Rating:  / 0
PoorBest 

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

Summary

  • Input, output, and error redirection in UNIX/Linux
  • FIFOs in UNIX/Linux
  • Use of FIFOs in a program and at the command line

Input, output and error redirection in UNIX/Linux

Linux redirection features can be used to detach the default files from stdin, stdout, and stderr and attach other files with them for a single execution of a command. The act of detaching defaults files from stdin, stdout, and stderr and attaching other files with them is known as input, output, and error redirection. In this section, we show the syntax,
semantics, and examples of I/O and error redirection.

Input Redirection:

Here is the syntax for input redirection:

command < input-file

or

command 0< input-file

With this command syntax, keyboard is detached from stdin of ‘command’ and ‘inputfile’ is attached to it, i.e., ‘command’ reads input from ‘input-file’ and not keyboard. Note that 0< operator cannot be used with the C and TC shells. Here is an example use of input redirection. In these examples, the cat and grep commands read input from the Phones file and not from keyboard.

$ cat < Phones
[ contents of Phones ]
$ grep “Nauman” < Phones
[ output of grep ]
$

Output Redirection:

Here is the syntax for output redirection:

command > output-file

or

command 1> output-file

With this command syntax, the display screen is detached from stdout and ‘output-file’ is attached to it, i.e., ‘command’ sends output to ‘output-file’ and not the display screen.
Note that 1> operator cannot be used with the C and TC shells. Here is an example use of input redirection. In these examples, the cat, grep, and find commands send their outputs to the Phones, Ali.Phones, and foo.log files, respectively, and not to the display screen.

$ cat > Phones
[ your input ]
<Ctrl-D>
$ grep “Ali” Phones > Ali.phones
[ output of grep ]
$ find ~ -name foo -print > foo.log
[ error messages ]
$

Error Redirection:

Here is the syntax for error redirection:

command 2> error-file

With this command syntax, the display screen is detached from stderr and ‘error-file’ is attached to it, i.e., error messages are sent to ‘error-file’ and not the display screen. Note that 2> cannot be used under C and TC shells. The following are a few examples of error redirection. In these examples, the first find command sends its error messages to the errors file and the second find command sends its error messages to the /dev/null file.
The ls command sends its error messages to the error.log file and not to the display screen.

$ find ~ -name foo -print 2> errors
[ output of the find command ]
$ ls -l foo 2> error.log
[ output of the find command ]
$ cat error.log
ls: foo: No such file or directory
$ find / -name ls -print 2> /dev/null
/bin/ls
$

UNIX/Linux FIFOs

A named pipe (also called a named FIFO, or just FIFO) is a pipe whose access point is a file kept on the file system. By opening this file for reading, a process gets access to the FIFO for reading. By opening the file for writing, the process gets access to the FIFO for writing. By default, a FIFO is opened for blocking I/O. This means that a process reading from a FIFO blocks until another process writes some data in the FIFO. The same goes the other way around. Unnamed pipes can only be used between processes that have an ancestral relationship. And they are temporary; they need to be created every time and are destroyed when the corresponding processes exit. Named pipes (FIFOs) overcome both of these limitations. Figure 10.1 shows two unrelated processes, P1 and P2,
communicating with each other using a FIFO.

Communication between two related or unrelated processes

Named pipes are created via the mknod() system call or mkfifo() C library call or by the mkfifo command. Here is the synopsis of the mknod() system call.

#include <sys/types.h>
#include <sys/stat.h>
int mknod (const char *path, mode_t mode, dev_t dev);

The mknod() call is normally used for creating special (i.e., device) files but it can be used to create FIFOs too. The ‘mode’ argument should be permission mode OR-ed with S_IFIFO and ‘dev’ is set to 0 for creating a FIFO. As is the case with all system calls in UNIX/Linux, mknod() returns –1 on failure and errno is set accordingly. Some of the reasons for this call to fail are:

  • File with the given name exists
  • Pathname too long
  • A component in the pathname not searchable, non-existent, or non-directory
  • Destination directory is read-only
  • Not enough memory space available
  • Signal caught during the execution of mknod()

Here is the synopsis of the mkfifo() library call.

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo (const char *path, mode_t mode)

The argument path is for the name and path of the FIFO created, where was the argument mode is for specifying the file permissions for the FIFO. The specification of the mode argument for this function is the same as for the open(). Once we have created a FIFO using mkfifo(), we open it using open(). In fact, the normal file I/O system calls (close(), read(), write(), unlink(), etc.) all works with FIFOs. Since mkfifo() invokes the mknod() system call, the reasons for its failure are pretty much the same as for the mknod() call given above.

Unlike a pipe, a FIFO must be opened before using it for communication. A write to a FIFO that no process has opened for reading results in a SIGPIPE signal. When the last process to write to a FIFO closes it, an EOF is sent to the reader. Multiple processes can write to a FIFO are atomic writes to prevent interleaving of multiple writes.

Two common uses of FIFOs are:

  • In client-server applications, FIFOs are used to pass data between a server process and client processes
  • Used by shell commands to pass data from one shell pipeline to another, without creating temporary files

In client-server software designed for use on the same machine, the server process creates a “well-known” FIFO. Clients communicate send their requests to the server process via the well-known FIFO. Server sends its response to a client via the clientspecific FIFO that each client creates and informs the server process about it. Figure 10.2 shows the diagrammatic view of such a software model.

Use of FIFOs to implement client-server software

On the command line, mkfifo may be used as shown in the following session. As shown in Figure 10.3, the semantics of this session are that prog1 reads its inputs from infile and its output is sent to prog2 and prog3.

$ mkfifo fifo1
$ prog3 < fifo1 &
$ prog1 < infile | tee fifo1 | prog2
[ Output ]
$

Semantics of the above shell session

In the following session, we demonstrate the command line use of FIFOs. The semantics of this session are shown in Figure 10.4. The output of the second command line is the number of lines in the ls.dat file containing ls (i.e., the number of lines in the manual page of the ls command containing the string ls) and the output of the third command line is the number of lines in the ls.dat file (i.e., the number of lines in the manual page for the ls command).

$ man ls > ls.dat
$ cat < fifo1 | grep ls | wc -l &
[1] 21108
$ sort < ls.dat | tee fifo1 | wc -l
31
528
$

Pictorial representation