1df8bae1dSRodney W. Grimes /*-
251369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
351369649SPedro F. Giffuni *
4df8bae1dSRodney W. Grimes * Copyright (c) 1982, 1986, 1991, 1993
5df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved.
6df8bae1dSRodney W. Grimes *
7df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without
8df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions
9df8bae1dSRodney W. Grimes * are met:
10df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright
11df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer.
12df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright
13df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the
14df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution.
1569a28758SEd Maste * 3. Neither the name of the University nor the names of its contributors
16df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software
17df8bae1dSRodney W. Grimes * without specific prior written permission.
18df8bae1dSRodney W. Grimes *
19df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29df8bae1dSRodney W. Grimes * SUCH DAMAGE.
30df8bae1dSRodney W. Grimes */
31df8bae1dSRodney W. Grimes
32677b542eSDavid E. O'Brien #include <sys/cdefs.h>
33df8bae1dSRodney W. Grimes /*
34df8bae1dSRodney W. Grimes * mapping routines for old line discipline (yuck)
35df8bae1dSRodney W. Grimes */
36df8bae1dSRodney W. Grimes
37df8bae1dSRodney W. Grimes #include <sys/param.h>
38df8bae1dSRodney W. Grimes #include <sys/systm.h>
39afd2f6c2SBruce Evans #include <sys/ioctl_compat.h>
40df8bae1dSRodney W. Grimes #include <sys/tty.h>
41df8bae1dSRodney W. Grimes #include <sys/kernel.h>
4287b6de2bSPoul-Henning Kamp #include <sys/sysctl.h>
43df8bae1dSRodney W. Grimes
44bc093719SEd Schouten struct speedtab {
45bc093719SEd Schouten int sp_speed; /* Speed. */
46bc093719SEd Schouten int sp_code; /* Code. */
47bc093719SEd Schouten };
48bc093719SEd Schouten
494d77a549SAlfred Perlstein static int ttcompatgetflags(struct tty *tp);
504d77a549SAlfred Perlstein static void ttcompatsetflags(struct tty *tp, struct termios *t);
514d77a549SAlfred Perlstein static void ttcompatsetlflags(struct tty *tp, struct termios *t);
524d77a549SAlfred Perlstein static int ttcompatspeedtab(int speed, struct speedtab *table);
5326f9a767SRodney W. Grimes
5487b6de2bSPoul-Henning Kamp static int ttydebug = 0;
5587b6de2bSPoul-Henning Kamp SYSCTL_INT(_debug, OID_AUTO, ttydebug, CTLFLAG_RW, &ttydebug, 0, "");
56df8bae1dSRodney W. Grimes
57df8bae1dSRodney W. Grimes static struct speedtab compatspeeds[] = {
585b96a5b9SBruce Evans #define MAX_SPEED 17
595b96a5b9SBruce Evans { 115200, 17 },
605b96a5b9SBruce Evans { 57600, 16 },
61df8bae1dSRodney W. Grimes { 38400, 15 },
62df8bae1dSRodney W. Grimes { 19200, 14 },
63df8bae1dSRodney W. Grimes { 9600, 13 },
64df8bae1dSRodney W. Grimes { 4800, 12 },
65df8bae1dSRodney W. Grimes { 2400, 11 },
66df8bae1dSRodney W. Grimes { 1800, 10 },
67df8bae1dSRodney W. Grimes { 1200, 9 },
68df8bae1dSRodney W. Grimes { 600, 8 },
69df8bae1dSRodney W. Grimes { 300, 7 },
70df8bae1dSRodney W. Grimes { 200, 6 },
71df8bae1dSRodney W. Grimes { 150, 5 },
72df8bae1dSRodney W. Grimes { 134, 4 },
73df8bae1dSRodney W. Grimes { 110, 3 },
74df8bae1dSRodney W. Grimes { 75, 2 },
75df8bae1dSRodney W. Grimes { 50, 1 },
76df8bae1dSRodney W. Grimes { 0, 0 },
77df8bae1dSRodney W. Grimes { -1, -1 },
78df8bae1dSRodney W. Grimes };
79af2a00bbSAndrey A. Chernov static int compatspcodes[] = {
80af2a00bbSAndrey A. Chernov 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
813b9a76f0SBruce Evans 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
82af2a00bbSAndrey A. Chernov };
83df8bae1dSRodney W. Grimes
843b9a76f0SBruce Evans static int
ttcompatspeedtab(int speed,struct speedtab * table)8555dbc267SPoul-Henning Kamp ttcompatspeedtab(int speed, struct speedtab *table)
864e5f7358SAndrey A. Chernov {
874e5f7358SAndrey A. Chernov if (speed == 0)
884e5f7358SAndrey A. Chernov return (0); /* hangup */
894e5f7358SAndrey A. Chernov for ( ; table->sp_speed > 0; table++)
904e5f7358SAndrey A. Chernov if (table->sp_speed <= speed) /* nearest one, rounded down */
914e5f7358SAndrey A. Chernov return (table->sp_code);
924e5f7358SAndrey A. Chernov return (1); /* 50, min and not hangup */
934e5f7358SAndrey A. Chernov }
944e5f7358SAndrey A. Chernov
9551514bc4SPoul-Henning Kamp static int
ttsetcompat(struct tty * tp,u_long * com,caddr_t data,struct termios * term)9655dbc267SPoul-Henning Kamp ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term)
970a247e7dSAndrey A. Chernov {
980a247e7dSAndrey A. Chernov switch (*com) {
990a247e7dSAndrey A. Chernov case TIOCSETP:
1000a247e7dSAndrey A. Chernov case TIOCSETN: {
10155dbc267SPoul-Henning Kamp struct sgttyb *sg = (struct sgttyb *)data;
1020a247e7dSAndrey A. Chernov int speed;
1030a247e7dSAndrey A. Chernov
1040a247e7dSAndrey A. Chernov if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0)
1050a247e7dSAndrey A. Chernov return(EINVAL);
106bc093719SEd Schouten else if (speed != ttcompatspeedtab(tp->t_termios.c_ispeed,
107bc093719SEd Schouten compatspeeds))
108af2a00bbSAndrey A. Chernov term->c_ispeed = compatspcodes[speed];
109e581051dSAndrey A. Chernov else
110bc093719SEd Schouten term->c_ispeed = tp->t_termios.c_ispeed;
1110a247e7dSAndrey A. Chernov if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0)
1120a247e7dSAndrey A. Chernov return(EINVAL);
113bc093719SEd Schouten else if (speed != ttcompatspeedtab(tp->t_termios.c_ospeed,
114bc093719SEd Schouten compatspeeds))
115af2a00bbSAndrey A. Chernov term->c_ospeed = compatspcodes[speed];
116e581051dSAndrey A. Chernov else
117bc093719SEd Schouten term->c_ospeed = tp->t_termios.c_ospeed;
1180a247e7dSAndrey A. Chernov term->c_cc[VERASE] = sg->sg_erase;
1190a247e7dSAndrey A. Chernov term->c_cc[VKILL] = sg->sg_kill;
1202bda9238SEd Schouten tp->t_compatflags = (tp->t_compatflags&0xffff0000) |
1212bda9238SEd Schouten (sg->sg_flags&0xffff);
1220a247e7dSAndrey A. Chernov ttcompatsetflags(tp, term);
1230a247e7dSAndrey A. Chernov *com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA;
1240a247e7dSAndrey A. Chernov break;
1250a247e7dSAndrey A. Chernov }
1260a247e7dSAndrey A. Chernov case TIOCSETC: {
1270a247e7dSAndrey A. Chernov struct tchars *tc = (struct tchars *)data;
12855dbc267SPoul-Henning Kamp cc_t *cc;
1290a247e7dSAndrey A. Chernov
1300a247e7dSAndrey A. Chernov cc = term->c_cc;
1310a247e7dSAndrey A. Chernov cc[VINTR] = tc->t_intrc;
1320a247e7dSAndrey A. Chernov cc[VQUIT] = tc->t_quitc;
1330a247e7dSAndrey A. Chernov cc[VSTART] = tc->t_startc;
1340a247e7dSAndrey A. Chernov cc[VSTOP] = tc->t_stopc;
1350a247e7dSAndrey A. Chernov cc[VEOF] = tc->t_eofc;
1360a247e7dSAndrey A. Chernov cc[VEOL] = tc->t_brkc;
137a77c37b6SOlivier Houchard if (tc->t_brkc == (char)_POSIX_VDISABLE)
1380a247e7dSAndrey A. Chernov cc[VEOL2] = _POSIX_VDISABLE;
1390a247e7dSAndrey A. Chernov *com = TIOCSETA;
1400a247e7dSAndrey A. Chernov break;
1410a247e7dSAndrey A. Chernov }
1420a247e7dSAndrey A. Chernov case TIOCSLTC: {
1430a247e7dSAndrey A. Chernov struct ltchars *ltc = (struct ltchars *)data;
14455dbc267SPoul-Henning Kamp cc_t *cc;
1450a247e7dSAndrey A. Chernov
1460a247e7dSAndrey A. Chernov cc = term->c_cc;
1470a247e7dSAndrey A. Chernov cc[VSUSP] = ltc->t_suspc;
1480a247e7dSAndrey A. Chernov cc[VDSUSP] = ltc->t_dsuspc;
1490a247e7dSAndrey A. Chernov cc[VREPRINT] = ltc->t_rprntc;
1500a247e7dSAndrey A. Chernov cc[VDISCARD] = ltc->t_flushc;
1510a247e7dSAndrey A. Chernov cc[VWERASE] = ltc->t_werasc;
1520a247e7dSAndrey A. Chernov cc[VLNEXT] = ltc->t_lnextc;
1530a247e7dSAndrey A. Chernov *com = TIOCSETA;
1540a247e7dSAndrey A. Chernov break;
1550a247e7dSAndrey A. Chernov }
1560a247e7dSAndrey A. Chernov case TIOCLBIS:
1570a247e7dSAndrey A. Chernov case TIOCLBIC:
1580a247e7dSAndrey A. Chernov case TIOCLSET:
1590a247e7dSAndrey A. Chernov if (*com == TIOCLSET)
1602bda9238SEd Schouten tp->t_compatflags = (tp->t_compatflags&0xffff) |
1612bda9238SEd Schouten *(int *)data<<16;
1620a247e7dSAndrey A. Chernov else {
1632bda9238SEd Schouten tp->t_compatflags = (ttcompatgetflags(tp)&0xffff0000) |
1642bda9238SEd Schouten (tp->t_compatflags&0xffff);
1650a247e7dSAndrey A. Chernov if (*com == TIOCLBIS)
1662bda9238SEd Schouten tp->t_compatflags |= *(int *)data<<16;
1670a247e7dSAndrey A. Chernov else
1682bda9238SEd Schouten tp->t_compatflags &= ~(*(int *)data<<16);
1690a247e7dSAndrey A. Chernov }
1700a247e7dSAndrey A. Chernov ttcompatsetlflags(tp, term);
1710a247e7dSAndrey A. Chernov *com = TIOCSETA;
1720a247e7dSAndrey A. Chernov break;
1730a247e7dSAndrey A. Chernov }
1740a247e7dSAndrey A. Chernov return 0;
1750a247e7dSAndrey A. Chernov }
1760a247e7dSAndrey A. Chernov
177df8bae1dSRodney W. Grimes /*ARGSUSED*/
17826f9a767SRodney W. Grimes int
tty_ioctl_compat(struct tty * tp,u_long com,caddr_t data,int fflag,struct thread * td)179328d9d2cSEd Schouten tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, int fflag,
180328d9d2cSEd Schouten struct thread *td)
181df8bae1dSRodney W. Grimes {
182df8bae1dSRodney W. Grimes switch (com) {
1830a247e7dSAndrey A. Chernov case TIOCSETP:
1840a247e7dSAndrey A. Chernov case TIOCSETN:
1850a247e7dSAndrey A. Chernov case TIOCSETC:
1860a247e7dSAndrey A. Chernov case TIOCSLTC:
1870a247e7dSAndrey A. Chernov case TIOCLBIS:
1880a247e7dSAndrey A. Chernov case TIOCLBIC:
1890a247e7dSAndrey A. Chernov case TIOCLSET: {
1900a247e7dSAndrey A. Chernov struct termios term;
1910a247e7dSAndrey A. Chernov int error;
1920a247e7dSAndrey A. Chernov
1930a247e7dSAndrey A. Chernov term = tp->t_termios;
1940a247e7dSAndrey A. Chernov if ((error = ttsetcompat(tp, &com, data, &term)) != 0)
1950a247e7dSAndrey A. Chernov return error;
196328d9d2cSEd Schouten return tty_ioctl(tp, com, &term, fflag, td);
1970a247e7dSAndrey A. Chernov }
198df8bae1dSRodney W. Grimes case TIOCGETP: {
19955dbc267SPoul-Henning Kamp struct sgttyb *sg = (struct sgttyb *)data;
200bc093719SEd Schouten cc_t *cc = tp->t_termios.c_cc;
201df8bae1dSRodney W. Grimes
202bc093719SEd Schouten sg->sg_ospeed = ttcompatspeedtab(tp->t_termios.c_ospeed,
203bc093719SEd Schouten compatspeeds);
204bc093719SEd Schouten if (tp->t_termios.c_ispeed == 0)
205df8bae1dSRodney W. Grimes sg->sg_ispeed = sg->sg_ospeed;
2064e5f7358SAndrey A. Chernov else
207bc093719SEd Schouten sg->sg_ispeed = ttcompatspeedtab(tp->t_termios.c_ispeed,
208bc093719SEd Schouten compatspeeds);
209df8bae1dSRodney W. Grimes sg->sg_erase = cc[VERASE];
210df8bae1dSRodney W. Grimes sg->sg_kill = cc[VKILL];
2112bda9238SEd Schouten sg->sg_flags = tp->t_compatflags = ttcompatgetflags(tp);
212df8bae1dSRodney W. Grimes break;
213df8bae1dSRodney W. Grimes }
214df8bae1dSRodney W. Grimes case TIOCGETC: {
215df8bae1dSRodney W. Grimes struct tchars *tc = (struct tchars *)data;
216bc093719SEd Schouten cc_t *cc = tp->t_termios.c_cc;
217df8bae1dSRodney W. Grimes
218df8bae1dSRodney W. Grimes tc->t_intrc = cc[VINTR];
219df8bae1dSRodney W. Grimes tc->t_quitc = cc[VQUIT];
220df8bae1dSRodney W. Grimes tc->t_startc = cc[VSTART];
221df8bae1dSRodney W. Grimes tc->t_stopc = cc[VSTOP];
222df8bae1dSRodney W. Grimes tc->t_eofc = cc[VEOF];
223df8bae1dSRodney W. Grimes tc->t_brkc = cc[VEOL];
224df8bae1dSRodney W. Grimes break;
225df8bae1dSRodney W. Grimes }
226df8bae1dSRodney W. Grimes case TIOCGLTC: {
227df8bae1dSRodney W. Grimes struct ltchars *ltc = (struct ltchars *)data;
228bc093719SEd Schouten cc_t *cc = tp->t_termios.c_cc;
229df8bae1dSRodney W. Grimes
230df8bae1dSRodney W. Grimes ltc->t_suspc = cc[VSUSP];
231df8bae1dSRodney W. Grimes ltc->t_dsuspc = cc[VDSUSP];
232df8bae1dSRodney W. Grimes ltc->t_rprntc = cc[VREPRINT];
233df8bae1dSRodney W. Grimes ltc->t_flushc = cc[VDISCARD];
234df8bae1dSRodney W. Grimes ltc->t_werasc = cc[VWERASE];
235df8bae1dSRodney W. Grimes ltc->t_lnextc = cc[VLNEXT];
236df8bae1dSRodney W. Grimes break;
237df8bae1dSRodney W. Grimes }
238df8bae1dSRodney W. Grimes case TIOCLGET:
2392bda9238SEd Schouten tp->t_compatflags =
240dec3cc97SAndrey A. Chernov (ttcompatgetflags(tp) & 0xffff0000UL)
2412bda9238SEd Schouten | (tp->t_compatflags & 0xffff);
2422bda9238SEd Schouten *(int *)data = tp->t_compatflags>>16;
243df8bae1dSRodney W. Grimes if (ttydebug)
244df8bae1dSRodney W. Grimes printf("CLGET: returning %x\n", *(int *)data);
245df8bae1dSRodney W. Grimes break;
246df8bae1dSRodney W. Grimes
247df8bae1dSRodney W. Grimes case OTIOCGETD:
248bc093719SEd Schouten *(int *)data = 2;
249df8bae1dSRodney W. Grimes break;
250df8bae1dSRodney W. Grimes
251df8bae1dSRodney W. Grimes case OTIOCSETD: {
252df8bae1dSRodney W. Grimes int ldisczero = 0;
253df8bae1dSRodney W. Grimes
254bc093719SEd Schouten return (tty_ioctl(tp, TIOCSETD,
255328d9d2cSEd Schouten *(int *)data == 2 ? (caddr_t)&ldisczero : data,
256328d9d2cSEd Schouten fflag, td));
257df8bae1dSRodney W. Grimes }
258df8bae1dSRodney W. Grimes
259*467e6276SBrooks Davis case OTIOCCONS: {
260*467e6276SBrooks Davis int one = 1;
261*467e6276SBrooks Davis
262*467e6276SBrooks Davis return (tty_ioctl(tp, TIOCCONS, (caddr_t)&one, fflag, td));
263*467e6276SBrooks Davis }
264df8bae1dSRodney W. Grimes
265df8bae1dSRodney W. Grimes default:
266239b7b69SBruce Evans return (ENOIOCTL);
267df8bae1dSRodney W. Grimes }
268df8bae1dSRodney W. Grimes return (0);
269df8bae1dSRodney W. Grimes }
270df8bae1dSRodney W. Grimes
271efb76ea6SAndrey A. Chernov static int
ttcompatgetflags(struct tty * tp)27255dbc267SPoul-Henning Kamp ttcompatgetflags(struct tty *tp)
273df8bae1dSRodney W. Grimes {
274bc093719SEd Schouten tcflag_t iflag = tp->t_termios.c_iflag;
275bc093719SEd Schouten tcflag_t lflag = tp->t_termios.c_lflag;
276bc093719SEd Schouten tcflag_t oflag = tp->t_termios.c_oflag;
277bc093719SEd Schouten tcflag_t cflag = tp->t_termios.c_cflag;
27855dbc267SPoul-Henning Kamp int flags = 0;
279df8bae1dSRodney W. Grimes
280df8bae1dSRodney W. Grimes if (iflag&IXOFF)
281df8bae1dSRodney W. Grimes flags |= TANDEM;
282df8bae1dSRodney W. Grimes if (iflag&ICRNL || oflag&ONLCR)
283df8bae1dSRodney W. Grimes flags |= CRMOD;
284dec3cc97SAndrey A. Chernov if ((cflag&CSIZE) == CS8) {
285dec3cc97SAndrey A. Chernov flags |= PASS8;
286dec3cc97SAndrey A. Chernov if (iflag&ISTRIP)
287dec3cc97SAndrey A. Chernov flags |= ANYP;
288dec3cc97SAndrey A. Chernov }
289dec3cc97SAndrey A. Chernov else if (cflag&PARENB) {
290df8bae1dSRodney W. Grimes if (iflag&INPCK) {
291df8bae1dSRodney W. Grimes if (cflag&PARODD)
292df8bae1dSRodney W. Grimes flags |= ODDP;
293df8bae1dSRodney W. Grimes else
294df8bae1dSRodney W. Grimes flags |= EVENP;
295df8bae1dSRodney W. Grimes } else
296df8bae1dSRodney W. Grimes flags |= EVENP | ODDP;
297df8bae1dSRodney W. Grimes }
298df8bae1dSRodney W. Grimes
299df8bae1dSRodney W. Grimes if ((lflag&ICANON) == 0) {
300df8bae1dSRodney W. Grimes /* fudge */
301dec3cc97SAndrey A. Chernov if (iflag&(INPCK|ISTRIP|IXON) || lflag&(IEXTEN|ISIG)
302694ad0a9SSteve Price || (cflag&(CSIZE|PARENB)) != CS8)
303df8bae1dSRodney W. Grimes flags |= CBREAK;
304df8bae1dSRodney W. Grimes else
305df8bae1dSRodney W. Grimes flags |= RAW;
306df8bae1dSRodney W. Grimes }
307694ad0a9SSteve Price if (!(flags&RAW) && !(oflag&OPOST) && (cflag&(CSIZE|PARENB)) == CS8)
308dec3cc97SAndrey A. Chernov flags |= LITOUT;
309df8bae1dSRodney W. Grimes if (cflag&MDMBUF)
310df8bae1dSRodney W. Grimes flags |= MDMBUF;
311df8bae1dSRodney W. Grimes if ((cflag&HUPCL) == 0)
312df8bae1dSRodney W. Grimes flags |= NOHANG;
313bc093719SEd Schouten if (oflag&TAB3)
314df8bae1dSRodney W. Grimes flags |= XTABS;
315df8bae1dSRodney W. Grimes if (lflag&ECHOE)
316df8bae1dSRodney W. Grimes flags |= CRTERA|CRTBS;
317df8bae1dSRodney W. Grimes if (lflag&ECHOKE)
318df8bae1dSRodney W. Grimes flags |= CRTKIL|CRTBS;
319df8bae1dSRodney W. Grimes if (lflag&ECHOPRT)
320df8bae1dSRodney W. Grimes flags |= PRTERA;
321df8bae1dSRodney W. Grimes if (lflag&ECHOCTL)
322df8bae1dSRodney W. Grimes flags |= CTLECH;
323df8bae1dSRodney W. Grimes if ((iflag&IXANY) == 0)
324df8bae1dSRodney W. Grimes flags |= DECCTQ;
325df8bae1dSRodney W. Grimes flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH);
326df8bae1dSRodney W. Grimes if (ttydebug)
327df8bae1dSRodney W. Grimes printf("getflags: %x\n", flags);
328df8bae1dSRodney W. Grimes return (flags);
329df8bae1dSRodney W. Grimes }
330df8bae1dSRodney W. Grimes
331efb76ea6SAndrey A. Chernov static void
ttcompatsetflags(struct tty * tp,struct termios * t)33255dbc267SPoul-Henning Kamp ttcompatsetflags(struct tty *tp, struct termios *t)
333df8bae1dSRodney W. Grimes {
3342bda9238SEd Schouten int flags = tp->t_compatflags;
33555dbc267SPoul-Henning Kamp tcflag_t iflag = t->c_iflag;
33655dbc267SPoul-Henning Kamp tcflag_t oflag = t->c_oflag;
33755dbc267SPoul-Henning Kamp tcflag_t lflag = t->c_lflag;
33855dbc267SPoul-Henning Kamp tcflag_t cflag = t->c_cflag;
339df8bae1dSRodney W. Grimes
340df8bae1dSRodney W. Grimes if (flags & RAW) {
341f1e302d4SAndrey A. Chernov iflag = IGNBRK;
342df8bae1dSRodney W. Grimes lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
343df8bae1dSRodney W. Grimes } else {
344f1e302d4SAndrey A. Chernov iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR);
345df8bae1dSRodney W. Grimes iflag |= BRKINT|IXON|IMAXBEL;
346df8bae1dSRodney W. Grimes lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */
347df8bae1dSRodney W. Grimes if (flags & XTABS)
348bc093719SEd Schouten oflag |= TAB3;
349df8bae1dSRodney W. Grimes else
350bc093719SEd Schouten oflag &= ~TAB3;
351df8bae1dSRodney W. Grimes if (flags & CBREAK)
352df8bae1dSRodney W. Grimes lflag &= ~ICANON;
353df8bae1dSRodney W. Grimes else
354df8bae1dSRodney W. Grimes lflag |= ICANON;
355df8bae1dSRodney W. Grimes if (flags&CRMOD) {
356df8bae1dSRodney W. Grimes iflag |= ICRNL;
357df8bae1dSRodney W. Grimes oflag |= ONLCR;
358df8bae1dSRodney W. Grimes } else {
359df8bae1dSRodney W. Grimes iflag &= ~ICRNL;
360df8bae1dSRodney W. Grimes oflag &= ~ONLCR;
361df8bae1dSRodney W. Grimes }
362df8bae1dSRodney W. Grimes }
363df8bae1dSRodney W. Grimes if (flags&ECHO)
364df8bae1dSRodney W. Grimes lflag |= ECHO;
365df8bae1dSRodney W. Grimes else
366df8bae1dSRodney W. Grimes lflag &= ~ECHO;
367df8bae1dSRodney W. Grimes
368df8bae1dSRodney W. Grimes cflag &= ~(CSIZE|PARENB);
369dec3cc97SAndrey A. Chernov if (flags&(RAW|LITOUT|PASS8)) {
370df8bae1dSRodney W. Grimes cflag |= CS8;
371dec3cc97SAndrey A. Chernov if (!(flags&(RAW|PASS8))
372dec3cc97SAndrey A. Chernov || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP))
373df8bae1dSRodney W. Grimes iflag |= ISTRIP;
374df8bae1dSRodney W. Grimes else
375df8bae1dSRodney W. Grimes iflag &= ~ISTRIP;
376dec3cc97SAndrey A. Chernov if (flags&(RAW|LITOUT))
377dec3cc97SAndrey A. Chernov oflag &= ~OPOST;
378dec3cc97SAndrey A. Chernov else
379dec3cc97SAndrey A. Chernov oflag |= OPOST;
380df8bae1dSRodney W. Grimes } else {
381df8bae1dSRodney W. Grimes cflag |= CS7|PARENB;
382df8bae1dSRodney W. Grimes iflag |= ISTRIP;
383dec3cc97SAndrey A. Chernov oflag |= OPOST;
384df8bae1dSRodney W. Grimes }
3853b9a76f0SBruce Evans /* XXX don't set INPCK if RAW or PASS8? */
386df8bae1dSRodney W. Grimes if ((flags&(EVENP|ODDP)) == EVENP) {
387df8bae1dSRodney W. Grimes iflag |= INPCK;
388df8bae1dSRodney W. Grimes cflag &= ~PARODD;
389df8bae1dSRodney W. Grimes } else if ((flags&(EVENP|ODDP)) == ODDP) {
390df8bae1dSRodney W. Grimes iflag |= INPCK;
391df8bae1dSRodney W. Grimes cflag |= PARODD;
392df8bae1dSRodney W. Grimes } else
393df8bae1dSRodney W. Grimes iflag &= ~INPCK;
394df8bae1dSRodney W. Grimes if (flags&TANDEM)
395df8bae1dSRodney W. Grimes iflag |= IXOFF;
396df8bae1dSRodney W. Grimes else
397df8bae1dSRodney W. Grimes iflag &= ~IXOFF;
39822055302SAndrey A. Chernov if ((flags&DECCTQ) == 0)
39922055302SAndrey A. Chernov iflag |= IXANY;
40022055302SAndrey A. Chernov else
40122055302SAndrey A. Chernov iflag &= ~IXANY;
402df8bae1dSRodney W. Grimes t->c_iflag = iflag;
403df8bae1dSRodney W. Grimes t->c_oflag = oflag;
404df8bae1dSRodney W. Grimes t->c_lflag = lflag;
405df8bae1dSRodney W. Grimes t->c_cflag = cflag;
406df8bae1dSRodney W. Grimes }
407df8bae1dSRodney W. Grimes
408efb76ea6SAndrey A. Chernov static void
ttcompatsetlflags(struct tty * tp,struct termios * t)40955dbc267SPoul-Henning Kamp ttcompatsetlflags(struct tty *tp, struct termios *t)
410df8bae1dSRodney W. Grimes {
4112bda9238SEd Schouten int flags = tp->t_compatflags;
41255dbc267SPoul-Henning Kamp tcflag_t iflag = t->c_iflag;
41355dbc267SPoul-Henning Kamp tcflag_t oflag = t->c_oflag;
41455dbc267SPoul-Henning Kamp tcflag_t lflag = t->c_lflag;
41555dbc267SPoul-Henning Kamp tcflag_t cflag = t->c_cflag;
416df8bae1dSRodney W. Grimes
417f1e302d4SAndrey A. Chernov iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR);
418df8bae1dSRodney W. Grimes if (flags&CRTERA)
419df8bae1dSRodney W. Grimes lflag |= ECHOE;
420df8bae1dSRodney W. Grimes else
421df8bae1dSRodney W. Grimes lflag &= ~ECHOE;
422df8bae1dSRodney W. Grimes if (flags&CRTKIL)
423df8bae1dSRodney W. Grimes lflag |= ECHOKE;
424df8bae1dSRodney W. Grimes else
425df8bae1dSRodney W. Grimes lflag &= ~ECHOKE;
426df8bae1dSRodney W. Grimes if (flags&PRTERA)
427df8bae1dSRodney W. Grimes lflag |= ECHOPRT;
428df8bae1dSRodney W. Grimes else
429df8bae1dSRodney W. Grimes lflag &= ~ECHOPRT;
430df8bae1dSRodney W. Grimes if (flags&CTLECH)
431df8bae1dSRodney W. Grimes lflag |= ECHOCTL;
432df8bae1dSRodney W. Grimes else
433df8bae1dSRodney W. Grimes lflag &= ~ECHOCTL;
43422055302SAndrey A. Chernov if (flags&TANDEM)
43522055302SAndrey A. Chernov iflag |= IXOFF;
43622055302SAndrey A. Chernov else
43722055302SAndrey A. Chernov iflag &= ~IXOFF;
438df8bae1dSRodney W. Grimes if ((flags&DECCTQ) == 0)
439df8bae1dSRodney W. Grimes iflag |= IXANY;
440df8bae1dSRodney W. Grimes else
441df8bae1dSRodney W. Grimes iflag &= ~IXANY;
442df8bae1dSRodney W. Grimes if (flags & MDMBUF)
443df8bae1dSRodney W. Grimes cflag |= MDMBUF;
444df8bae1dSRodney W. Grimes else
445df8bae1dSRodney W. Grimes cflag &= ~MDMBUF;
446df8bae1dSRodney W. Grimes if (flags&NOHANG)
447df8bae1dSRodney W. Grimes cflag &= ~HUPCL;
448df8bae1dSRodney W. Grimes else
449df8bae1dSRodney W. Grimes cflag |= HUPCL;
450df8bae1dSRodney W. Grimes lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH);
451df8bae1dSRodney W. Grimes lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH);
452dec3cc97SAndrey A. Chernov
453dec3cc97SAndrey A. Chernov /*
454dec3cc97SAndrey A. Chernov * The next if-else statement is copied from above so don't bother
455dec3cc97SAndrey A. Chernov * checking it separately. We could avoid fiddlling with the
456dec3cc97SAndrey A. Chernov * character size if the mode is already RAW or if neither the
457dec3cc97SAndrey A. Chernov * LITOUT bit or the PASS8 bit is being changed, but the delta of
458dec3cc97SAndrey A. Chernov * the change is not available here and skipping the RAW case would
459dec3cc97SAndrey A. Chernov * make the code different from above.
460dec3cc97SAndrey A. Chernov */
461df8bae1dSRodney W. Grimes cflag &= ~(CSIZE|PARENB);
462dec3cc97SAndrey A. Chernov if (flags&(RAW|LITOUT|PASS8)) {
463df8bae1dSRodney W. Grimes cflag |= CS8;
464dec3cc97SAndrey A. Chernov if (!(flags&(RAW|PASS8))
465dec3cc97SAndrey A. Chernov || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP))
466df8bae1dSRodney W. Grimes iflag |= ISTRIP;
467dec3cc97SAndrey A. Chernov else
468dec3cc97SAndrey A. Chernov iflag &= ~ISTRIP;
469dec3cc97SAndrey A. Chernov if (flags&(RAW|LITOUT))
470dec3cc97SAndrey A. Chernov oflag &= ~OPOST;
471dec3cc97SAndrey A. Chernov else
472dec3cc97SAndrey A. Chernov oflag |= OPOST;
473dec3cc97SAndrey A. Chernov } else {
474df8bae1dSRodney W. Grimes cflag |= CS7|PARENB;
475dec3cc97SAndrey A. Chernov iflag |= ISTRIP;
476df8bae1dSRodney W. Grimes oflag |= OPOST;
477df8bae1dSRodney W. Grimes }
478df8bae1dSRodney W. Grimes t->c_iflag = iflag;
479df8bae1dSRodney W. Grimes t->c_oflag = oflag;
480df8bae1dSRodney W. Grimes t->c_lflag = lflag;
481df8bae1dSRodney W. Grimes t->c_cflag = cflag;
482df8bae1dSRodney W. Grimes }
483