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

Hello Monks,

i'm trying to test a module that should read data from file descriptor 3. I've write this code but i can't read from the file even if the files are flushed or autoflushed.

my expected output is:

aaaaaaaaaa
bbbbbbbbbb
bbbbbbbbbb
aaaaaaaaaa
bbbbbbbbbb

This is the code i'm working on

use strict; use warnings; use IO::Handle; use IO::File; my $ftmp = new IO::File "> test_eagi.tmp"; unless ( defined $ftmp) { die "Couldn't open (test_eagi.tmp)\n"; } if ( fileno($ftmp) == 3 ) { print "open file with fd 3\n"; } else { die "ERROR: file opened with fd : ".fileno($ftmp)."\n"; } $| = 1; $ftmp->autoflush(1); my $fh_in = new IO::Handle; my $fh_out = new IO::Handle; my $buff; my $blen = 10; $fh_in->fdopen(3,'w') || die "No se pudo abrir fh_in\n$!\n"; $fh_out->fdopen(3,'r') || die "No se pudo abrir fh_out\n$!\n"; #$fh_out->autoflush(1); $fh_in->autoflush(1); my $data_a = 'a'x10; my $data_b = 'b'x20; print "data a: ($data_a)\n"; print "data b: ($data_b)\n"; my $r = $fh_in->write($data_a,10); $fh_in->flush; $fh_out->read($buff,$blen); print "$buff\n"; $fh_in->write($data_b,20); $fh_out->read($buff,$blen); print "$buff\n"; $fh_in->write($data_a,10); $fh_out->read($buff,$blen); print "$buff\n"; $fh_in->write($data_b,20); $fh_out->read($buff,$blen); print "$buff\n"; $fh_out->read($buff,$blen); print "$buff\n"; $fh_out->close(); $fh_in->close(); $ftmp->close();

Replies are listed 'Best First'.
Re: testing interface
by almut (Canon) on Sep 25, 2009 at 19:38 UTC

    You'd need to open the file in read-write mode ("+>") and also reset the file pointer to the beginning of the file between every write and read cycle (or seek to where it was before the write) — otherwise, you'd try to read from the position where the write has left the file pointer...

    Anyhow, maybe you rather want a pipe?

      use strict; use warnings; use Fcntl qw( SEEK_SET ); use IO::Handle qw( ); my $qfn = 'test_eagi.tmp'; open(my $fh, '+>', $qfn) or die("Can't create \"$qfn\": $!\n"); $fh->autoflush(1); ( my $pos = tell($fh) ) >= 0 or die("tell: $!\n"); $fh->write('abcde') or die("write: $!\n"); seek($fh, $pos, SEEK_SET) or die("seek: $!\n"); my $buf = ''; while (!$fh->eof) { $fh->read($buf, 4096, length($buf)) or die("read: $!\n"); } print "$buf\n";

        Thanks a lot for your help. Finally i solved it, mixing a little of everything. Maybe i should say before that i'm doing this in order to unit test a class wich will comunicate with Asterisk and get audio from EAGI interface wich writes the audio in fd=3.

        use strict; use warnings; use IO::Handle; use IO::File; my $ftmp = new IO::File ("test_eagi.tmp",'r+'); unless ( defined $ftmp) { die "Couldn't open (test_eagi.tmp)\n"; } if ( fileno($ftmp) == 3 ) { print "open file with fd 3\n"; } else { die "ERROR: file opened with fd : ".fileno($ftmp)."\n"; } $| = 1; $ftmp->autoflush(1); my $fh_in = new IO::Handle; my $fh_out = new IO::Handle; my $buff; my $blen = 10; $fh_out->fdopen(3,'r') || die "No se pudo abrir fh_out\n$!\n"; #$fh_out->autoflush(1); $fh_in->autoflush(1); my $data_a = 'a'x10; my $data_b = 'b'x20; print "data a: ($data_a)\n"; print "data b: ($data_b)\n"; tswrite($data_a,10); tsread(); tswrite($data_b,20); tsread(); tswrite($data_a,10); tsread(); tsread(); tswrite($data_b,20); tsread(); tsread(); $fh_out->close(); $ftmp->close(); sub tswrite { my ($d,$s) = @_; ( my $pos = tell($ftmp) ) >= 0 or die("tell: $!\n"); my $r = $ftmp->write($d,$s); seek($ftmp, $pos, SEEK_SET) or die("seek: $!\n"); } sub tsread { $fh_out->read($buff,$blen); print "$buff\n"; }
Re: testing interface
by ikegami (Patriarch) on Sep 25, 2009 at 19:26 UTC

    i'm trying to test a module that should read data from file descriptor 3.

    But it's open for writing. That's probably why read is returning Bad file descriptor