need systm.h included for insque
[unix-history] / usr / src / sys / hp / hpux / hpux_tty.c
CommitLineData
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 *
12 * from: Utah $Hdr: hpux_tty.c 1.7 89/04/11$
13 *
14 * @(#)hpux_tty.c 7.1 (Berkeley) %G%
15 */
16
17/*
18 * stty/gtty/termio emulation stuff
19 */
20#ifdef HPUXCOMPAT
21
22#include "param.h"
23#include "systm.h"
24#include "user.h"
25#include "ioctl.h"
26#include "tty.h"
27#include "proc.h"
28#include "file.h"
29#include "conf.h"
30#include "buf.h"
31#include "uio.h"
32#include "kernel.h"
33
34#include "hpux.h"
35#include "hpux_termio.h"
36
37char hpuxtobsdbaud[32] = {
38 B0, B50, B75, B110, B134, B150, B200, B300,
39 B600, B0, B1200, B1800, B2400, B0, B4800, B0,
40 B9600, EXTA, EXTB, B0, B0, B0, B0, B0,
41 B0, B0, B0, B0, B0, B0, B0, B0
42};
43
44char bsdtohpuxbaud[16] = {
45 TIO_B0, TIO_B50, TIO_B75, TIO_B110,
46 TIO_B134, TIO_B150, TIO_B200, TIO_B300,
47 TIO_B600, TIO_B1200, TIO_B1800, TIO_B2400,
48 TIO_B4800, TIO_B9600, TIO_B19200, TIO_B38400
49};
50
51/*
52 * Map BSD style sgtty info to and from SYS5 style termio stuff.
53 * Map BSD style sgtty info to and from V7 style sgtty stuff.
54 */
55hpuxtermio(fp, com, data)
56 struct file *fp;
57 caddr_t data;
58{
59 struct sgttyb sg;
60 struct bsdtchars { /* avoid problem with ttychars.h */
61 char bsdt_intrc;
62 char bsdt_quitc;
63 char bsdt_startc;
64 char bsdt_stopc;
65 char bsdt_eofc;
66 char bsdt_brkc;
67 } tc;
68 struct bsdltchars { /* avoid problem with ttychars.h */
69 char bsdt_suspc;
70 char bsdt_dsuspc;
71 char bsdt_rprntc;
72 char bsdt_flushc;
73 char bsdt_werasc;
74 char bsdt_lnextc;
75 } ltc;
76 int lmode, (*ioctlrout)();
77 register u_short flag;
78 register struct hpuxtermio *tiop;
79
80 ioctlrout = fp->f_ops->fo_ioctl;
81 tiop = (struct hpuxtermio *)data;
82 switch (com) {
83 case HPUXTCGETA:
84 /* get everything we might need */
85 bzero(data, sizeof(struct hpuxtermio));
86 if (u.u_error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg))
87 break;
88 (void) ioctlrout(fp, TIOCGETC, (caddr_t)&tc);
89 (void) ioctlrout(fp, TIOCLGET, (caddr_t)&lmode);
90
91 /* set baud rate */
92 tiop->c_cflag = (u_short)bsdtohpuxbaud[sg.sg_ispeed&0xF];
93
94 /* set editing chars except for EOF/EOL (set below) */
95 tiop->c_cc[HPUXVINTR] = tc.bsdt_intrc;
96 tiop->c_cc[HPUXVQUIT] = tc.bsdt_quitc;
97 tiop->c_cc[HPUXVERASE] = sg.sg_erase;
98 tiop->c_cc[HPUXVKILL] = sg.sg_kill;
99
100 /* set flags */
101 flag = sg.sg_flags;
102 if ((flag & TBDELAY) == XTABS)
103 tiop->c_oflag |= TIO_TAB3;
104 else if (flag & TBDELAY)
105 tiop->c_oflag |= TIO_TAB1;
106 if (flag & LCASE) {
107 tiop->c_iflag |= TIO_IUCLC;
108 tiop->c_oflag |= TIO_OLCUC;
109 tiop->c_lflag |= TIO_XCASE;
110 }
111 if (flag & ECHO)
112 tiop->c_lflag |= TIO_ECHO;
113 if (flag & CRMOD) {
114 tiop->c_iflag |= TIO_ICRNL;
115 tiop->c_oflag |= TIO_ONLCR;
116 if (flag & CR1)
117 tiop->c_oflag |= TIO_CR1;
118 if (flag & CR2)
119 tiop->c_oflag |= TIO_CR2|TIO_ONOCR;
120 } else {
121 tiop->c_oflag |= TIO_ONLRET;
122 if (flag & NL1)
123 tiop->c_oflag |= TIO_CR1;
124 if (flag & NL2)
125 tiop->c_oflag |= TIO_CR2;
126 }
127 if (flag & RAW) {
128 tiop->c_cflag |= TIO_CS8;
129 tiop->c_iflag &= ~(TIO_ICRNL|TIO_IUCLC);
130 tiop->c_cc[HPUXVMIN] = 6;
131 tiop->c_cc[HPUXVTIME] = 1;
132 } else {
133 tiop->c_iflag |= TIO_BRKINT;
134 if (tc.bsdt_startc == CSTART && tc.bsdt_stopc == CSTOP)
135 tiop->c_iflag |= TIO_IXON;
136 if (flag & TANDEM)
137 tiop->c_iflag |= TIO_IXOFF;
138 else if ((lmode & LDECCTQ) == 0)
139 tiop->c_iflag |= TIO_IXANY;
140 if ((lmode & LLITOUT) == 0) {
141 tiop->c_iflag |= TIO_IGNPAR;
142 tiop->c_oflag |= TIO_OPOST;
143 }
144 if (lmode & LPASS8)
145 tiop->c_cflag |= TIO_CS8;
146 else
147 tiop->c_iflag |= TIO_ISTRIP;
148 tiop->c_cflag |= TIO_CS7|TIO_PARENB;
149 tiop->c_lflag |= TIO_ISIG;
150 if (flag & CBREAK) {
151 tiop->c_cc[HPUXVMIN] = 6;
152 tiop->c_cc[HPUXVTIME] = 1;
153 } else {
154 tiop->c_lflag |= TIO_ICANON|TIO_ECHOK;
155 if (lmode & LCRTERA)
156 tiop->c_lflag |= TIO_ECHOE;
157 tiop->c_cc[HPUXVEOF] = tc.bsdt_eofc;
158 tiop->c_cc[HPUXVEOL] = tc.bsdt_brkc;
159 }
160 }
161 tiop->c_cflag |= TIO_PARENB;
162 if (flag & ODDP) {
163 if (flag & EVENP)
164 tiop->c_cflag &= ~TIO_PARENB;
165 tiop->c_cflag |= TIO_PARODD;
166 }
167 if (tiop->c_cflag & TIO_PARENB)
168 tiop->c_iflag |= TIO_INPCK;
169 if (flag & VTDELAY)
170 tiop->c_oflag |= TIO_FFDLY;
171 if (flag & BSDELAY)
172 tiop->c_oflag |= TIO_BSDLY;
173 break;
174
175 case HPUXTCSETA:
176 case HPUXTCSETAW:
177 case HPUXTCSETAF:
178 /* get old lmode and determine if we are a tty */
179 if (u.u_error = ioctlrout(fp, TIOCLGET, (caddr_t)&lmode))
180 break;
181 (void) ioctlrout(fp, TIOCGLTC, (caddr_t)&ltc);
182
183 /* set baud rate */
184 sg.sg_ispeed = hpuxtobsdbaud[tiop->c_cflag&TIO_CBAUD];
185 sg.sg_ospeed = sg.sg_ispeed;
186
187 /* set special chars to defaults for cooked mode */
188 sg.sg_erase = tiop->c_cc[HPUXVERASE];
189 sg.sg_kill = tiop->c_cc[HPUXVKILL];
190 tc.bsdt_intrc = tiop->c_cc[HPUXVINTR];
191 tc.bsdt_quitc = tiop->c_cc[HPUXVQUIT];
192 tc.bsdt_startc = CSTART;
193 tc.bsdt_stopc = CSTOP;
194 tc.bsdt_eofc = tiop->c_cc[HPUXVEOF];
195 tc.bsdt_brkc = tiop->c_cc[HPUXVEOL];
196 ltc.bsdt_suspc = CSUSP;
197 ltc.bsdt_dsuspc = CDSUSP;
198 ltc.bsdt_flushc = CFLUSH;
199 ltc.bsdt_lnextc = CLNEXT;
200
201 /* set flags */
202 flag = 0;
203 if (tiop->c_oflag & TIO_BSDLY)
204 flag |= BSDELAY;
205 if (tiop->c_oflag & TIO_FFDLY)
206 flag |= VTDELAY;
207 if (tiop->c_oflag & TIO_TAB1) {
208 if (tiop->c_oflag & TIO_TAB2)
209 flag |= XTABS;
210 else
211 flag |= TAB1;
212 } else if (tiop->c_oflag & TIO_TAB2)
213 flag |= TAB2;
214 if (tiop->c_oflag & TIO_CR1) {
215 flag |= CR1;
216 if (tiop->c_oflag & TIO_ONLRET)
217 flag |= NL1;
218 }
219 if (tiop->c_oflag & TIO_CR2) {
220 flag |= CR2;
221 if (tiop->c_oflag & TIO_ONLRET)
222 flag |= NL2;
223 }
224 if ((tiop->c_oflag & (TIO_NLDLY|TIO_ONLRET)) == TIO_NLDLY)
225 flag |= NL2;
226 if ((tiop->c_cflag & TIO_PARENB) == 0)
227 flag |= ODDP|EVENP;
228 else if (tiop->c_cflag & TIO_PARODD)
229 flag |= ODDP;
230 else
231 flag |= EVENP;
232 if ((tiop->c_iflag & TIO_ICRNL) || (tiop->c_oflag & TIO_ONLCR))
233 flag |= CRMOD;
234 if (tiop->c_lflag & TIO_ECHO)
235 flag |= ECHO;
236 if (tiop->c_iflag & TIO_IUCLC)
237 flag |= LCASE;
238 if (tiop->c_iflag & TIO_IXOFF)
239 flag |= TANDEM;
240 if ((tiop->c_lflag & TIO_ICANON) == 0) {
241 if (tiop->c_lflag & TIO_ISIG)
242 flag |= CBREAK;
243 else
244 flag |= RAW;
245 }
246 if (flag & CBREAK) {
247 ltc.bsdt_suspc = ltc.bsdt_dsuspc = -1;
248 ltc.bsdt_flushc = ltc.bsdt_lnextc = -1;
249 if ((tiop->c_iflag & TIO_IXON) == 0)
250 tc.bsdt_startc = tc.bsdt_stopc = -1;
251 }
252 sg.sg_flags = flag;
253 lmode &= ~(LCRTERA|LLITOUT|LDECCTQ|LPASS8);
254 if (tiop->c_lflag & TIO_ECHOE)
255 lmode |= LCRTERA;
256 if ((tiop->c_oflag & TIO_OPOST) == 0)
257 lmode |= LLITOUT;
258 if ((tiop->c_iflag & TIO_IXANY) == 0)
259 lmode |= LDECCTQ;
260 if ((tiop->c_cflag & TIO_CS8) &&
261 (tiop->c_iflag & TIO_ISTRIP) == 0)
262 lmode |= LPASS8;
263
264 /* set the new stuff */
265 if (com == HPUXTCSETA)
266 com = TIOCSETN;
267 else
268 com = TIOCSETP;
269 (void) ioctlrout(fp, com, (caddr_t)&sg);
270 (void) ioctlrout(fp, TIOCSETC, (caddr_t)&tc);
271 (void) ioctlrout(fp, TIOCSLTC, (caddr_t)&ltc);
272 (void) ioctlrout(fp, TIOCLSET, (caddr_t)&lmode);
273 if (tiop->c_cflag & TIO_HUPCL)
274 (void) ioctlrout(fp, TIOCHPCL, (caddr_t)0);
275 break;
276
277 case HPUXTIOCGETP:
278 u.u_error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg);
279 if (u.u_error)
280 break;
281 flag = sg.sg_flags;
282 sg.sg_flags &= ~(V7_HUPCL|V7_XTABS|V7_NOAL);
283 if (flag & XTABS)
284 sg.sg_flags |= V7_XTABS;
285 bcopy((caddr_t)&sg, data, sizeof sg);
286 break;
287
288 case HPUXTIOCSETP:
289 bcopy(data, (caddr_t)&sg, sizeof sg);
290 flag = sg.sg_flags;
291 sg.sg_flags &= ~(V7_HUPCL|V7_XTABS|V7_NOAL);
292 if (flag & V7_XTABS)
293 sg.sg_flags |= XTABS;
294 u.u_error = ioctlrout(fp, TIOCSETP, (caddr_t)&sg);
295 if (flag & V7_HUPCL)
296 (void) ioctlrout(fp, TIOCHPCL, (caddr_t)0);
297 break;
298
299 default:
300 break;
301 }
302 return(u.u_error);
303}
304
305/* #ifdef COMPAT */
306ohpuxgtty()
307{
308 struct a {
309 int fdes;
310 caddr_t cmarg;
311 } *uap = (struct a *)u.u_ap;
312
313 getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg);
314}
315
316ohpuxstty()
317{
318 struct a {
319 int fdes;
320 caddr_t cmarg;
321 } *uap = (struct a *)u.u_ap;
322
323 getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg);
324}
325
326/*
327 * Simplified version of ioctl() for use by
328 * gtty/stty and TIOCGETP/TIOCSETP.
329 */
330getsettty(fdes, com, cmarg)
331 int fdes, com;
332 caddr_t cmarg;
333{
334 register struct file *fp;
335 struct hpuxsgttyb hsb;
336 struct sgttyb sb;
337
338 if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) {
339 u.u_error = EBADF;
340 return;
341 }
342 if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
343 u.u_error = EBADF;
344 return;
345 }
346 if (com == HPUXTIOCSETP) {
347 u.u_error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb);
348 if (u.u_error)
349 return;
350 sb.sg_ispeed = hsb.sg_ispeed;
351 sb.sg_ospeed = hsb.sg_ospeed;
352 sb.sg_erase = hsb.sg_erase;
353 sb.sg_kill = hsb.sg_kill;
354 sb.sg_flags = (short) hsb.sg_flags;
355 com = TIOCSETP;
356 } else {
357 bzero((caddr_t)&hsb, sizeof hsb);
358 com = TIOCGETP;
359 }
360 u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb);
361 if (u.u_error == 0 && com == TIOCGETP) {
362 hsb.sg_ispeed = sb.sg_ispeed;
363 hsb.sg_ospeed = sb.sg_ospeed;
364 hsb.sg_erase = sb.sg_erase;
365 hsb.sg_kill = sb.sg_kill;
366 hsb.sg_flags = (int) sb.sg_flags;
367 u.u_error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
368 }
369}
370/* #endif */
371#endif