summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan O'Rear <stefanor@cox.net>2009-02-03 22:32:34 -0500
committerStefan O'Rear <stefanor@cox.net>2009-02-03 22:32:34 -0500
commit2623b8edff6b776a5972edb2b1ef702e55340549 (patch)
treedff4afc733aab495888e762938e7ca4f7162aeb3
parentc86c82120d0ca83a1425778ac58e82c8bf79c73e (diff)
downloadio-pty-easy-2623b8edff6b776a5972edb2b1ef702e55340549.tar.gz
io-pty-easy-2623b8edff6b776a5972edb2b1ef702e55340549.zip
Fix BSD by draining the kernel pty buffer before waiting
-rw-r--r--lib/IO/Pty/Easy.pm13
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/IO/Pty/Easy.pm b/lib/IO/Pty/Easy.pm
index fdef28f..644b1da 100644
--- a/lib/IO/Pty/Easy.pm
+++ b/lib/IO/Pty/Easy.pm
@@ -155,6 +155,7 @@ sub spawn {
close $writep;
$self->{pty}->close_slave;
$self->{pty}->set_raw;
+ $self->{final_output} = '';
# this sysread will block until either we get an EOF from the other end of
# the pipe being closed due to the exec, or until the child process sends
# us the errno of the exec call after it fails
@@ -210,6 +211,8 @@ sub read {
my $nchars = sysread($self->{pty}, $buf, $max_chars);
$buf = '' if defined($nchars) && $nchars == 0;
}
+ $buf = $self->{final_output} . $buf;
+ $self->{final_output} = '';
return $buf;
}
# }}}
@@ -253,6 +256,16 @@ sub is_active {
my $self = shift;
return 0 unless defined $self->{pid};
+ # XXX XXX XXX FreeBSD 7.0 will not allow a session leader to exit
+ # until the kernel tty output buffer is empty. Make it so.
+ my $rin = '';
+ vec($rin, fileno($self->{pty}), 1) = 1;
+ my $nfound = select($rin, undef, undef, 0);
+ if ($nfound > 0) {
+ sysread($self->{pty}, $self->{final_output},
+ $self->{def_max_read_chars}, length $self->{final_output});
+ }
+
my $active = kill 0 => $self->{pid};
if ($active) {
my $pid = waitpid($self->{pid}, POSIX::WNOHANG());