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