Unix Power ToolsUnix Power ToolsSearch this book

43.11. Named Pipes: FIFOs

When you type a pipe symbol (|) on a command line, the two processes that communicate through the pipe must both have been started from that same shell. Newer versions of Unix have a way to let two unrelated processes (processes not started from the same parent process) communicate: a named pipe or FIFO (First In First Out).

A FIFO works like a pipe, but its interface looks like a file. It has a filename and permissions (Section 1.17), and it's in a directory. Once you make the FIFO, one process can write to it (with the shell's > operator, or directly) and another process can read from it (the shell's < operator, or directly). Unlike a regular file, though, a FIFO doesn't "fill up" with data as a process writes to it: if there's no process waiting to read the data, the data is lost. So, when you use a FIFO between two processes, the processes still need to coordinate with each other. There are times that temporary files are better.

Figure Go to http://examples.oreilly.com/upt3 for more information on: mkfifo

The command to make a FIFO is mkfifo. (The GNU version is on the CD-ROM [see http://examples.oreilly.com/upt3].) Like other files, the default permission is set by your umask. There's also a -m option that sets the permissions -- with a numeric or symbolic mode like chmod (Section 50.5) uses. To remove a FIFO, use -- you guessed it -- rm.

Let's look at an example that, although it's made up, shows some important things to know about FIFOs. If you're using a window system, you'll use two terminal windows (like xterm (Section 24.20)); you'll write to the FIFO from one window and read it from the other. Or if you have two terminals, you can use both of them. Otherwise, with a single terminal, you can put the writing process in the background (Section 23.2) and run the reading process in the foreground.[131]

[131]This may take some juggling because your system may require you to start the reading process before the writing process. If it does, and if your system has job control (Section 23.3), do this: start the reading process, stop it with CTRL-z, start the writing process in the background, then bring the reading process to the foreground.

Start by making the FIFO. You can make it from any window. (The FIFO stays in the filesystem until you remove it. You can use it over and over again, though only one pair of processes can use it at any one time.) Then have a look with ls; the FIFO has zero size, it has a p type in the -l output and a | symbol from -F:

-F Section 8.10

$ mkfifo /tmp/fifo
$ ls -l /tmp/fifo
prw-rw-r--    1 jpeek    jpeek           0 Dec 30 00:25 /tmp/fifo
$ ls -F /tmp/fifo
/tmp/fifo|

Next, start the process that reads from the FIFO. Like a program that's reading from a regular (anonymous) pipe, the process will block (sit there doing nothing) until there's something to read. For now, plain cat (Section 12.2) is a good choice:

$ cat /tmp/fifo
   ...nothing (yet)...

To write to the FIFO, here's a little shell script (Section 35.1) that sends the current date and time to its standard output every three seconds. You could name it dater:

while Section 35.15, sleep Section 24.9

#!/bin/sh

while sleep 3
do date
done

In the other window or terminal, start dater and redirect its output to the FIFO. The process will run, writing data to the FIFO periodically:

$ dater > /tmp/fifo

In your window running cat, the dates should start to appear. When you kill the writing process (or it finishes by itself), the reader should terminate.

Also try reading from the FIFO with any other Unix program, like the pr (Section 45.6) formatter with its -l15 option (to make output pages 15 lines long, so you don't have to wait too long to see the next page header). This makes a nice illustration of the way that standard pipes, as well as named pipes, work: dribbling output to the reading process as the writing process makes it. (Standard pipes may be buffered, though, passing output in larger chunks.)

If you have a third terminal or window, and you start another reading process (like cat /tmp/fifo) there, it will block until you kill the first reading process (the previous cat /tmp/fifo).

This can be good food for thought. For instance, what output do you see when tail (Section 12.8) reads from a pipe or FIFO? (Answer: nothing until the writing process dies.)

To review, though, a FIFO is useful anytime two processes need to communicate but those processes weren't started from the same parent process, so a traditional pipe can't work (because the second process can't access the open file descriptor from the first process).

-- JP



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.