leighsharpe has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,
Is there any way to monitor whether or not a named pipe has data to give, without opening it?
I want to do something like this:
my $dbh=DBI->connect("DBI:mysql:database=pings;host=$host;mysql_connec +t_timeout=10","$user","$password") or die "$!\n"; $sth=$dbh->prepare("LOAD DATA LOCAL INFILE 'MYFIFO' INTO TABLE $table +FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'") or print "$!\n".$ +dbh->{'mysql_error'}; $sth->execute() or print "$!\n".$dbh->{'mysql_error'}; $sth->finish() or print "$!\n".$dbh->{'mysql_error'}; $dbh->disconnect() or print "Trouble disconnecting! $!\n";
The problem is that if I execute the LOAD DATA INFILE whilst there is nothing writing to MYFIFO, the server times out and the operation fails. I would much rather do something like this:
while (1) { if (fifo_is_ready()) { # Connect to database # LOAD DATA LOCAL INFILE 'MYFIFO' etc. etc. # Disconnect } else { sleep(2); } }
But I don't know how to keep an eye on that FIFO. It gets more complicated by the fact that I need to lock tables prior to writing, but I don't want to go locking tables until I know that I'm ready to write data to them.
Any ideas?

Replies are listed 'Best First'.
Re: Watching a named pipe
by cdarke (Prior) on Feb 26, 2009 at 09:39 UTC
    The simple answer to your question is no, but... Normally attempting to open a pipe with no writer for read will block (I assume this is *nix), but you can use sysopen with O_NONBLOCK or O_NDELAY. Opening with O_NONBLOCK should return the number of bytes read as -1 on read, and set $! to EAGAIN, or returns 0 if there is no writer; using O_NDELAY just returns 0 if the pipe is empty.

    The downside is that when you do have data in the pipe you may have to loop until you get the number of bytes required, since there might have been a partial write.
    Update: corrected some wording
Re: Watching a named pipe
by lostjimmy (Chaplain) on Feb 26, 2009 at 01:59 UTC

    I know you said you don't want to open it first, but I don't know if there is any other way to do it.

    What if you did something like this? (untested):

    use IO::Select; open my $fh, "<", $fifo or die "couldn't open $fifo: $!"; my $sel = IO::Select->new($fh); if ($sel->can_read(0.1)) { close $fh; do_database_stuff(); }
      More simply:
      open FH, $fifo or die $!; while (select($ready = fileno(FH), undef, undef, undef)) { # do stuff... }
Re: Watching a named pipe
by plobsing (Friar) on Feb 26, 2009 at 00:24 UTC

    There are probably better ways, but ignoring read fails seems to work:

    use 5.10.0; open my $fh, "<", "fifo" or die; while (1) { my ($line) = <$fh> or sleep 1 and redo; chomp $line; say "FIFO> $line"; }

    Update: just realized it blocks until there's a writer the first time. A hack avoiding this is arranging to have one line written to the fifo and ignoring this line. Like I said before, there are probably better ways.

Re: Watching a named pipe
by zentara (Cardinal) on Feb 26, 2009 at 16:34 UTC