#!/usr/local/bin/perl -w
BEGIN { unshift(@INC,"./blib")}

use Ptty;
require POSIX;


$obj = Ptty->new;
$master = $obj->master;

unless (@ARGV)
 {
  my $slave  = $obj->slave;
  print "master $master $$master\n";
  print "slave $slave $$slave\n";
  foreach $val (1..10)
   {            
    print $master "$val\n";
    $_ = <$slave>;
    print "$_"; 
   }            
  close($slave);
 }
else
 {
  my $pid = fork;
  die "Cannot fork:$!" if ($pid < 0);
  if ($pid)
   {
    parent($obj);
   }
  else
   {
    child($obj);
   }
 }

sub child
{
 my ($obj) = @_; 
 my $tty = $obj->slave;
 close($obj->master);
 print $tty "From the Child\n";
# setpgrp(0,$$);
 POSIX::setsid();
 open(STDIN, "<&".fileno($tty)) || (sleep(5),die "Cannot open STDIN");
 open(STDOUT,">&".fileno($tty)) || (sleep(5),die "Cannot open STDOUT");
 open(STDERR,">&STDOUT")        || (sleep(5),die "Cannot open STDERR");
 printf "STDIN=%d STDOUT=%d STDERR=%d\n",fileno(STDIN),fileno(STDOUT),fileno(STDERR);
 close($tty);
 my $prog = shift(@ARGV);
 if (!@ARGV && $prog =~ /sh$/)
  {
   exec $prog '-sh'
  }
 exec($prog,@ARGV);
 die "Cannot exec"; 
}

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 ($obj) = @_; 
 my $tty = $obj->master;
 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);
}


