Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

How to clear named pipe to just have one line

by techman2006 (Beadle)
on Feb 08, 2014 at 12:54 UTC ( #1073995=perlquestion: print w/replies, xml ) Need Help??
techman2006 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to have a named pipe with only one line at time. As this named pipe will be read by another program may be a C/C++ program I can't delete before doing that operation.

Below is a sample code which I am trying to put.

use strict; use warnings; use POSIX qw(mkfifo); my $path = "./test_fifo"; unless ( -p $path) { mkfifo($path, 0666) or die "can't mknod fpath: $!"; warn "$0: created $path as a named pipe\n"; } while (1) { open(FIFO, "+> $path") or die "Couldn't open $path for writing: $!\n"; #truncate(FIFO, 0) or die "Can't reduce size to 0 $!\n"; print FIFO "The current time is ", scalar(localtime), "\n"; close FIFO; sleep(1); }

Any thoughts how to do it.

Replies are listed 'Best First'.
Re: How to clear named pipe to just have one line
by moritz (Cardinal) on Feb 08, 2014 at 13:13 UTC

    I don't think it's possible; if you read from a (named) pipe, its content is gone. So you can't read to check how much is in there.

    Usually you don't need it either, since named pipes are buffered, and once the buffer is full, writing to it blocks. And, more to the point, you shouldn't even care how much is in the pipe; pipes are there to abstract that away.

    What problem are you actually trying to solve? It could be an XY Problem.

      Basically there are two unrelated processes say P1 (A C program) and P2(a Perl script). Now P2 is running and is output some data to stdout. Now P1 will come at regular interval to read such data.

      As these are unrelated processes. So I was thinking to use named pipe. Now process P1 want to read only one line which is output from process P2. As it continuously generates output we want to truncate the data so that process P1 don't read redundant data.

      Any thoughts how to solve this problem.

Re: How to clear named pipe to just have one line
by graff (Chancellor) on Feb 10, 2014 at 06:32 UTC
    The way you've written your sample perl script (P2) for writing to the fifo, there could never be more than one line in the pipe; the open statement, having one ">" in the mode flag, always truncates the file on opening. Then you write one line and close the fifo.

    (I don't understand why you include "+" in the open mode - it allows your script to have read access as well as write access, but you don't seem to need that.)

    If you know enough about the behavior of the other program, perhaps you can write a simple perl script to emulate how that program reads from a file, then use the perl script to see what happens when you run it at the same time as your sample P2 script.

    I don't recall ever using named pipes in any serious way, so playing the the following two scripts was instructive for me:

    Script for writing to pipe:

    #!/usr/bin/perl use strict; use warnings; use POSIX 'mkfifo'; my $fifo = "/tmp/named.pipe"; unless ( -p $fifo ) { mkfifo( $fifo, 0666 ) or die $!; } while (1) { open( my $fh, '>', $fifo ); my $t = scalar localtime; warn "writing to fifo at $t\n"; print $fh "written at $t\n"; close $fh; sleep 2; }

    Script for reading from pipe:

    #!/usr/bin/perl use strict; use warnings; my $input = "/tmp/named.pipe"; die "$input is not really a named pipe\n" unless (-p $input); while(1) { my $t = scalar localtime; warn "opening input at $t\n"; open( my $p, "<", $input ) or die $!; $_=<$p>; print "got: $_" }
    I noticed these behaviors:
    • Either script could be started first, but nothing would happen until both were running.
    • Once both were running, output from both could continue indefinitely, one line every two seconds.
    • If I killed the writer, the reader would keep running, and just would not show any more output until I restarted the writer.
    • If I killed the reader, the writer would finish (terminate) on its next iteration.
    The simple reader script above differs from the typical unix program in that it repeatedly opens and closes a given file. Here's a different reader, more like the typical unix program because it opens a file, reads it until there's an end-of-file condition, then exits:
    #!/usr/bin/perl use strict; use warnings; my $input = "/tmp/named.pipe"; die "$input is not really a named pipe\n" unless (-p $input); my $t = scalar localtime; warn "opening input at $t\n"; open( my $p, "<", $input ) or die $!; while(<$p>) { $t = scalar localtime; print "reading at $t, got: $_" }
    In this case, I can still start either writer or reader first, nothing happens till both are running, and then they both show continuous output every 2 seconds, but now if either one is stopped, then the other will also stop.

    Other variations might be worth trying… but as moritz mentioned, we don't know enough yet about what you are actually trying to accomplish.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1073995]
Approved by moritz
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2017-06-24 06:32 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (557 votes). Check out past polls.