CS 3733 Operating Systems Notes: USP Chapter 6: UNIX Special Files



Pipes
From the command line:
ls -l | sort -nr +4 | head
produces a list of files sorted by size with only the largest ones displayed.
This is implemented with the pipe system call:

#include <unistd.h>

int pipe(int fildes[2]);
Program 6.1, parentwritepipe, on page 185 shows a program in which the parent writes to a pipe and the child reads from it.

Program 6.2, synchronizefan, on page 187 shows a process fan in which the parent writes n bytes to a pipe and then each process reads one byte from the pipe.
No processes can continue until all processes have been created.

Example 6.5, page 188:
ls -l | sort -nr +4
Figure 6.1 shows how the pipe and the processes are connected.

Program 6.3, simpleredirect, on page 190 shows how this might be implemented.

Figures 6.2 through 6.4 shoud the status of the program as it progresses.

Figure 6.1 (page 189): Status of the file descriptor table during the execution of Example 6.5.

Figure 6.2 (page 191): Status of the file descriptor table after the fork in Program 6.3.

Figure 6.3 (page 191): Status of the file descriptor table after both dup2 functions in Program 6.3.

Figure 6.4 (page 192): Status of the file descriptor table after all close calls in Program 6.3.

FIFOs
FIFOs, or named pipes allow you to use pipes between processes that are not related.
You can create a named pipe with the mkfifo command or the mkfifo system call.

#include <sys/stat.h>

int mkfifo(const char *path, mode_t mode);
Program 6.4, parentchildfifo, on page 194 creates a named pipe.
The child executes dofifochild, Program 6.5 on page 195 and the parent executes dofifoparent, Program 6.6 on page 196.
Only the name of the pipe is passed to the parent and child routines.


Pipes and the Client-Server Model
In the client-server model of communication:

Program 6.7, pipeserver, on page 197 is a server process that creates a pipe (if necessary) and opens the pipe. Whatever it receives from the pipe it outputs to standard output.

Program 6.8, pipeclient, on page 198 is a client process that opens the named pipe for writing and copies everyting from standard input to the pipe.

Important property of pipes and FIFOs:
A write of at most PIPE_BUF bytes to a pipe or FIFO is atomic.
Note that reads are not necessarily atomic.


Terminal Control
Terminals are represented by special files that with additional control features that determine such things as when input is delivered to the terminal and how input and output are related.

Terminals are controlled from the command line with the stty command.

stty [-a | -g]
stty operands
The first form reports information about the terminal.
The -a form produces all information available.
The -g form produces a single line of numbers.

Programs access terminal characteristics through a structure of type struct termios.
This structure contains at least the following members:

   tcflag_t    c_iflag;       /* input modes */
   tcflag_t    c_oflag;       /* output modes */
   tcflag_t    c_cflag;       /* control modes */
   tcflag_t    c_lflag;       /* local modes */
   cc_t        c_cc[NCCS];    /* control characters */
The c_cc array holds the values of characters that have special meaning to the terminal device drivers, such as the end-of-file character (usually CTRL-D) and the interrupt character (usually CTRL-C).

How these characters behave is determined by the mode of the terminal, either canonical or noncanonical.
The special control cahracters are listed in Table 6.1 on page 206.

canonical mode noncanonical mode description usual default
VEOF EOF character CTRL-D
VEOL EOL character none
VERASE ERASE character backspace or delete
VINTR VINTR INTR character CTRL-C
VKILL KILL character CTRL-U
VMIN MIN value 1
VQUIT VQUIT QUIT character CTRL-\
VSUSP VSUSP SUSP character CTRL-Z
VTIME TIME value 0
VSTART VSTART START character CTRL-Q
VSTOP VSTOP STOP character CTRL-S
Table 6.1, page 206: The POSIX special control characters.

The other fields of the termios structure are described in Table 6.2 on page 210.

field flag description
c_iflag BRKINT signal interrupt on break
ICRNL map CR to NL on input
IGNBRK ignore break condition
IGNCR ignore CR
IGNPAR ignore characters with parity errors
INLCR map NL to CR on input
INPCK enable input parity check
ISTRIP strip character
IXOFF enable start/stop input control
IXON enable start/stop output control
PARMRK mark parity errors
c_oflag OPOST postprocess output
OCRNL map CR to NL on output (POSIX:XSI Extension)
ONOCR no CR output at column 0 (POSIX:XSI Extension)
ONLRET NL performs CR function (POSIX:XSI Extension)
c_cflag CSIZE character size (CS5-CS8 for 5 to 8 bits)
CSTOPB send two stop bits, else one
CREAD enable receiver
PARENB enable parity
PARODD odd parity, else even
HUPCL hang up on last close
CLOCAL ignore modem status lines
c_lflag ECHO enable echo
ECHOE echo ERASE as an error-correcting backspace
ECHOK enable KILL
ECHONL echo a newline
ICANON canonical input (erase and kill processing)
IEXTEN enable extended (implementation-defined) functions
ISIG enable signals
NOFLSH disable flush after interrupt, quit, or suspend
TOSTOP send SIGTTOU for background output \hline
Table 6.2, page 210: The POSIX values of flags for terminal control.

Two functions are used to get and set the termios structure:

  #include <termios.h>

  int tcgetattr(int fildes, struct termios *termios_p);
  int tcsetattr(int fildes, int optional_actions,
                const struct termios *termios_p);

Program 6.11, ttysetchar, on page 206 shows how to set a particular control character.
Program 6.12, setecho, on page 207 shows how to turn echo on or off.
Program 6.13, passwordnosigs, on page 208 shows how to prompt for a password with the echo off.


Noncaononical Mode
In noncanonical mode the editing characters such as ERASE and KILL no longer work. Characters are delivered to the program based on two parameters, MIN and TIME.
case meaning
MIN > 0, TIME > 0 TIME is an interbyte timer.
If TIME expires or MIN bytes are received, read is satisfied.
MIN > 0, TIME = 0 read blocks until at least MIN bytes received.
MIN = 0, TIME > 0read is satisfied when a single byte arrives or TIME expires
MIN = 0, TIME = 0 minimum of number of bytes requested or number of bytes available returned
Table 6.3, page 211: Parameters for noncanonical mode processing.

When setting noncanonical mode, you should do the following:

Unfortunately, you cannot just unset noncanonical mode because on some systems the locations used for MIN and TIME are used by VEOF and VEOL.

Program 6.14, setnoncanonical, on page 212 sets noncanonical mode.
It uses ttsetchar from Program 6.11.

Program 6.15, savetermios, on page 213 can be used to save and restore the termios structure.