
use blib;
use IO::Pty;
require POSIX;
$^W = 1;

$pty = new IO::Pty;

unless (@ARGV) {
  my $slave  = $pty->slave;
  print %{*$pty},"\n";
  print "master $pty $$pty ",$pty->ttyname,"\n";
  print "slave  $slave $$slave ",$slave->ttyname,"\n";

  foreach $val (1..10) {
    print $pty "$val\n";
    $_ = <$slave>;
    print "$_";
  }
  close($slave);
} else {
  $pty->spawn(@ARGV)
    or die "Cannot spawn @ARGV: $!";
  parent($pty);
}

sub process
{
 my ($rin,$src,$dst) = @_;
 my $buf = '';
 my $read = sysread($src, $buf, 1);
 if (defined $read && $read)
  {
   syswrite($dst,$buf,$read);
   syswrite(LOG,$buf,$read);
  }
 else
  {
   print STDERR "Nothing for $src i.e. $read\n";
   vec($rin, fileno($src), 1) = 0;
  }
 return $rin;
}

sub parent
{
 open(LOG,">log") || die;
 my ($pty) = @_;
 my $tty = $pty;
 my ($rin,$win,$ein) = ('','','');
 vec($rin, fileno(STDIN), 1) = 1;
 vec($rin, fileno($tty), 1) = 1;
 vec($win, fileno($tty), 1) = 1;
 vec($ein, fileno($tty), 1) = 1;
 select($tty);
 $| = 1;
 select(STDOUT);
 $| = 1;
 while (1)
  {
   my ($rout,$wout,$eout,$timeleft);
   ($nfound,$timeleft) = select($rout=$rin,$wout=$win,$eout=$ein,3600);
   die "select failed:$!" if ($nfound < 0);
   if ($nfound > 0)
    {
     if (vec($eout, fileno($tty), 1))
      {
#       print STDERR "Exception on $tty\n";
      }
     if (vec($rout, fileno($tty), 1))
      {
       $rin = process($rin,$tty,STDOUT);
       last unless (vec($rin, fileno($tty), 1));
      }
     elsif (vec($rout, fileno(STDIN), 1) && vec($wout, fileno($tty), 1))
      {
       $rin = process($rin,STDIN,$tty);
      }
    }
  }
 close(LOG);
}


