#!/usr/bin/perl # logFifo # This script illustrates how to have a fifo that processes textual input. # Run this script and then write (e.g. with 'echo') to the fifo. # Each message sent will be output to STDOUT tagged with the current time. # # Cameron Hayne (macdev@hayne.net) Nov 2006 use warnings; use strict; use POSIX qw(mkfifo); use Time::HiRes qw(time); my $scriptname = "logFifo"; die "Usage: $scriptname: name_of_fifo\n" unless scalar(@ARGV) == 1; my $fifoName = $ARGV[0]; sub fatalError($) { my ($msg) = @_; print STDERR "$scriptname: $msg\n"; finish(); } sub createFifo() { mkfifo($fifoName, 0666) or fatalError("name: can't mkfifo $fifoName: $!"); } sub removeFifo() { unlink($fifoName); } sub finish() { removeFifo(); exit; } sub openFifo() { open(FIFO, "< $fifoName") or fatalError("can't read $fifoName: $!"); #print "Somebody is writing to the fifo $fifoName\n"; } sub readFromFifo() { while () { chomp(); my $time = time(); print "$time: $_\n"; } } sub closeFifo() { #print "Closing fifo\n"; close(FIFO); } MAIN: { # catch control-C and "kill" and clean up $SIG{INT} = $SIG{TERM} = sub { $SIG{INT} = $SIG{TERM} = 'DEFAULT'; finish() }; # install an alarm handler that closes the fifo (to avoid denial of service) $SIG{ALRM} = sub { closeFifo() }; createFifo(); while (1) { alarm(0); # next line blocks until there's a writer openFifo(); alarm(3); # allow 3 seconds for the writer to finish readFromFifo(); closeFifo(); } }