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

Hello, Monks,

I'm trying to autoflush pipe, but it doesn't work.
#!/usr/bin/perl -w use strict; use IO::Handle; use POSIX qw /mkfifo/; mkfifo "fifo", 0777 unless (-p "fifo"); pipe (PARENTR, SAPW); pipe (SAPR, PARENTW); SAPW->autoflush(1); PARENTW->autoflush(1); my $pid = fork; if ($pid) { close PARENTR; close PARENTW; while (1) { open FIFOR, "fifo"; my $line = <FIFOR>; close FIFOR; print SAPW $line; close SAPW; # don't want this print <SAPR>; } } else { close SAPR; close SAPW; open STDIN , '<&PARENTR'; open STDOUT, '>&PARENTW'; exec "cat"; die $!; }
As you see, I have to close pipe SAPW, but I need it for next whiles.

Thank for your help.

Replies are listed 'Best First'.
Re: Pipe autoflush
by almut (Canon) on Aug 23, 2007 at 12:33 UTC

    I think your problem is that you're reading from SAPR in list context (because of the print), so it's trying to read too much, and thus blocks...  Try

    print scalar <SAPR>;

    or

    my $sap_line = <SAPR>; # scalar context print $sap_line;

    In that case you don't have to close SAPW.

      Works. Thank you very much!

      UPDATE

      ...but only for cat. For other programs, for example md5sum, not.

        Smooth communication depends on both sides agreeing on a common protocol. Not all programs operate in a line based fashion like cat. For example, if you're having md5sum read its data from stdin (instead of supplying a list of filenames), it is reading the entire input (which may include newlines), then prints the digest of that data to stdout, and quits. IOW, simply replacing cat with md5sum in the code above can't work.

        If you let us in on what you're ultimately trying to achieve, we might be able to provide better assistance... :)

Re: Pipe autoflush
by technojosh (Priest) on Aug 23, 2007 at 14:18 UTC
    I try to make a habit, when I need autoflush on, of setting:
    $| = 1;

    near the start of my script

      That would autoflush the currently selected file handle, usually STDOUT. That would be totally useless here.