CPS 346 & 444/544 Lecture notes: I/O Redirection, and
Pipes and FIFOs
Coverage: [USP] §4.7
(pp. 128-132) and
§§6.1-6.4
(pp. 183-202)
Implementing I/O redirection
redirecting stdout from the display to a disk file
- open disk file
- copy file descriptor for disk file
into entry for stdout;
use dup2,
involves an implicit close on the target of the copy
- close disk file using
its file descriptor
(regenerated with minor modifications from [USP] Fig. 4.7, p. 131)
(regenerated with minor modifications from [USP] Fig. 4.6, p. 130)
Helpful functions
- fileno(stdin): returns the file descriptor for stdin
- dup(fileno(stdin)): returns a copy of its file descriptor
argument
- isatty(desc): returns 1 if file descriptor desc
is an open descriptor connected to a terminal and 0 otherwise
Simple (unnamed) pipes
- a process communication buffer
- basic ingredient for interprocess communication (IPC) in UNIX
- data written to filedes[1] can be read
from filedes[0] using FIFO
- created with pipe function
- read blocks until something is written to the pipe
- can be used as a synchronization mechanism
- can be used to create a barrier
- not very useful for a single process
- only usable by a process which calls fork
and its descendants
Setting up pipelines in C
- grep cats pets > _text
- wc -l < num_cats
- grep cats pets | wc -l
- ps -A | grep grep
- traditionally, but perhaps non-intuitively, the command to the right of the
pipe symbol (|) is the parent of that to the left of it in the
command line
- blocking nature of read and write synchronize the
processes
- use pipe and dup2 functions in concert to setup a
pipeline
Implementing ls -l | sort -n +4
- unifies many concepts we have learned
- process creation and image swapping
- low level I/O
- interprocess communication
- why return only error conditions?
- graphical (octopus-looking) depiction of the changes to the file descriptor table before and after system calls
- after call to fork
(regenerated from [USP] Fig. 6.2, p. 191)
- after both calls to dup2
(regenerated from [USP] Fig. 6.3, p. 191)
- after all calls to close
(regenerated from [USP] Fig. 6.4, p. 192)
Named pipes (or FIFOs)
- pipes are temporary, FIFOs area permanent (until you unlink)
- useful when the processes communicating were not
created with fork
- created with mkfifo function call or UNIX command
- resulting file
contains p as the character to left of its file permission list
in ls -l output
- beauty of UNIX: unified file access interface
- regular files
- FIFOs
- terminals
- leads to a simple client-server model
- note:
data written to named pipes on our system is not line buffered;
- must explicitly call fflush(stdout), or
- use setvbuf to turn line buffering on
Note about pipes
- writes to pipes are atomic (contrast with fprintf)
- reads from pipes are not atomic
Observations on client-server programs
- first version
- simple-request: a one-way communication protocol;
clients send information to server
- why does server open pipe for writing, even
though it will never write to it?
- client cannot cause server to terminate
- second version
- request-reply: a two-way communication protocol
- request pipe: client sends a request (`g')
- sequence pipe: server sends a reply (sequence `#')
- difficult to implement with only one named pipe
- server replies (i.e., the sequence #) can be read by any client
because of the single, shared pipe;
side-effect of non-atomic reads
- possible erroneous outcomes
- partial input (e.g., read only 2 bytes)
- complete, but incorrect, input due to the interleaving
- quick fix: have client who read partial input send an error code
(`e') to the server on the request pipe to cause it to terminate
- causes all future clients to block
- causes all pending clients to terminate (writing to an unopened pipe)
- secure? absolutely not
- a malicious client could intentionally bring down the server
- moral of the story: a client should never have the capability to
shut down the server
- better solution:
each client communicates to the server through its own
individual named pipe
Experimental runs of client-server programs
- one server, several clients (version one; [USP] exercise 6.12)
- one server, two clients (version two; [USP] exercise 6.13)
- two servers, one client (version two; [USP] exercise 6.14);
it is possible that the client will get the same sequence #
twice
References
| [USP] |
K.A. Robbins and S. Robbins.
UNIX Systems Programming: Concurrency, Communication, and Threads.
Prentice Hall, Upper Saddle River, NJ, Second edition, 2003.
|
|