trace("Child", "Child FH: ", fileno($s1a), "/", fileno($s2a));
open(STDIN, "<&=" . fileno($s1a)) || die "dup of stdin failed";
open(STDOUT, ">&=" . fileno($s2a)) || die "dup of stdout failed";
open(STDERR, ">&STDOUT") || die "dup of stderr failed";
shutdown($s1a, 1);
close($s1b);
shutdown($s2a, 0);
close($s2b);
exec @_;
die;
} else {
close($s1a);
shutdown($s1b, 0);
close($s2a);
shutdown($s2b, 1);
$self->{INPUT} = $s2b;
$self->{OUTPUT} = $s1b;
}
1;
}
#
# Initialize a tty's termio setting: turn off echo.
#
sub init_tty
{
my($self, $fd) = @_;
unless ($termios->getattr(fileno($fd))) {
$self->{JUNOS_Device}->report_error("getattr failed on pty");
return;
}
my $lflags = $termios->getlflag;
$lflags &= ~(&ECHO);
$termios->setlflag($lflags);
$termios->setattr(fileno($fd));
1;
}
#
# Start a command in a sub-process under a pty
#
sub start_command
{
my $self = shift;
tracept("IO");
my $pty = new IO::Pty;
my $slave = $pty->slave;
unless ($slave) {
$self->{JUNOS_Device}->report_error("cannot create pty slave");
return;
}
trace("IO", "Access: pty $pty $$pty ", $pty->ttyname);
trace("IO", "Access: slv $slave $$slave ", $slave->ttyname);
&init_tty($self, $slave) || return;
my $pid = fork;
if ($pid < 0) {
$self->{JUNOS_Device}->report_error("fork failed");
return;
} elsif ($pid == 0) {
trace("Child", "Child $pid/", $$, " cmd: ", join(" ", @_));
trace("Child", "Child FH: ", fileno($pty), "/", fileno($slave));
# Turn the pty/tty into our stdin/stdout/stderr
close(STDIN);
open(STDIN, "<&" . fileno($slave)) || die "dup of stdin failed";
shutdown(STDIN, 1);
close(STDOUT);
open(STDOUT, ">&" . fileno($slave)) || die "dup of stdout failed";
shutdown(STDOUT, 0);
close(STDERR);
open(STDERR, ">&STDOUT") || die "dup of stderr failed";
#
# We need to disassociate ourselves from the controlling tty.
# It would be nice to make the pty/tty we just made into our
# controlling tty, but this does not seem to be working....
#
setsid;
# Close off the original pty/tty handles
close($slave);
close($pty);
exec @_;
die;
=3= |