add support for kernel profiling; add sysctl_struct; eliminate trailing blanks
[unix-history] / usr / src / sys / kern / tty_compat.c
CommitLineData
f406ae69
KB
1/*-
2 * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
3 * All rights reserved.
f73a43fc 4 *
f406ae69
KB
5 * %sccs.include.redist.c%
6 *
38a01dbe 7 * @(#)tty_compat.c 7.16 (Berkeley) %G%
f73a43fc
MT
8 */
9
10/*
e39f9ea6 11 * mapping routines for old line discipline (yuck)
f73a43fc 12 */
7b630ab2 13#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
f73a43fc 14
38a01dbe
KB
15#include <sys/param.h>
16#include <sys/systm.h>
17#include <sys/ioctl.h>
18#include <sys/proc.h>
19#include <sys/tty.h>
20#include <sys/termios.h>
21#include <sys/file.h>
22#include <sys/conf.h>
23#include <sys/kernel.h>
24#include <sys/syslog.h>
f73a43fc 25
e39f9ea6 26int ttydebug = 0;
f73a43fc 27
f73a43fc
MT
28static struct speedtab compatspeeds[] = {
29 38400, 15,
30 19200, 14,
31 9600, 13,
32 4800, 12,
33 2400, 11,
34 1800, 10,
35 1200, 9,
36 600, 8,
37 300, 7,
38 200, 6,
39 150, 5,
40 134, 4,
41 110, 3,
42 75, 2,
43 50, 1,
44 0, 0,
45 -1, -1,
46};
47static int compatspcodes[16] = {
48 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
49 1800, 2400, 4800, 9600, 19200, 38400,
50};
51
52/*ARGSUSED*/
53ttcompat(tp, com, data, flag)
54 register struct tty *tp;
fd1092d8 55 int com;
f73a43fc 56 caddr_t data;
fd1092d8 57 int flag;
f73a43fc 58{
7fbb76da
MT
59
60 switch (com) {
f73a43fc
MT
61 case TIOCGETP: {
62 register struct sgttyb *sg = (struct sgttyb *)data;
63 register u_char *cc = tp->t_cc;
64 register speed;
65
66 speed = ttspeedtab(tp->t_ospeed, compatspeeds);
67 sg->sg_ospeed = (speed == -1) ? 15 : speed;
68 if (tp->t_ispeed == 0)
69 sg->sg_ispeed = sg->sg_ospeed;
70 else {
71 speed = ttspeedtab(tp->t_ispeed, compatspeeds);
72 sg->sg_ispeed = (speed == -1) ? 15 : speed;
73 }
f73a43fc
MT
74 sg->sg_erase = cc[VERASE];
75 sg->sg_kill = cc[VKILL];
e39f9ea6 76 sg->sg_flags = ttcompatgetflags(tp);
f73a43fc
MT
77 break;
78 }
79
80 case TIOCSETP:
81 case TIOCSETN: {
82 register struct sgttyb *sg = (struct sgttyb *)data;
83 struct termios term;
84 int speed;
85
86 term = tp->t_termios;
f73a43fc
MT
87 if ((speed = sg->sg_ispeed) > 15 || speed < 0)
88 term.c_ispeed = speed;
89 else
90 term.c_ispeed = compatspcodes[speed];
91 if ((speed = sg->sg_ospeed) > 15 || speed < 0)
92 term.c_ospeed = speed;
93 else
94 term.c_ospeed = compatspcodes[speed];
f73a43fc
MT
95 term.c_cc[VERASE] = sg->sg_erase;
96 term.c_cc[VKILL] = sg->sg_kill;
7fbb76da 97 tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff;
f73a43fc
MT
98 ttcompatsetflags(tp, &term);
99 return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
100 &term, flag));
101 }
102
103 case TIOCGETC: {
104 struct tchars *tc = (struct tchars *)data;
105 register u_char *cc = tp->t_cc;
106
107 tc->t_intrc = cc[VINTR];
108 tc->t_quitc = cc[VQUIT];
109 tc->t_startc = cc[VSTART];
110 tc->t_stopc = cc[VSTOP];
111 tc->t_eofc = cc[VEOF];
112 tc->t_brkc = cc[VEOL];
113 break;
114 }
115 case TIOCSETC: {
116 struct tchars *tc = (struct tchars *)data;
117 register u_char *cc = tp->t_cc;
118
119 cc[VINTR] = tc->t_intrc;
120 cc[VQUIT] = tc->t_quitc;
121 cc[VSTART] = tc->t_startc;
122 cc[VSTOP] = tc->t_stopc;
123 cc[VEOF] = tc->t_eofc;
124 cc[VEOL] = tc->t_brkc;
125 if (tc->t_brkc == -1)
e39f9ea6 126 cc[VEOL2] = _POSIX_VDISABLE;
f73a43fc
MT
127 break;
128 }
129 case TIOCSLTC: {
130 struct ltchars *ltc = (struct ltchars *)data;
131 register u_char *cc = tp->t_cc;
132
133 cc[VSUSP] = ltc->t_suspc;
134 cc[VDSUSP] = ltc->t_dsuspc;
135 cc[VREPRINT] = ltc->t_rprntc;
ee3c7f94 136 cc[VDISCARD] = ltc->t_flushc;
f73a43fc
MT
137 cc[VWERASE] = ltc->t_werasc;
138 cc[VLNEXT] = ltc->t_lnextc;
139 break;
140 }
141 case TIOCGLTC: {
142 struct ltchars *ltc = (struct ltchars *)data;
143 register u_char *cc = tp->t_cc;
144
145 ltc->t_suspc = cc[VSUSP];
146 ltc->t_dsuspc = cc[VDSUSP];
147 ltc->t_rprntc = cc[VREPRINT];
ee3c7f94 148 ltc->t_flushc = cc[VDISCARD];
f73a43fc
MT
149 ltc->t_werasc = cc[VWERASE];
150 ltc->t_lnextc = cc[VLNEXT];
151 break;
152 }
153 case TIOCLBIS:
154 case TIOCLBIC:
155 case TIOCLSET: {
156 struct termios term;
157
158 term = tp->t_termios;
159 if (com == TIOCLSET)
e39f9ea6 160 tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
f73a43fc
MT
161 else {
162 tp->t_flags =
163 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
164 if (com == TIOCLBIS)
e39f9ea6 165 tp->t_flags |= *(int *)data<<16;
f73a43fc 166 else
e39f9ea6 167 tp->t_flags &= ~(*(int *)data<<16);
f73a43fc
MT
168 }
169 ttcompatsetlflags(tp, &term);
170 return (ttioctl(tp, TIOCSETA, &term, flag));
171 }
172 case TIOCLGET:
e39f9ea6
MT
173 *(int *)data = ttcompatgetflags(tp)>>16;
174 if (ttydebug)
175 printf("CLGET: returning %x\n", *(int *)data);
f73a43fc 176 break;
e39f9ea6 177
6ef1614c 178 case OTIOCGETD:
e39f9ea6
MT
179 *(int *)data = tp->t_line ? tp->t_line : 2;
180 break;
181
6ef1614c 182 case OTIOCSETD: {
e39f9ea6
MT
183 int ldisczero = 0;
184
7fbb76da 185 return (ttioctl(tp, TIOCSETD,
e39f9ea6 186 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
7fbb76da 187 }
a574d21e
KM
188
189 case OTIOCCONS:
190 *(int *)data = 1;
7fbb76da 191 return (ttioctl(tp, TIOCCONS, data, flag));
e39f9ea6 192
f73a43fc
MT
193 default:
194 return (-1);
195 }
7fbb76da 196 return (0);
f73a43fc
MT
197}
198
f73a43fc
MT
199ttcompatgetflags(tp)
200 register struct tty *tp;
201{
202 register long iflag = tp->t_iflag;
203 register long lflag = tp->t_lflag;
204 register long oflag = tp->t_oflag;
205 register long cflag = tp->t_cflag;
206 register flags = 0;
207
208 if (iflag&IXOFF)
209 flags |= TANDEM;
210 if (iflag&ICRNL || oflag&ONLCR)
211 flags |= CRMOD;
212 if (cflag&PARENB) {
213 if (iflag&INPCK) {
214 if (cflag&PARODD)
215 flags |= ODDP;
216 else
217 flags |= EVENP;
218 } else
219 flags |= EVENP | ODDP;
220 } else {
221 if ((tp->t_flags&LITOUT) && !(oflag&OPOST))
222 flags |= LITOUT;
223 if (tp->t_flags&PASS8)
224 flags |= PASS8;
225 }
226
227 if ((lflag&ICANON) == 0) {
228 /* fudge */
229 if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB)
230 flags |= CBREAK;
231 else
232 flags |= RAW;
233 }
702e2c39
MT
234 if (cflag&MDMBUF)
235 flags |= MDMBUF;
236 if ((cflag&HUPCL) == 0)
237 flags |= NOHANG;
f73a43fc
MT
238 if (oflag&OXTABS)
239 flags |= XTABS;
f73a43fc 240 if (lflag&ECHOE)
e39f9ea6 241 flags |= CRTERA|CRTBS;
f73a43fc 242 if (lflag&ECHOKE)
e39f9ea6 243 flags |= CRTKIL|CRTBS;
f73a43fc
MT
244 if (lflag&ECHOPRT)
245 flags |= PRTERA;
246 if (lflag&ECHOCTL)
247 flags |= CTLECH;
248 if ((iflag&IXANY) == 0)
249 flags |= DECCTQ;
702e2c39 250 flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH);
e39f9ea6
MT
251if (ttydebug)
252 printf("getflags: %x\n", flags);
f73a43fc
MT
253 return (flags);
254}
255
256ttcompatsetflags(tp, t)
257 register struct tty *tp;
258 register struct termios *t;
259{
260 register flags = tp->t_flags;
261 register long iflag = t->c_iflag;
262 register long oflag = t->c_oflag;
263 register long lflag = t->c_lflag;
264 register long cflag = t->c_cflag;
265
266 if (flags & RAW) {
267 iflag &= IXOFF;
268 oflag &= ~OPOST;
85a1af63 269 lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
f73a43fc 270 } else {
85a1af63 271 iflag |= BRKINT|IXON|IMAXBEL;
f73a43fc 272 oflag |= OPOST;
7fbb76da 273 lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */
f73a43fc
MT
274 if (flags & XTABS)
275 oflag |= OXTABS;
276 else
277 oflag &= ~OXTABS;
278 if (flags & CBREAK)
279 lflag &= ~ICANON;
280 else
281 lflag |= ICANON;
282 if (flags&CRMOD) {
283 iflag |= ICRNL;
284 oflag |= ONLCR;
285 } else {
286 iflag &= ~ICRNL;
287 oflag &= ~ONLCR;
288 }
289 }
290 if (flags&ECHO)
291 lflag |= ECHO;
292 else
293 lflag &= ~ECHO;
294
295 if (flags&(RAW|LITOUT|PASS8)) {
296 cflag &= ~(CSIZE|PARENB);
297 cflag |= CS8;
298 if ((flags&(RAW|PASS8)) == 0)
299 iflag |= ISTRIP;
7fbb76da
MT
300 else
301 iflag &= ~ISTRIP;
f73a43fc
MT
302 } else {
303 cflag &= ~CSIZE;
304 cflag |= CS7|PARENB;
7fbb76da 305 iflag |= ISTRIP;
f73a43fc
MT
306 }
307 if ((flags&(EVENP|ODDP)) == EVENP) {
308 iflag |= INPCK;
309 cflag &= ~PARODD;
310 } else if ((flags&(EVENP|ODDP)) == ODDP) {
311 iflag |= INPCK;
312 cflag |= PARODD;
313 } else
314 iflag &= ~INPCK;
315 if (flags&LITOUT)
316 oflag &= ~OPOST; /* move earlier ? */
317 if (flags&TANDEM)
318 iflag |= IXOFF;
319 else
320 iflag &= ~IXOFF;
321 t->c_iflag = iflag;
322 t->c_oflag = oflag;
323 t->c_lflag = lflag;
324 t->c_cflag = cflag;
325}
326
f73a43fc
MT
327ttcompatsetlflags(tp, t)
328 register struct tty *tp;
329 register struct termios *t;
330{
331 register flags = tp->t_flags;
332 register long iflag = t->c_iflag;
333 register long oflag = t->c_oflag;
334 register long lflag = t->c_lflag;
335 register long cflag = t->c_cflag;
e39f9ea6 336
f73a43fc
MT
337 if (flags&CRTERA)
338 lflag |= ECHOE;
339 else
e39f9ea6 340 lflag &= ~ECHOE;
f73a43fc
MT
341 if (flags&CRTKIL)
342 lflag |= ECHOKE;
343 else
344 lflag &= ~ECHOKE;
345 if (flags&PRTERA)
346 lflag |= ECHOPRT;
347 else
348 lflag &= ~ECHOPRT;
349 if (flags&CTLECH)
350 lflag |= ECHOCTL;
351 else
352 lflag &= ~ECHOCTL;
353 if ((flags&DECCTQ) == 0)
702e2c39 354 iflag |= IXANY;
f73a43fc 355 else
702e2c39
MT
356 iflag &= ~IXANY;
357 if (flags & MDMBUF)
358 cflag |= MDMBUF;
359 else
360 cflag &= ~MDMBUF;
361 if (flags&NOHANG)
362 cflag &= ~HUPCL;
363 else
364 cflag |= HUPCL;
365 lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH);
366 lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH);
f73a43fc
MT
367 if (flags&(LITOUT|PASS8)) {
368 iflag &= ~ISTRIP;
369 cflag &= ~(CSIZE|PARENB);
370 cflag |= CS8;
371 if (flags&LITOUT)
372 oflag &= ~OPOST;
373 if ((flags&(PASS8|RAW)) == 0)
374 iflag |= ISTRIP;
375 } else if ((flags&RAW) == 0) {
376 cflag &= ~CSIZE;
377 cflag |= CS7|PARENB;
378 oflag |= OPOST;
379 }
380 t->c_iflag = iflag;
381 t->c_oflag = oflag;
382 t->c_lflag = lflag;
383 t->c_cflag = cflag;
384}
7b630ab2 385#endif /* COMPAT_43 || COMPAT_SUNOS */