Import Upstream version 20180207
[hcoop/debian/mlton.git] / basis-library / posix / tty.sml
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2006, 2008 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 *)
8
9structure PosixTTY: POSIX_TTY =
10 struct
11 structure Prim = PrimitiveFFI.Posix.TTY
12 open Prim
13 structure FileDesc = PrePosix.FileDesc
14 structure PId = PrePosix.PId
15
16 structure Error = PosixError
17 structure SysCall = Error.SysCall
18
19 type file_desc = FileDesc.t
20 type pid = PId.t
21
22 structure V =
23 struct
24 open V
25 val nccs = C_Int.toInt NCCS
26 val eof = C_Int.toInt VEOF
27 val eol = C_Int.toInt VEOL
28 val erase = C_Int.toInt VERASE
29 val intr = C_Int.toInt VINTR
30 val kill = C_Int.toInt VKILL
31 val min = C_Int.toInt VMIN
32 val quit = C_Int.toInt VQUIT
33 val susp = C_Int.toInt VSUSP
34 val time = C_Int.toInt VTIME
35 val start = C_Int.toInt VSTART
36 val stop = C_Int.toInt VSTOP
37
38 type cc = C_CC.t array
39
40 val default = C_CC.castFromSysWord 0w0
41
42 fun new () = Array.array (nccs, default)
43
44 fun updates (a, l) =
45 List.app (fn (i, cc) =>
46 Array.update (a, i, (C_CC.castFromSysWord o Word8.castToSysWord o Byte.charToByte) cc))
47 l
48
49 fun cc l = let val a = new ()
50 in updates (a, l)
51 ; a
52 end
53
54 fun update (a, l) =
55 let val a' = new ()
56 in Array.copy {src = a, dst = a', di = 0}
57 ; updates (a', l)
58 ; a'
59 end
60
61 val sub = (Byte.byteToChar o Word8.castFromSysWord o C_CC.castToSysWord) o Array.sub
62 end
63
64 structure Flags = BitFlags(structure S = C_TCFlag)
65 structure I =
66 struct
67 open I Flags
68 val brkint = BRKINT
69 val icrnl = ICRNL
70 val ignbrk = IGNBRK
71 val igncr = IGNCR
72 val ignpar = IGNPAR
73 val inlcr = INLCR
74 val inpck = INPCK
75 val istrip = ISTRIP
76 val ixany = IXANY
77 val ixoff = IXOFF
78 val ixon = IXON
79 val parmrk = PARMRK
80 end
81
82 structure O =
83 struct
84 open O Flags
85 val bs0 = BS0
86 val bs1 = BS1
87 val bsdly = BSDLY
88 val cr0 = CR0
89 val cr1 = CR1
90 val cr2 = CR2
91 val cr3 = CR3
92 val crdly = CRDLY
93 val ff0 = FF0
94 val ff1 = FF1
95 val ffdly = FFDLY
96 val nl0 = NL0
97 val nl1 = NL1
98 val onldly = NLDLY
99 val ocrnl = OCRNL
100 val ofill = OFILL
101 val onlcr = ONLCR
102 val onlret = ONLRET
103 val onocr = ONOCR
104 val opost = OPOST
105 val tab0 = TAB0
106 val tab1 = TAB1
107 val tab2 = TAB2
108 val tab3 = TAB3
109 val tabdly = TABDLY
110 val vt0 = VT0
111 val vt1 = VT1
112 val vtdly = VTDLY
113 end
114
115 structure C =
116 struct
117 open C Flags
118 val clocal = CLOCAL
119 val cread = CREAD
120 val cs5 = CS5
121 val cs6 = CS6
122 val cs7 = CS7
123 val cs8 = CS8
124 val csize = CSIZE
125 val cstopb = CSTOPB
126 val hupcl = HUPCL
127 val parenb = PARENB
128 val parodd = PARODD
129 end
130
131 structure L =
132 struct
133 open L Flags
134 val echo = ECHO
135 val echoe = ECHOE
136 val echok = ECHOK
137 val echonl = ECHONL
138 val icanon = ICANON
139 val iexten = IEXTEN
140 val isig = ISIG
141 val noflsh = NOFLSH
142 val tostop = TOSTOP
143 end
144
145 type speed = C_Speed.t
146
147 val b0 = B0
148 val b110 = B110
149 val b1200 = B1200
150 val b134 = B134
151 val b150 = B150
152 val b1800 = B1800
153 val b19200 = B19200
154 val b200 = B200
155 val b2400 = B2400
156 val b300 = B300
157 val b38400 = B38400
158 val b4800 = B4800
159 val b50 = B50
160 val b600 = B600
161 val b75 = B75
162 val b9600 = B9600
163
164 val compareSpeed = C_Speed.compare
165 val speedToWord = C_Speed.castToSysWord
166 val wordToSpeed = C_Speed.castFromSysWord
167
168 type termios = {iflag: I.flags,
169 oflag: O.flags,
170 cflag: C.flags,
171 lflag: L.flags,
172 cc: V.cc,
173 ispeed: speed,
174 ospeed: speed}
175
176 val id = fn x => x
177 val termios = id
178 val fieldsOf = id
179
180 val getiflag: termios -> I.flags = #iflag
181 val getoflag: termios -> O.flags = #oflag
182 val getcflag: termios -> C.flags = #cflag
183 val getlflag: termios -> L.flags = #oflag
184 val getcc: termios -> V.cc = #cc
185
186 structure CF =
187 struct
188 val getospeed: termios -> speed = #ospeed
189 fun setospeed ({iflag, oflag, cflag, lflag, cc, ispeed, ...}: termios,
190 ospeed: speed): termios =
191 {iflag = iflag,
192 oflag = oflag,
193 cflag = cflag,
194 lflag = lflag,
195 cc = cc,
196 ispeed = ispeed,
197 ospeed = ospeed}
198
199 val getispeed: termios -> speed = #ispeed
200
201 fun setispeed ({iflag, oflag, cflag, lflag, cc, ospeed, ...}: termios,
202 ispeed: speed): termios =
203 {iflag = iflag,
204 oflag = oflag,
205 cflag = cflag,
206 lflag = lflag,
207 cc = cc,
208 ispeed = ispeed,
209 ospeed = ospeed}
210 end
211
212 structure Termios = Prim.Termios
213
214 structure TC =
215 struct
216 open Prim.TC
217
218 type set_action = C_Int.t
219 val sadrain = TCSADRAIN
220 val saflush = TCSAFLUSH
221 val sanow = TCSANOW
222
223 type flow_action = C_Int.t
224 val ioff = TCIOFF
225 val ion = TCION
226 val ooff = TCOOFF
227 val oon = TCOON
228
229 type queue_sel = C_Int.t
230 val iflush = TCIFLUSH
231 val oflush = TCOFLUSH
232 val ioflush = TCIOFLUSH
233
234 fun getattr fd =
235 SysCall.syscallRestart
236 (fn () =>
237 (Prim.TC.getattr (FileDesc.toRep fd), fn _ =>
238 {iflag = Termios.getIFlag (),
239 oflag = Termios.getOFlag (),
240 cflag = Termios.getCFlag (),
241 lflag = Termios.getLFlag (),
242 cc = let val a = V.new ()
243 in Termios.getCC (a); a
244 end,
245 ispeed = Termios.cfGetISpeed (),
246 ospeed = Termios.cfGetOSpeed ()}))
247
248 fun setattr (fd, a,
249 {iflag, oflag, cflag, lflag, cc, ispeed, ospeed}) =
250 SysCall.syscallRestart
251 (fn () =>
252 (Termios.setIFlag iflag
253 ; Termios.setOFlag oflag
254 ; Termios.setCFlag cflag
255 ; Termios.setLFlag lflag
256 ; SysCall.simple (fn () => Termios.cfSetOSpeed ospeed)
257 ; SysCall.simple (fn () => Termios.cfSetISpeed ispeed)
258 ; Termios.setCC cc
259 ; (Prim.TC.setattr (FileDesc.toRep fd, a), fn _ => ())))
260
261 fun sendbreak (fd, n) =
262 SysCall.simpleRestart
263 (fn () => Prim.TC.sendbreak (FileDesc.toRep fd, C_Int.fromInt n))
264
265 fun drain fd =
266 SysCall.simpleRestart
267 (fn () => Prim.TC.drain (FileDesc.toRep fd))
268
269 fun flush (fd, n) =
270 SysCall.simpleRestart
271 (fn () => Prim.TC.flush (FileDesc.toRep fd, n))
272
273 fun flow (fd, n) =
274 SysCall.simpleRestart
275 (fn () => Prim.TC.flow (FileDesc.toRep fd, n))
276
277 fun getpgrp fd =
278 (PId.fromRep o SysCall.simpleResultRestart')
279 ({errVal = C_PId.castFromFixedInt ~1}, fn () =>
280 Prim.TC.getpgrp (FileDesc.toRep fd))
281
282 fun setpgrp (fd, pid) =
283 SysCall.simpleRestart
284 (fn () => Prim.TC.setpgrp (FileDesc.toRep fd, PId.toRep pid))
285 end
286 end