0
|
1 |
#!/usr/local/bin/perl
|
|
2 |
#======================================================================
|
|
3 |
# T T Y C A T
|
|
4 |
# doc: Tue Aug 8 13:58:51 2006
|
|
5 |
# dlm: Tue Oct 3 12:15:33 2006
|
|
6 |
# (c) 2006 turbulence@
|
|
7 |
# uE-Info: 15 57 NIL 0 0 72 10 2 8 NIL ofnI
|
|
8 |
#======================================================================
|
|
9 |
|
|
10 |
# read from tty, write to stdout
|
|
11 |
|
|
12 |
# HISTORY:
|
|
13 |
# Aug 8, 2006: - created from [bbabble] on DYNAMUCK cruise
|
|
14 |
# Oct 3, 2006: - added -B)reak
|
|
15 |
# - added dummy -n for [find_comms_params]
|
|
16 |
|
|
17 |
use Getopt::Std;
|
|
18 |
use POSIX ();
|
|
19 |
|
|
20 |
#----------------------------------------------------------------------
|
|
21 |
# Usage
|
|
22 |
#----------------------------------------------------------------------
|
|
23 |
|
|
24 |
$USAGE = "Usage: $0 [-b)aud <rate[9600]>] " .
|
|
25 |
"[-d)ata <bits[8]>] [-s)top <bits[1]>] " .
|
|
26 |
"[-e)ven | -o)dd | -n)o parity] " .
|
|
27 |
"[send -B)reak] " .
|
|
28 |
"<tty device>\n";
|
|
29 |
|
|
30 |
die($USAGE) unless (getopts('Bb:d:ns:eo'));
|
|
31 |
die($USAGE) if ($opt_e+$opt_o+$opt_n > 1);
|
|
32 |
die($USAGE) unless (@ARGV == 1);
|
|
33 |
|
|
34 |
$opt_b = 9600 unless defined($opt_b);
|
|
35 |
$opt_s = 1 unless defined($opt_s);
|
|
36 |
$opt_d = 8 unless defined($opt_d);
|
|
37 |
|
|
38 |
die("$0: data bits must be 5, 6, 7 or 8\n")
|
|
39 |
unless ($opt_d >= 5 && $opt_d <= 8);
|
|
40 |
die("$0: stop bits must be 1 or 2\n")
|
|
41 |
unless ($opt_s == 1 || $opt_s == 2);
|
|
42 |
|
|
43 |
$TTY = $ARGV[0];
|
|
44 |
|
|
45 |
#----------------------------------------------------------------------
|
|
46 |
# determine correct tcsetospeed() argument for non-POSIX speeds
|
|
47 |
#----------------------------------------------------------------------
|
|
48 |
|
|
49 |
# This is ugly, slow, but seems fairly portable.
|
|
50 |
|
|
51 |
open(TMP,'>/tmp/tt.c');
|
|
52 |
print(TMP "#include <termios.h>\nB$opt_b\n");
|
|
53 |
close(TMP);
|
|
54 |
$SPEED = `gcc -E /tmp/tt.c | tail -1`;
|
|
55 |
$SPEED = hex($SPEED) if ($SPEED =~ /^0x/);
|
|
56 |
$SPEED = oct($SPEED) if ($SPEED =~ /^0/);
|
|
57 |
unlink('/tmp/tt.c');
|
|
58 |
|
|
59 |
#----------------------------------------------------------------------
|
|
60 |
# setup TTY
|
|
61 |
#----------------------------------------------------------------------
|
|
62 |
|
|
63 |
print(STDERR "Opening $TTY...");
|
|
64 |
my($sfd);
|
|
65 |
open(TTY,$TTY) || die(" $!\n");
|
|
66 |
$sfd = fileno(TTY);
|
|
67 |
print(STDERR "\n");
|
|
68 |
|
|
69 |
print(STDERR "Configuring $TTY...");
|
|
70 |
|
|
71 |
my($t) = POSIX::Termios::new();
|
|
72 |
die(" tcgetattr: $!\n")
|
|
73 |
unless defined($t->getattr($sfd));
|
|
74 |
|
|
75 |
$t->setiflag($t->getiflag() & ~(POSIX::IGNBRK() |
|
|
76 |
POSIX::BRKINT() |
|
|
77 |
POSIX::PARMRK() |
|
|
78 |
POSIX::ISTRIP() |
|
|
79 |
POSIX::INLCR() |
|
|
80 |
POSIX::IGNCR() |
|
|
81 |
POSIX::ICRNL() |
|
|
82 |
POSIX::IXON()));
|
|
83 |
|
|
84 |
$t->setoflag($t->getoflag() & ~POSIX::OPOST());
|
|
85 |
|
|
86 |
$t->setlflag($t->getlflag() & ~(POSIX::ECHO() |
|
|
87 |
POSIX::ECHONL() |
|
|
88 |
POSIX::ICANON() |
|
|
89 |
POSIX::ISIG() |
|
|
90 |
POSIX::IEXTEN()));
|
|
91 |
|
|
92 |
$cf = $t->getcflag();
|
|
93 |
$cf &= ~POSIX::CSIZE(); # word length
|
|
94 |
$cf |= POSIX::CS5() if ($opt_d == 5);
|
|
95 |
$cf |= POSIX::CS6() if ($opt_d == 6);
|
|
96 |
$cf |= POSIX::CS7() if ($opt_d == 7);
|
|
97 |
$cf |= POSIX::CS8() if ($opt_d == 8);
|
|
98 |
$cf &= ~POSIX::CSTOPB(); # stop bits
|
|
99 |
$cf |= POSIX::CSTOPB() if ($opt_s == 2);
|
|
100 |
$cf &= ~POSIX::PARENB(); # parity
|
|
101 |
if ($opt_e || $opt_o) {
|
|
102 |
$cf |= POSIX::PARENB();
|
|
103 |
$cf |= POSIX::PARODD() if $opt_o;
|
|
104 |
}
|
|
105 |
$t->setcflag($cf);
|
|
106 |
|
|
107 |
$t->setcc(POSIX::VMIN,1);
|
|
108 |
$t->setcc(POSIX::VTIME,0);
|
|
109 |
|
|
110 |
$t->setispeed($SPEED);
|
|
111 |
$t->setospeed($SPEED);
|
|
112 |
|
|
113 |
die(" tcsetattr: $!\n")
|
|
114 |
unless defined($t->setattr($sfd,POSIX::TCSANOW));
|
|
115 |
print(STDERR "\n");
|
|
116 |
|
|
117 |
#----------------------------------------------------------------------
|
|
118 |
# send BREAK if requested
|
|
119 |
#----------------------------------------------------------------------
|
|
120 |
|
|
121 |
if ($opt_B) {
|
|
122 |
print(STDERR "Sending BREAK...");
|
|
123 |
die(" tcsendbreak: $!\n")
|
|
124 |
unless defined(POSIX::tcsendbreak($sfd,0));
|
|
125 |
print(STDERR "\n");
|
|
126 |
}
|
|
127 |
|
|
128 |
#----------------------------------------------------------------------
|
|
129 |
# TTY reader
|
|
130 |
#----------------------------------------------------------------------
|
|
131 |
|
|
132 |
do {
|
|
133 |
my($buf,$nread);
|
|
134 |
$nread = POSIX::read($sfd,$buf,64);
|
|
135 |
POSIX::write(1,$buf,$nread);
|
|
136 |
} while ($nread >= 0);
|
|
137 |
|
|
138 |
exit(0);
|
|
139 |
|
|
140 |
|