Media table reorganization.
[unix-history] / sys / kern / tty_compat.c
CommitLineData
15637ed4
RG
1/*-
2 * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
600f7f07 33 * from: @(#)tty_compat.c 7.10 (Berkeley) 5/9/91
4c45483e 34 * $Id: tty_compat.c,v 1.2 1993/10/16 15:24:57 rgrimes Exp $
15637ed4
RG
35 */
36
37/*
38 * mapping routines for old line discipline (yuck)
39 */
40#ifdef COMPAT_43
41
42#include "param.h"
43#include "systm.h"
44#include "ioctl.h"
45#include "tty.h"
46#include "termios.h"
47#include "proc.h"
48#include "file.h"
49#include "conf.h"
50#include "dkstat.h"
51#include "kernel.h"
52#include "syslog.h"
53
4c45483e
GW
54static int ttcompatgetflags(struct tty *);
55static void ttcompatsetflags(struct tty *, struct termios *);
56static void ttcompatsetlflags(struct tty *, struct termios *);
57
15637ed4
RG
58int ttydebug = 0;
59
60static struct speedtab compatspeeds[] = {
61#define MAX_SPEED 17
62 115200, 17,
63 57600, 16,
64 38400, 15,
65 19200, 14,
66 9600, 13,
67 4800, 12,
68 2400, 11,
69 1800, 10,
70 1200, 9,
71 600, 8,
72 300, 7,
73 200, 6,
74 150, 5,
75 134, 4,
76 110, 3,
77 75, 2,
78 50, 1,
79 0, 0,
80 -1, -1,
81};
82static int compatspcodes[] = {
83 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
84 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
85};
86
87/*ARGSUSED*/
4c45483e 88int
15637ed4
RG
89ttcompat(tp, com, data, flag)
90 register struct tty *tp;
4c45483e 91 int com;
15637ed4 92 caddr_t data;
4c45483e 93 int flag;
15637ed4
RG
94{
95
96 switch (com) {
97 case TIOCGETP: {
98 register struct sgttyb *sg = (struct sgttyb *)data;
99 register u_char *cc = tp->t_cc;
100 register speed;
101
102 speed = ttspeedtab(tp->t_ospeed, compatspeeds);
103 sg->sg_ospeed = (speed == -1) ? MAX_SPEED : speed;
104 if (tp->t_ispeed == 0)
105 sg->sg_ispeed = sg->sg_ospeed;
106 else {
107 speed = ttspeedtab(tp->t_ispeed, compatspeeds);
108 sg->sg_ispeed = (speed == -1) ? MAX_SPEED : speed;
109 }
110 sg->sg_erase = cc[VERASE];
111 sg->sg_kill = cc[VKILL];
112 sg->sg_flags = tp->t_flags = ttcompatgetflags(tp);
113 break;
114 }
115
116 case TIOCSETP:
117 case TIOCSETN: {
118 register struct sgttyb *sg = (struct sgttyb *)data;
119 struct termios term;
120 int speed;
121
122 term = tp->t_termios;
123 if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0)
124 term.c_ispeed = speed;
125 else
126 term.c_ispeed = compatspcodes[speed];
127 if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0)
128 term.c_ospeed = speed;
129 else
130 term.c_ospeed = compatspcodes[speed];
131 term.c_cc[VERASE] = sg->sg_erase;
132 term.c_cc[VKILL] = sg->sg_kill;
133 tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff;
134 ttcompatsetflags(tp, &term);
135 return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA,
136 (caddr_t)&term, flag));
137 }
138
139 case TIOCGETC: {
140 struct tchars *tc = (struct tchars *)data;
141 register u_char *cc = tp->t_cc;
142
143 tc->t_intrc = cc[VINTR];
144 tc->t_quitc = cc[VQUIT];
145 tc->t_startc = cc[VSTART];
146 tc->t_stopc = cc[VSTOP];
147 tc->t_eofc = cc[VEOF];
148 tc->t_brkc = cc[VEOL];
149 break;
150 }
151 case TIOCSETC: {
152 struct tchars *tc = (struct tchars *)data;
153 register u_char *cc = tp->t_cc;
154
155 cc[VINTR] = tc->t_intrc;
156 cc[VQUIT] = tc->t_quitc;
157 cc[VSTART] = tc->t_startc;
158 cc[VSTOP] = tc->t_stopc;
159 cc[VEOF] = tc->t_eofc;
160 cc[VEOL] = tc->t_brkc;
161 if (tc->t_brkc == -1)
162 cc[VEOL2] = _POSIX_VDISABLE;
163 break;
164 }
165 case TIOCSLTC: {
166 struct ltchars *ltc = (struct ltchars *)data;
167 register u_char *cc = tp->t_cc;
168
169 cc[VSUSP] = ltc->t_suspc;
170 cc[VDSUSP] = ltc->t_dsuspc;
171 cc[VREPRINT] = ltc->t_rprntc;
172 cc[VDISCARD] = ltc->t_flushc;
173 cc[VWERASE] = ltc->t_werasc;
174 cc[VLNEXT] = ltc->t_lnextc;
175 break;
176 }
177 case TIOCGLTC: {
178 struct ltchars *ltc = (struct ltchars *)data;
179 register u_char *cc = tp->t_cc;
180
181 ltc->t_suspc = cc[VSUSP];
182 ltc->t_dsuspc = cc[VDSUSP];
183 ltc->t_rprntc = cc[VREPRINT];
184 ltc->t_flushc = cc[VDISCARD];
185 ltc->t_werasc = cc[VWERASE];
186 ltc->t_lnextc = cc[VLNEXT];
187 break;
188 }
189 case TIOCLBIS:
190 case TIOCLBIC:
191 case TIOCLSET: {
192 struct termios term;
193
194 term = tp->t_termios;
195 if (com == TIOCLSET)
196 tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16;
197 else {
198 tp->t_flags =
199 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
200 if (com == TIOCLBIS)
201 tp->t_flags |= *(int *)data<<16;
202 else
203 tp->t_flags &= ~(*(int *)data<<16);
204 }
205 ttcompatsetlflags(tp, &term);
206 return (ttioctl(tp, TIOCSETA, (caddr_t)&term, flag));
207 }
208 case TIOCLGET:
209 tp->t_flags =
210 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff);
211 *(int *)data = tp->t_flags>>16;
212 if (ttydebug)
213 printf("CLGET: returning %x\n", *(int *)data);
214 break;
215
216 case OTIOCGETD:
217 *(int *)data = tp->t_line ? tp->t_line : 2;
218 break;
219
220 case OTIOCSETD: {
221 int ldisczero = 0;
222
223 return (ttioctl(tp, TIOCSETD,
224 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
225 }
226
227 case OTIOCCONS:
228 *(int *)data = 1;
229 return (ttioctl(tp, TIOCCONS, data, flag));
230
231 default:
232 return (-1);
233 }
234 return (0);
235}
236
4c45483e 237static int
15637ed4
RG
238ttcompatgetflags(tp)
239 register struct tty *tp;
240{
241 register long iflag = tp->t_iflag;
242 register long lflag = tp->t_lflag;
243 register long oflag = tp->t_oflag;
244 register long cflag = tp->t_cflag;
245 register flags = 0;
246
247 if (iflag&IXOFF)
248 flags |= TANDEM;
249 if (iflag&ICRNL || oflag&ONLCR)
250 flags |= CRMOD;
251 if ((cflag&CSIZE) == CS8) {
252 flags |= PASS8;
253 if (iflag&ISTRIP)
254 flags |= ANYP;
255 }
256 else if (cflag&PARENB) {
257 if (iflag&INPCK) {
258 if (cflag&PARODD)
259 flags |= ODDP;
260 else
261 flags |= EVENP;
262 }
263 else
264 flags |= EVENP | ODDP;
265 }
266
267 if ((lflag&ICANON) == 0) {
268 /* fudge */
269 if (iflag&(INPCK|ISTRIP|IXON) || lflag&(IEXTEN|ISIG)
270 || cflag&(CSIZE|PARENB) != CS8)
271 flags |= CBREAK;
272 else
273 flags |= RAW;
274 }
275 if (!(flags&RAW) && !(oflag&OPOST) && cflag&(CSIZE|PARENB) == CS8)
276 flags |= LITOUT;
277 if (oflag&OXTABS)
278 flags |= XTABS;
279 if (lflag&ECHOE)
280 flags |= CRTERA|CRTBS;
281 if (lflag&ECHOKE)
282 flags |= CRTKIL|CRTBS;
283 if (lflag&ECHOPRT)
284 flags |= PRTERA;
285 if (lflag&ECHOCTL)
286 flags |= CTLECH;
287 if ((iflag&IXANY) == 0)
288 flags |= DECCTQ;
289 flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
290if (ttydebug)
291 printf("getflags: %x\n", flags);
292 return (flags);
293}
294
4c45483e 295static void
15637ed4
RG
296ttcompatsetflags(tp, t)
297 register struct tty *tp;
298 register struct termios *t;
299{
300 register flags = tp->t_flags;
301 register long iflag = t->c_iflag;
302 register long oflag = t->c_oflag;
303 register long lflag = t->c_lflag;
304 register long cflag = t->c_cflag;
305
306 if (flags & RAW) {
307 iflag &= IXOFF|IXANY;
308 lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
309 } else {
310 iflag |= BRKINT|IXON|IMAXBEL;
311 lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */
312 if (flags & XTABS)
313 oflag |= OXTABS;
314 else
315 oflag &= ~OXTABS;
316 if (flags & CBREAK)
317 lflag &= ~ICANON;
318 else
319 lflag |= ICANON;
320 if (flags&CRMOD) {
321 iflag |= ICRNL;
322 oflag |= ONLCR;
323 } else {
324 iflag &= ~ICRNL;
325 oflag &= ~ONLCR;
326 }
327 }
328 if (flags&ECHO)
329 lflag |= ECHO;
330 else
331 lflag &= ~ECHO;
332
333 cflag &= ~(CSIZE|PARENB);
334 if (flags&(RAW|LITOUT|PASS8)) {
335 cflag |= CS8;
336 if (!(flags&(RAW|PASS8))
337 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP))
338 iflag |= ISTRIP;
339 else
340 iflag &= ~ISTRIP;
341 if (flags&(RAW|LITOUT))
342 oflag &= ~OPOST;
343 else
344 oflag |= OPOST;
345 } else {
346 cflag |= CS7|PARENB;
347 iflag |= ISTRIP;
348 oflag |= OPOST;
349 }
350 if ((flags&(EVENP|ODDP)) == EVENP) {
351 iflag |= INPCK;
352 cflag &= ~PARODD;
353 } else if ((flags&(EVENP|ODDP)) == ODDP) {
354 iflag |= INPCK;
355 cflag |= PARODD;
356 } else
357 iflag &= ~INPCK;
358 if (flags&TANDEM)
359 iflag |= IXOFF;
360 else
361 iflag &= ~IXOFF;
362 t->c_iflag = iflag;
363 t->c_oflag = oflag;
364 t->c_lflag = lflag;
365 t->c_cflag = cflag;
366}
367
4c45483e 368static void
15637ed4
RG
369ttcompatsetlflags(tp, t)
370 register struct tty *tp;
371 register struct termios *t;
372{
373 register flags = tp->t_flags;
374 register long iflag = t->c_iflag;
375 register long oflag = t->c_oflag;
376 register long lflag = t->c_lflag;
377 register long cflag = t->c_cflag;
378
379 if (flags&CRTERA)
380 lflag |= ECHOE;
381 else
382 lflag &= ~ECHOE;
383 if (flags&CRTKIL)
384 lflag |= ECHOKE;
385 else
386 lflag &= ~ECHOKE;
387 if (flags&PRTERA)
388 lflag |= ECHOPRT;
389 else
390 lflag &= ~ECHOPRT;
391 if (flags&CTLECH)
392 lflag |= ECHOCTL;
393 else
394 lflag &= ~ECHOCTL;
395 if ((flags&DECCTQ) == 0)
396 lflag |= IXANY;
397 else
398 lflag &= ~IXANY;
399 lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
400 lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH);
401
402 cflag &= ~(CSIZE|PARENB);
403 /*
404 * The next if-else statement is copied from above so don't bother
405 * checking it separately. We could avoid fiddlling with the
406 * character size if the mode is already RAW or if neither the
407 * LITOUT bit or the PASS8 bit is being changed, but the delta of
408 * the change is not available here and skipping the RAW case would
409 * make the code different from above.
410 */
411 if (flags&(RAW|LITOUT|PASS8)) {
412 cflag |= CS8;
413 if (!(flags&(RAW|PASS8))
414 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP))
415 iflag |= ISTRIP;
416 else
417 iflag &= ~ISTRIP;
418 if (flags&(RAW|LITOUT))
419 oflag &= ~OPOST;
420 else
421 oflag |= OPOST;
422 } else {
423 cflag |= CS7|PARENB;
424 iflag |= ISTRIP;
425 oflag |= OPOST;
426 }
427 t->c_iflag = iflag;
428 t->c_oflag = oflag;
429 t->c_lflag = lflag;
430 t->c_cflag = cflag;
431}
432#endif /* COMPAT_43 */