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