1#!/usr/local/bin/perl
2#
3# Attaches user's input and output to a local terminal device (/dev/tty*).
4#
5# Usage:
6#
7# PortTest tty_device
8#
9
10use strict;
11use POSIX ();
12use Fcntl ();
13
14my $in;
15my $termios = POSIX::Termios->new;
16my $ttydev = $ARGV[ 0 ];
17my $stdin_oldiflag;
18my $stdin_oldlflag;
19my $tty_oldlflag;
20my $tty_oldiflag;
21
22die 'Terminal device not specified' unless $ttydev;
23
24# install signal handler:
25$SIG{'INT'}    = \&handler;
26$SIG{'QUIT'}   = \&handler;
27$SIG{'HUP'}    = \&handler;
28$SIG{'ILL'}    = \&handler;
29$SIG{'TRAP'}   = \&handler;
30$SIG{'ABRT'}   = \&handler;
31$SIG{'EMT'}    = \&handler;
32$SIG{'FPE'}    = \&handler;
33$SIG{'BUS'}    = \&handler;
34$SIG{'SEGV'}   = \&handler;
35$SIG{'SYS'}    = \&handler;
36$SIG{'PIPE'}   = \&handler;
37$SIG{'ALRM'}   = \&handler;
38$SIG{'TERM'}   = \&handler;
39$SIG{'TSTP'}   = \&handler;
40$SIG{'TTIN'}   = \&handler;
41$SIG{'TTOU'}   = \&handler;
42$SIG{'XCPU'}   = \&handler;
43$SIG{'XFSZ'}   = \&handler;
44$SIG{'VTALRM'} = \&handler;
45$SIG{'PROF'}   = \&handler;
46$SIG{'USR1'}   = \&handler;
47
48sysopen( DEV, $ttydev, &Fcntl::O_RDWR ) || die( "Can't open $ttydev: $!" );
49
50# Make tty line unbuffered and timeout-blocking on STDIN and TTY:
51$termios->getattr( fileno( DEV ) );
52$tty_oldlflag = $termios->getlflag();
53$tty_oldiflag = $termios->getiflag();
54$termios->setlflag( $tty_oldlflag & ~&POSIX::ECHO & ~&POSIX::ICANON );
55$termios->setiflag( $tty_oldiflag & ~&POSIX::ICRNL );
56$termios->setcc( &POSIX::VMIN, 0 );
57$termios->setcc( &POSIX::VTIME, 1 );
58$termios->setattr( fileno( DEV ), &POSIX::TCSANOW );
59$termios->getattr( fileno( STDIN ) );
60$stdin_oldlflag = $termios->getlflag();
61$stdin_oldiflag = $termios->getiflag();
62$termios->setlflag( $stdin_oldlflag & ~&POSIX::ECHO & ~&POSIX::ICANON );
63$termios->setiflag( $stdin_oldiflag & ~&POSIX::ICRNL | &POSIX::BRKINT | &POSIX::IGNBRK );
64$termios->setcc( &POSIX::VMIN, 0 );
65$termios->setcc( &POSIX::VTIME, 1 );
66$termios->setattr( fileno( STDIN ), &POSIX::TCSANOW );
67
68while( 1 ){
69	while( sysread( STDIN, $in, 1024 ) > 0 ){
70                syswrite( DEV, $in, length $in );
71	}
72	while( sysread( DEV, $in, 1024 ) > 0 ){
73                syswrite( STDOUT, $in, length $in );
74	}
75}
76handler();
77
78sub handler
79{
80        close DEV;
81	# Turning STDIN back
82	$termios->setlflag( $stdin_oldlflag );
83	$termios->setiflag( $stdin_oldiflag );
84	$termios->setcc( &POSIX::VMIN, 1 );
85	$termios->setcc( &POSIX::VTIME, 0 );
86	$termios->setattr( fileno( STDIN ), &POSIX::TCSANOW );
87	# Turning TTY device back
88	$termios->getattr( fileno( DEV ) );
89	$termios->setlflag( $tty_oldlflag );
90	$termios->setiflag( $tty_oldiflag );
91	$termios->setcc( &POSIX::VMIN, 1 );
92	$termios->setcc( &POSIX::VTIME, 0 );
93	$termios->setattr( fileno( DEV ), &POSIX::TCSANOW );
94        exit;
95}
96