This is just a wild a*s guess, but it sounds familiar to the problem of making a bidirectional socket client. The idea is to fork ( or thread ) off the input from the output. The code below is for sockets, but you should be able to figure out how to open your DEVICE handle and read/write to it instead. Also, you might need to open DEVICE read/write, i.e. '+<'
#!/usr/bin/perl -w
use strict;
# remove the socket code, and insert your
# DEVICE open
#############################
use IO::Socket;
my ( $host, $port, $kidpid, $handle, $line );
( $host, $port ) = ('localhost',1200);
my $name = shift || '';
if($name eq ''){print "What's your name?\n"}
chomp ($name = <>);
# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $host,
PeerPort => $port
)
or die "can't connect to port $port on $host: $!";
$handle->autoflush(1); # so output gets there right away
print STDERR "[Connected to $host:$port]\n";
############################
# here is the essence of what I'm proposing to try
# split the program into two processes, identical twins
die "can't fork: $!" unless defined( $kidpid = fork() );
# the if{} block runs only in the parent process
if ($kidpid) {
# copy the socket to standard output
while ( defined( $line = <$handle> ) ) {
print STDOUT $line;
}
kill( "TERM", $kidpid ); # send SIGTERM to child
}
# the else{} block runs only in the child process
else {
# copy standard input to the socket
while ( defined( $line = <STDIN> ) ) {
print $handle "$name->$line";
}
}