build: Update autosetup to v0.6.6-8-g062d650
[jimtcl.git] / examples / tip.tcl
blob61ae2cc32bf198c89ced248fe646782cc276b769
1 #!/usr/bin/env jimsh
3 # tip.tcl is like a simple version of cu, written in pure Jim Tcl
4 # It makes use of the new aio tty support
6 # Note: On Mac OS X, be sure to open /dev/cu.* devices, not /dev/tty.* devices
8 set USAGE \
9 {Usage: tip ?settings? device
10 or tip help
12 Where settings are as follows:
13 1|2 stop bits (default 1)
14 5|6|7|8 data bits (default 8)
15 even|odd parity (default none)
16 xonxoff|rtscts handshaking (default none)
17 <number> baud rate (default 115200)
19 e.g. tip 9600 8 1 rtscts /dev/ttyUSB0}
21 set settings {
22 baud 115200
23 stop 1
24 data 8
25 parity none
26 handshake none
27 input raw
28 output raw
29 vmin 1
30 vtime 1
33 set showhelp 0
35 foreach i $argv {
36 if {[string match -h* $i] || [string match help* $i]} {
37 puts $USAGE
38 return 0
40 if {$i in {even odd}} {
41 set settings(parity) $i
42 continue
44 if {$i in {ixonixoff rtscts}} {
45 set settings(handshake) $i
46 continue
48 if {$i in {1 2}} {
49 set settings(stop) $i
50 continue
52 if {$i in {5 6 7 8}} {
53 set settings(data) $i
54 continue
56 if {[string is integer -strict $i]} {
57 set settings(baud) $i
58 continue
60 if {[file exists $i]} {
61 set device $i
62 continue
64 puts "Warning: unrecognised setting $i"
67 if {![exists device]} {
68 puts $USAGE
69 exit 1
72 # save stdin and stdout tty settings
73 # note that stdin and stdout are probably the same file descriptor,
74 # but it doesn't hurt to treat them independently
75 set stdin_save [stdin tty]
76 set stdout_save [stdout tty]
78 try {
79 set f [open $device r+]
80 } on error msg {
81 puts "Failed to open $device"
82 return 1
85 if {[$f lock] == 0} {
86 puts "Device is in use: $device"
87 return 1
90 try {
91 $f tty {*}$settings
92 } on error msg {
93 puts "$device: $msg"
94 return 1
97 puts "\[$device\] Use ~. to exit"
99 $f ndelay 1
100 $f buffering none
102 stdin tty input raw
103 stdin ndelay 1
105 stdout tty output raw
106 stdout buffering none
108 set status ""
110 # I/O loop
112 set tilde 0
114 $f readable {
115 set c [$f read]
116 if {[$f eof]} {
117 set status "$device: disconnected"
118 incr done
119 } else {
120 stdout puts -nonewline $c
124 proc tilde_timeout {} {
125 global tilde f
126 if {$tilde} {
127 $f puts -nonewline ~
128 set tilde 0
132 stdin readable {
133 set c [stdin read]
134 # may receive more than one char here, but only need to consider
135 # ~. processing if we receive them as separate chars
136 if {$tilde == 0 && $c eq "~"} {
137 incr tilde
138 # Need ~. within 1 second of each other
139 after 1000 tilde_timeout
140 } else {
141 if {$tilde} {
142 after cancel tilde_timeout
143 set tilde 0
144 if {$c eq "."} {
145 incr done
146 return
148 $f puts -nonewline ~
150 $f puts -nonewline $c
154 vwait done
156 # restore previous settings
157 stdin tty {*}$stdin_save
158 stdout tty {*}$stdout_save
160 puts $status