--- name: FIFOs tutorial --- # FIFOs A FIFO - a *named pipe* - is a pipe with a name on the filesystem. Two programs that share no parent, started independently from different shells, can still talk: one opens the path for writing, the other opens it for reading, and bytes flow between them exactly as through an anonymous [`pipe`](../../p5/core/perlfunc/pipe). The path is a rendezvous point; no data is ever stored in the file itself. This is the channel to reach for when the processes are *unrelated* - when a plain `pipe` is impossible because there was never a common `fork` to inherit the descriptor from. ## Creating the FIFO A FIFO is created once, as a special file, with `POSIX::mkfifo`. After that it is opened like any other path: ```perl use POSIX qw(mkfifo); my $path = "/tmp/demo.fifo"; mkfifo($path, 0600) or die "mkfifo $path: $!"; ``` The second argument is the permission mode, the same `0600` / `0644` you would pass to [`chmod`](../../p5/core/perlfunc/chmod) - it decides who may open the FIFO. The call fails if the path already exists, so a long-running setup typically `unlink`s a stale FIFO first. ## Producer and consumer The defining behaviour of a FIFO is that **`open` blocks until both ends are present**. A reader opening the path waits until some writer opens it too, and vice versa. That rendezvous is the feature: it synchronises two programs that never agreed on timing. This single program demonstrates both ends by forking, but the two halves would work just as well as two separate scripts run from two terminals: ```perl use POSIX qw(mkfifo); my $path = "/tmp/demo.fifo"; unlink $path; # clear any stale FIFO mkfifo($path, 0600) or die "mkfifo $path: $!"; my $kid = fork() // die "fork: $!"; if ($kid == 0) { # Producer: open for writing (blocks until a reader appears). open my $w, ">", $path or die "producer open: $!"; $w->autoflush(1); print $w "from-producer\n"; close $w; exit 0; } # Consumer: open for reading (blocks until a writer appears). open my $r, "<", $path or die "consumer open: $!"; my $line = <$r>; print "consumer read: $line"; # consumer read: from-producer close $r; waitpid($kid, 0); unlink $path; # remove the FIFO when finished ``` The two `open` calls are the synchronisation. Whichever process reaches its `open` first parks there until the other arrives; then both proceed together. Once open, the read and write handles behave like the two ends of any pipe - line reads, [`readline`](../../p5/core/perlfunc/readline), buffered [`print`](../../p5/core/perlfunc/print), all unchanged. Two practical notes: - **Autoflush on the writer.** As with every pipe and socket, a buffered write may never reach the reader until the buffer fills or the handle closes. Set `autoflush(1)` if the reader expects each line as it is produced. - **A FIFO persists on disk.** `mkfifo` leaves a special file behind that outlives both processes. Remove it with [`unlink`](../../p5/core/perlfunc/unlink) when the conversation is over, the same way you would clean up a lock file. ## Reference cross-links - [`open`](../../p5/core/perlfunc/open) - open the FIFO path for reading or writing - [`pipe`](../../p5/core/perlfunc/pipe) - the anonymous-pipe relative for related processes - [`unlink`](../../p5/core/perlfunc/unlink) - remove the FIFO when finished - [`readline`](../../p5/core/perlfunc/readline) - the function behind `<$fh>` ## Next When two processes need a connection rather than a one-way path - request and reply, both directions at once - reach for a socket. See [UNIX-domain and UDP sockets](sockets-unix-udp) and [TCP sockets](sockets-tcp).