Commit | Line | Data |
---|---|---|
a8fd2d0d KM |
1 | /* |
2 | * Copyright (c) 1988 University of Utah. | |
3 | * Copyright (c) 1990 The Regents of the University of California. | |
4 | * All rights reserved. | |
5 | * | |
6 | * This code is derived from software contributed to Berkeley by | |
7 | * the Systems Programming Group of the University of Utah Computer | |
8 | * Science Department. | |
9 | * | |
10 | * %sccs.include.redist.c% | |
11 | * | |
fbdf09dd | 12 | * from: Utah $Hdr: hpux_tty.c 1.1 90/07/09$ |
a8fd2d0d | 13 | * |
b28b3a13 | 14 | * @(#)hpux_tty.c 7.6 (Berkeley) %G% |
a8fd2d0d KM |
15 | */ |
16 | ||
17 | /* | |
18 | * stty/gtty/termio emulation stuff | |
19 | */ | |
20 | #ifdef HPUXCOMPAT | |
21 | ||
b28b3a13 KB |
22 | #include "sys/param.h" |
23 | #include "sys/systm.h" | |
24 | #include "sys/user.h" | |
25 | #include "sys/ioctl.h" | |
26 | #include "sys/tty.h" | |
27 | #include "sys/proc.h" | |
28 | #include "sys/file.h" | |
29 | #include "sys/conf.h" | |
30 | #include "sys/buf.h" | |
31 | #include "sys/uio.h" | |
32 | #include "sys/kernel.h" | |
a8fd2d0d KM |
33 | |
34 | #include "hpux.h" | |
35 | #include "hpux_termio.h" | |
36 | ||
a8fd2d0d | 37 | /* |
7556cc71 | 38 | * Map BSD/POSIX style termios info to and from SYS5 style termio stuff. |
a8fd2d0d KM |
39 | */ |
40 | hpuxtermio(fp, com, data) | |
41 | struct file *fp; | |
42 | caddr_t data; | |
43 | { | |
7556cc71 MH |
44 | struct termios tios; |
45 | int line, error, (*ioctlrout)(); | |
a8fd2d0d KM |
46 | register struct hpuxtermio *tiop; |
47 | ||
48 | ioctlrout = fp->f_ops->fo_ioctl; | |
49 | tiop = (struct hpuxtermio *)data; | |
50 | switch (com) { | |
51 | case HPUXTCGETA: | |
7556cc71 MH |
52 | /* |
53 | * Get BSD terminal state | |
54 | */ | |
a8fd2d0d | 55 | bzero(data, sizeof(struct hpuxtermio)); |
7556cc71 | 56 | if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios)) |
a8fd2d0d | 57 | break; |
7556cc71 MH |
58 | /* |
59 | * Set iflag. | |
60 | * Same through ICRNL, no BSD equivs for IUCLC, IENQAK | |
61 | */ | |
62 | tiop->c_iflag = tios.c_iflag & 0x1ff; | |
63 | if (tios.c_iflag & IXON) | |
64 | tiop->c_iflag |= TIO_IXON; | |
65 | if (tios.c_iflag & IXOFF) | |
66 | tiop->c_iflag |= TIO_IXOFF; | |
67 | if (tios.c_iflag & IXANY) | |
68 | tiop->c_iflag |= TIO_IXANY; | |
69 | /* | |
70 | * Set oflag. | |
71 | * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL | |
72 | * or any of the delays. | |
73 | */ | |
74 | if (tios.c_oflag & OPOST) | |
75 | tiop->c_oflag |= TIO_OPOST; | |
76 | if (tios.c_oflag & ONLCR) | |
77 | tiop->c_oflag |= TIO_ONLCR; | |
78 | if (tios.c_oflag & OXTABS) | |
a8fd2d0d | 79 | tiop->c_oflag |= TIO_TAB3; |
7556cc71 MH |
80 | /* |
81 | * Set cflag. | |
82 | * Baud from ospeed, rest from cflag. | |
83 | */ | |
84 | tiop->c_cflag = bsdtohpuxbaud(tios.c_ospeed); | |
85 | switch (tios.c_cflag & CSIZE) { | |
86 | case CS5: | |
87 | tiop->c_cflag |= TIO_CS5; break; | |
88 | case CS6: | |
89 | tiop->c_cflag |= TIO_CS6; break; | |
90 | case CS7: | |
91 | tiop->c_cflag |= TIO_CS7; break; | |
92 | case CS8: | |
93 | tiop->c_cflag |= TIO_CS8; break; | |
a8fd2d0d | 94 | } |
7556cc71 MH |
95 | if (tios.c_cflag & CSTOPB) |
96 | tiop->c_cflag |= TIO_CSTOPB; | |
97 | if (tios.c_cflag & CREAD) | |
98 | tiop->c_cflag |= TIO_CREAD; | |
99 | if (tios.c_cflag & PARENB) | |
100 | tiop->c_cflag |= TIO_PARENB; | |
101 | if (tios.c_cflag & PARODD) | |
102 | tiop->c_cflag |= TIO_PARODD; | |
103 | if (tios.c_cflag & HUPCL) | |
104 | tiop->c_cflag |= TIO_HUPCL; | |
105 | if (tios.c_cflag & CLOCAL) | |
106 | tiop->c_cflag |= TIO_CLOCAL; | |
107 | /* | |
108 | * Set lflag. | |
109 | * No BSD equiv for XCASE. | |
110 | */ | |
111 | if (tios.c_lflag & ECHOE) | |
112 | tiop->c_lflag |= TIO_ECHOE; | |
113 | if (tios.c_lflag & ECHOK) | |
114 | tiop->c_lflag |= TIO_ECHOK; | |
115 | if (tios.c_lflag & ECHO) | |
a8fd2d0d | 116 | tiop->c_lflag |= TIO_ECHO; |
7556cc71 MH |
117 | if (tios.c_lflag & ECHONL) |
118 | tiop->c_lflag |= TIO_ECHONL; | |
119 | if (tios.c_lflag & ISIG) | |
a8fd2d0d | 120 | tiop->c_lflag |= TIO_ISIG; |
7556cc71 MH |
121 | if (tios.c_lflag & ICANON) |
122 | tiop->c_lflag |= TIO_ICANON; | |
123 | if (tios.c_lflag & NOFLSH) | |
124 | tiop->c_lflag |= TIO_NOFLSH; | |
125 | /* | |
126 | * Line discipline | |
127 | */ | |
128 | line = 0; | |
129 | (void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line); | |
130 | tiop->c_line = line; | |
131 | /* | |
132 | * Set editing chars | |
133 | */ | |
134 | tiop->c_cc[HPUXVINTR] = tios.c_cc[VINTR]; | |
135 | tiop->c_cc[HPUXVQUIT] = tios.c_cc[VQUIT]; | |
136 | tiop->c_cc[HPUXVERASE] = tios.c_cc[VERASE]; | |
137 | tiop->c_cc[HPUXVKILL] = tios.c_cc[VKILL]; | |
138 | if (tiop->c_lflag & TIO_ICANON) { | |
139 | tiop->c_cc[HPUXVEOF] = tios.c_cc[VEOF]; | |
140 | tiop->c_cc[HPUXVEOL] = tios.c_cc[VEOL]; | |
141 | } else { | |
142 | tiop->c_cc[HPUXVMIN] = tios.c_cc[VMIN]; | |
143 | tiop->c_cc[HPUXVTIME] = tios.c_cc[VTIME]; | |
a8fd2d0d | 144 | } |
a8fd2d0d KM |
145 | break; |
146 | ||
147 | case HPUXTCSETA: | |
148 | case HPUXTCSETAW: | |
149 | case HPUXTCSETAF: | |
7556cc71 MH |
150 | /* |
151 | * Get old characteristics and determine if we are a tty. | |
152 | */ | |
153 | if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios)) | |
a8fd2d0d | 154 | break; |
7556cc71 MH |
155 | /* |
156 | * Set iflag. | |
157 | * Same through ICRNL, no HP-UX equiv for IMAXBEL | |
158 | */ | |
159 | tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff); | |
160 | tios.c_iflag |= tiop->c_iflag & 0x1ff; | |
161 | if (tiop->c_iflag & TIO_IXON) | |
162 | tios.c_iflag |= IXON; | |
a8fd2d0d | 163 | if (tiop->c_iflag & TIO_IXOFF) |
7556cc71 MH |
164 | tios.c_iflag |= IXOFF; |
165 | if (tiop->c_iflag & TIO_IXANY) | |
166 | tios.c_iflag |= IXANY; | |
167 | /* | |
168 | * Set oflag. | |
169 | * No HP-UX equiv for ONOEOT | |
170 | */ | |
171 | tios.c_oflag &= ~(OPOST|ONLCR|OXTABS); | |
172 | if (tiop->c_oflag & TIO_OPOST) | |
173 | tios.c_oflag |= OPOST; | |
174 | if (tiop->c_oflag & TIO_ONLCR) | |
175 | tios.c_oflag |= ONLCR; | |
176 | if (tiop->c_oflag & TIO_TAB3) | |
177 | tios.c_oflag |= OXTABS; | |
178 | /* | |
179 | * Set cflag. | |
180 | * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF | |
181 | */ | |
182 | tios.c_cflag &= | |
183 | ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL); | |
184 | switch (tiop->c_cflag & TIO_CSIZE) { | |
185 | case TIO_CS5: | |
186 | tios.c_cflag |= CS5; break; | |
187 | case TIO_CS6: | |
188 | tios.c_cflag |= CS6; break; | |
189 | case TIO_CS7: | |
190 | tios.c_cflag |= CS7; break; | |
191 | case TIO_CS8: | |
192 | tios.c_cflag |= CS8; break; | |
a8fd2d0d | 193 | } |
7556cc71 MH |
194 | if (tiop->c_cflag & TIO_CSTOPB) |
195 | tios.c_cflag |= CSTOPB; | |
196 | if (tiop->c_cflag & TIO_CREAD) | |
197 | tios.c_cflag |= CREAD; | |
198 | if (tiop->c_cflag & TIO_PARENB) | |
199 | tios.c_cflag |= PARENB; | |
200 | if (tiop->c_cflag & TIO_PARODD) | |
201 | tios.c_cflag |= PARODD; | |
202 | if (tiop->c_cflag & TIO_HUPCL) | |
203 | tios.c_cflag |= HUPCL; | |
204 | if (tiop->c_cflag & TIO_CLOCAL) | |
205 | tios.c_cflag |= CLOCAL; | |
206 | /* | |
207 | * Set lflag. | |
208 | * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL | |
209 | * IEXTEN treated as part of ICANON | |
210 | */ | |
211 | tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH); | |
a8fd2d0d | 212 | if (tiop->c_lflag & TIO_ECHOE) |
7556cc71 MH |
213 | tios.c_lflag |= ECHOE; |
214 | if (tiop->c_lflag & TIO_ECHOK) | |
215 | tios.c_lflag |= ECHOK; | |
216 | if (tiop->c_lflag & TIO_ECHO) | |
217 | tios.c_lflag |= ECHO; | |
218 | if (tiop->c_lflag & TIO_ECHONL) | |
219 | tios.c_lflag |= ECHONL; | |
220 | if (tiop->c_lflag & TIO_ISIG) | |
221 | tios.c_lflag |= ISIG; | |
222 | if (tiop->c_lflag & TIO_ICANON) | |
223 | tios.c_lflag |= (ICANON|IEXTEN); | |
224 | if (tiop->c_lflag & TIO_NOFLSH) | |
225 | tios.c_lflag |= NOFLSH; | |
226 | /* | |
227 | * Set editing chars. | |
228 | * No HP-UX equivs of VEOL2/VWERASE/VREPRINT/VSUSP/VDSUSP | |
229 | * VSTOP/VLNEXT/VDISCARD/VMIN/VTIME/VSTATUS/VERASE2 | |
230 | */ | |
231 | tios.c_cc[VINTR] = tiop->c_cc[HPUXVINTR]; | |
232 | tios.c_cc[VQUIT] = tiop->c_cc[HPUXVQUIT]; | |
233 | tios.c_cc[VERASE] = tiop->c_cc[HPUXVERASE]; | |
234 | tios.c_cc[VKILL] = tiop->c_cc[HPUXVKILL]; | |
235 | if (tios.c_lflag & ICANON) { | |
236 | tios.c_cc[VEOF] = tiop->c_cc[HPUXVEOF]; | |
237 | tios.c_cc[VEOL] = tiop->c_cc[HPUXVEOL]; | |
238 | } else { | |
239 | tios.c_cc[VMIN] = tiop->c_cc[HPUXVMIN]; | |
240 | tios.c_cc[VTIME] = tiop->c_cc[HPUXVTIME]; | |
241 | } | |
242 | /* | |
243 | * Set the new stuff | |
244 | */ | |
a8fd2d0d | 245 | if (com == HPUXTCSETA) |
7556cc71 MH |
246 | com = TIOCSETA; |
247 | else if (com == HPUXTCSETAW) | |
248 | com = TIOCSETAW; | |
a8fd2d0d | 249 | else |
7556cc71 MH |
250 | com = TIOCSETAF; |
251 | error = (*ioctlrout)(fp, com, (caddr_t)&tios); | |
252 | if (error == 0) { | |
253 | /* | |
254 | * Set line discipline | |
255 | */ | |
256 | line = tiop->c_line; | |
257 | (void) (*ioctlrout)(fp, TIOCSETD, (caddr_t)&line); | |
258 | /* | |
259 | * Set non-blocking IO if VMIN == VTIME == 0. | |
260 | * Should handle the other cases as well. It also | |
261 | * isn't correct to just turn it off as it could be | |
262 | * on as the result of a fcntl operation. | |
263 | * XXX - wouldn't need to do this at all if VMIN/VTIME | |
264 | * were implemented. | |
265 | */ | |
266 | line = (tiop->c_cc[HPUXVMIN] == 0 && | |
267 | tiop->c_cc[HPUXVTIME] == 0); | |
268 | (void) fset(fp, FNDELAY, line); | |
269 | } | |
a8fd2d0d KM |
270 | break; |
271 | ||
a8fd2d0d | 272 | default: |
d9bd2b96 | 273 | error = EINVAL; |
a8fd2d0d KM |
274 | break; |
275 | } | |
d9bd2b96 | 276 | return(error); |
a8fd2d0d KM |
277 | } |
278 | ||
7556cc71 MH |
279 | bsdtohpuxbaud(bsdspeed) |
280 | long bsdspeed; | |
281 | { | |
282 | switch (bsdspeed) { | |
283 | case B0: return(TIO_B0); | |
284 | case B50: return(TIO_B50); | |
285 | case B75: return(TIO_B75); | |
286 | case B110: return(TIO_B110); | |
287 | case B134: return(TIO_B134); | |
288 | case B150: return(TIO_B150); | |
289 | case B200: return(TIO_B200); | |
290 | case B300: return(TIO_B300); | |
291 | case B600: return(TIO_B600); | |
292 | case B1200: return(TIO_B1200); | |
293 | case B1800: return(TIO_B1800); | |
294 | case B2400: return(TIO_B2400); | |
295 | case B4800: return(TIO_B4800); | |
296 | case B9600: return(TIO_B9600); | |
297 | case B19200: return(TIO_B19200); | |
298 | case B38400: return(TIO_B38400); | |
299 | default: return(TIO_B0); | |
300 | } | |
301 | } | |
302 | ||
303 | hpuxtobsdbaud(hpuxspeed) | |
304 | int hpuxspeed; | |
305 | { | |
306 | static char hpuxtobsdbaudtab[32] = { | |
307 | B0, B50, B75, B110, B134, B150, B200, B300, | |
308 | B600, B0, B1200, B1800, B2400, B0, B4800, B0, | |
309 | B9600, B19200, B38400, B0, B0, B0, B0, B0, | |
310 | B0, B0, B0, B0, B0, B0, EXTA, EXTB | |
311 | }; | |
312 | ||
313 | return(hpuxtobsdbaudtab[hpuxspeed & TIO_CBAUD]); | |
314 | } | |
315 | ||
a8fd2d0d | 316 | /* #ifdef COMPAT */ |
d9bd2b96 MH |
317 | ohpuxgtty(p, uap, retval) |
318 | struct proc *p; | |
319 | struct args { | |
a8fd2d0d KM |
320 | int fdes; |
321 | caddr_t cmarg; | |
d9bd2b96 MH |
322 | } *uap; |
323 | int *retval; | |
324 | { | |
a8fd2d0d | 325 | |
8fbf35df | 326 | return (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg)); |
a8fd2d0d KM |
327 | } |
328 | ||
d9bd2b96 MH |
329 | ohpuxstty(p, uap, retval) |
330 | struct proc *p; | |
331 | struct args { | |
a8fd2d0d KM |
332 | int fdes; |
333 | caddr_t cmarg; | |
d9bd2b96 MH |
334 | } *uap; |
335 | int *retval; | |
336 | { | |
a8fd2d0d | 337 | |
8fbf35df | 338 | return (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg)); |
a8fd2d0d KM |
339 | } |
340 | ||
341 | /* | |
342 | * Simplified version of ioctl() for use by | |
343 | * gtty/stty and TIOCGETP/TIOCSETP. | |
344 | */ | |
345 | getsettty(fdes, com, cmarg) | |
346 | int fdes, com; | |
347 | caddr_t cmarg; | |
348 | { | |
349 | register struct file *fp; | |
350 | struct hpuxsgttyb hsb; | |
351 | struct sgttyb sb; | |
d9bd2b96 | 352 | int error; |
a8fd2d0d | 353 | |
d9bd2b96 MH |
354 | if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) |
355 | return (EBADF); | |
356 | if ((fp->f_flag & (FREAD|FWRITE)) == 0) | |
357 | return (EBADF); | |
a8fd2d0d | 358 | if (com == HPUXTIOCSETP) { |
d9bd2b96 MH |
359 | if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb)) |
360 | return (error); | |
a8fd2d0d KM |
361 | sb.sg_ispeed = hsb.sg_ispeed; |
362 | sb.sg_ospeed = hsb.sg_ospeed; | |
363 | sb.sg_erase = hsb.sg_erase; | |
364 | sb.sg_kill = hsb.sg_kill; | |
d9bd2b96 MH |
365 | sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); |
366 | if (hsb.sg_flags & V7_XTABS) | |
367 | sb.sg_flags |= XTABS; | |
368 | if (hsb.sg_flags & V7_HUPCL) | |
369 | (void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0); | |
a8fd2d0d KM |
370 | com = TIOCSETP; |
371 | } else { | |
372 | bzero((caddr_t)&hsb, sizeof hsb); | |
373 | com = TIOCGETP; | |
374 | } | |
d9bd2b96 MH |
375 | error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb); |
376 | if (error == 0 && com == TIOCGETP) { | |
a8fd2d0d KM |
377 | hsb.sg_ispeed = sb.sg_ispeed; |
378 | hsb.sg_ospeed = sb.sg_ospeed; | |
379 | hsb.sg_erase = sb.sg_erase; | |
380 | hsb.sg_kill = sb.sg_kill; | |
d9bd2b96 MH |
381 | hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); |
382 | if (sb.sg_flags & XTABS) | |
383 | hsb.sg_flags |= V7_XTABS; | |
384 | error = copyout((caddr_t)&hsb, cmarg, sizeof hsb); | |
a8fd2d0d | 385 | } |
d9bd2b96 | 386 | return (error); |
a8fd2d0d KM |
387 | } |
388 | /* #endif */ | |
389 | #endif |