File Coverage

blib/lib/IO/Tty/Util.pm
Criterion Covered Total %
statement 34 52 65.3
branch 9 26 34.6
condition n/a
subroutine 8 9 88.8
pod 3 4 75.0
total 54 91 59.3


line stmt bran cond sub pod time code
1             package IO::Tty::Util ;
2              
3 3     3   63243 use strict ;
  3         6  
  3         114  
4 3     3   3180 use IO::Handle ;
  3         24165  
  3         156  
5 3     3   2706 use IO::Select ;
  3         5595  
  3         141  
6 3     3   21 use Carp ;
  3         6  
  3         2229  
7              
8             our $VERSION = '0.03' ;
9              
10             require Exporter ;
11             our @ISA = qw(Exporter) ;
12             our @EXPORT_OK = qw( openpty login_tty forkpty passthru ) ;
13              
14             require XSLoader ;
15             XSLoader::load('IO::Tty::Util', $VERSION) ;
16              
17              
18             sub import {
19 6     6   60 my $class = shift ;
20              
21 6         21 foreach my $a (@_){
22 9 50       27 if ($a eq "passthru"){
23 0         0 shift ;
24 0         0 my ($pid, $master) = forkpty(@_) ;
25 0 0       0 croak("forkpty error: $!") unless $master ;
26 0         0 passthru($master) ;
27 0         0 exit() ;
28             }
29             }
30              
31 6         654 $class->export_to_level(1, $class, @_) ;
32             }
33              
34              
35             sub openpty {
36 5     5 1 21 my ($rows, $cols) = @_ ;
37              
38 5         3761 my ($master, $slave) = _openpty($rows, $cols) ;
39 5 50       28 return () unless defined($master) ;
40              
41 5         92 return (IO::Handle->new_from_fd($master, "r+"), IO::Handle->new_from_fd($slave, "r+")) ;
42             }
43              
44              
45             sub login_tty {
46 2     2 1 2242 my $h = shift ;
47              
48 2         290 my $rc = _login_tty(fileno($h)) ;
49 2 50       446 return ($rc == -1 ? 0 : 1) ;
50             }
51              
52              
53             sub forkpty {
54 2     2 1 407634 my ($rows, $cols, @cmd) = @_ ;
55              
56 2         28 my ($master, $slave) = openpty($rows, $cols) ;
57 2 50       876 return () unless defined($master) ;
58              
59 2         3408 my $pid = fork() ;
60 2 50       177 return () unless defined($pid) ;
61              
62 2 100       87 if ($pid){
63 1         40 close($slave) ;
64 1         216 return ($pid, $master) ;
65             }
66             else {
67 1         54 close($master) ;
68 1 50       50 return () unless login_tty($slave) ;
69 1 50       139 return (0) unless scalar(@cmd) ;
70 0 0         exec(@cmd) or die("Can't exec '@cmd': $!") ;
71             }
72             }
73              
74              
75             sub passthru {
76 0     0 0   my $master = shift ;
77              
78 0           STDOUT->autoflush(1) ;
79 0           $master->autoflush(1) ;
80 0           my $select = new IO::Select($master, \*STDIN) ;
81 0           while (1){
82 0           my @ready = $select->can_read() ;
83 0           foreach my $h (@ready){
84 0           my $buf = '' ;
85 0           my $rc = sysread($h, $buf, 4096) ;
86 0 0         return if !$rc ; # pty seems to return error instead of EOF...
87              
88 0 0         my $out = ($h eq \*STDIN ? $master : \*STDOUT) ;
89             # open(DEBUG, ">>/tmp/output") && print DEBUG "[$buf]\n" ;
90 0 0         print $out $buf or croak("print error: $!") ;
91             }
92             }
93             }
94              
95              
96              
97              
98             1 ;
99             __END__