xref: /xnu-10063.121.3/bsd/kern/tty_compat.c (revision 2c2f96dc2b9a4408a43d3150ae9c105355ca3daa)
1*2c2f96dcSApple OSS Distributions /*
2*2c2f96dcSApple OSS Distributions  * Copyright (c) 2019 Apple Inc. All rights reserved.
3*2c2f96dcSApple OSS Distributions  *
4*2c2f96dcSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*2c2f96dcSApple OSS Distributions  *
6*2c2f96dcSApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*2c2f96dcSApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*2c2f96dcSApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*2c2f96dcSApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*2c2f96dcSApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*2c2f96dcSApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*2c2f96dcSApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*2c2f96dcSApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*2c2f96dcSApple OSS Distributions  *
15*2c2f96dcSApple OSS Distributions  * Please obtain a copy of the License at
16*2c2f96dcSApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*2c2f96dcSApple OSS Distributions  *
18*2c2f96dcSApple OSS Distributions  * The Original Code and all software distributed under the License are
19*2c2f96dcSApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*2c2f96dcSApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*2c2f96dcSApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*2c2f96dcSApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*2c2f96dcSApple OSS Distributions  * Please see the License for the specific language governing rights and
24*2c2f96dcSApple OSS Distributions  * limitations under the License.
25*2c2f96dcSApple OSS Distributions  *
26*2c2f96dcSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*2c2f96dcSApple OSS Distributions  */
28*2c2f96dcSApple OSS Distributions /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
29*2c2f96dcSApple OSS Distributions /*-
30*2c2f96dcSApple OSS Distributions  * Copyright (c) 1982, 1986, 1991, 1993
31*2c2f96dcSApple OSS Distributions  *      The Regents of the University of California.  All rights reserved.
32*2c2f96dcSApple OSS Distributions  *
33*2c2f96dcSApple OSS Distributions  * Redistribution and use in source and binary forms, with or without
34*2c2f96dcSApple OSS Distributions  * modification, are permitted provided that the following conditions
35*2c2f96dcSApple OSS Distributions  * are met:
36*2c2f96dcSApple OSS Distributions  * 1. Redistributions of source code must retain the above copyright
37*2c2f96dcSApple OSS Distributions  *    notice, this list of conditions and the following disclaimer.
38*2c2f96dcSApple OSS Distributions  * 2. Redistributions in binary form must reproduce the above copyright
39*2c2f96dcSApple OSS Distributions  *    notice, this list of conditions and the following disclaimer in the
40*2c2f96dcSApple OSS Distributions  *    documentation and/or other materials provided with the distribution.
41*2c2f96dcSApple OSS Distributions  * 3. All advertising materials mentioning features or use of this software
42*2c2f96dcSApple OSS Distributions  *    must display the following acknowledgement:
43*2c2f96dcSApple OSS Distributions  *      This product includes software developed by the University of
44*2c2f96dcSApple OSS Distributions  *      California, Berkeley and its contributors.
45*2c2f96dcSApple OSS Distributions  * 4. Neither the name of the University nor the names of its contributors
46*2c2f96dcSApple OSS Distributions  *    may be used to endorse or promote products derived from this software
47*2c2f96dcSApple OSS Distributions  *    without specific prior written permission.
48*2c2f96dcSApple OSS Distributions  *
49*2c2f96dcSApple OSS Distributions  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50*2c2f96dcSApple OSS Distributions  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51*2c2f96dcSApple OSS Distributions  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52*2c2f96dcSApple OSS Distributions  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53*2c2f96dcSApple OSS Distributions  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54*2c2f96dcSApple OSS Distributions  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55*2c2f96dcSApple OSS Distributions  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56*2c2f96dcSApple OSS Distributions  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57*2c2f96dcSApple OSS Distributions  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58*2c2f96dcSApple OSS Distributions  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59*2c2f96dcSApple OSS Distributions  * SUCH DAMAGE.
60*2c2f96dcSApple OSS Distributions  *
61*2c2f96dcSApple OSS Distributions  *      @(#)tty_compat.c        8.1 (Berkeley) 6/10/93
62*2c2f96dcSApple OSS Distributions  */
63*2c2f96dcSApple OSS Distributions 
64*2c2f96dcSApple OSS Distributions /*
65*2c2f96dcSApple OSS Distributions  * Compatibility routines for BSD 4.3 tty ioctl() commands
66*2c2f96dcSApple OSS Distributions  *
67*2c2f96dcSApple OSS Distributions  * The only function externalized from this file is ttcompat() and it is
68*2c2f96dcSApple OSS Distributions  * externalized as private extern to prevent exporting of the symbol when
69*2c2f96dcSApple OSS Distributions  * KEXTs link against the kernel.
70*2c2f96dcSApple OSS Distributions  *
71*2c2f96dcSApple OSS Distributions  * Locks:	All functions in this file assume that the tty_lock()
72*2c2f96dcSApple OSS Distributions  *		is held on the tty structure before these functions are
73*2c2f96dcSApple OSS Distributions  *		called.
74*2c2f96dcSApple OSS Distributions  */
75*2c2f96dcSApple OSS Distributions 
76*2c2f96dcSApple OSS Distributions #include <sys/param.h>
77*2c2f96dcSApple OSS Distributions #include <sys/systm.h>
78*2c2f96dcSApple OSS Distributions #include <sys/ioctl.h>
79*2c2f96dcSApple OSS Distributions #include <sys/proc_internal.h>
80*2c2f96dcSApple OSS Distributions #include <sys/tty.h>
81*2c2f96dcSApple OSS Distributions #include <sys/termios.h>
82*2c2f96dcSApple OSS Distributions #include <sys/file_internal.h>
83*2c2f96dcSApple OSS Distributions #include <sys/conf.h>
84*2c2f96dcSApple OSS Distributions #include <sys/kernel.h>
85*2c2f96dcSApple OSS Distributions #include <sys/sysctl.h>
86*2c2f96dcSApple OSS Distributions #include <sys/syslog.h>
87*2c2f96dcSApple OSS Distributions 
88*2c2f96dcSApple OSS Distributions static int ttcompatgetflags(struct tty *tp);
89*2c2f96dcSApple OSS Distributions static void ttcompatsetflags(struct tty *tp, struct termios *t);
90*2c2f96dcSApple OSS Distributions static void ttcompatsetlflags(struct tty *tp, struct termios *t);
91*2c2f96dcSApple OSS Distributions static unsigned int ttcompatspeedtab(speed_t speed, struct speedtab *table);
92*2c2f96dcSApple OSS Distributions 
93*2c2f96dcSApple OSS Distributions /*
94*2c2f96dcSApple OSS Distributions  * These two tables encode baud rate to speed code and speed code to
95*2c2f96dcSApple OSS Distributions  * baud rate information.  They are a mapping between the <sys/termios.h>
96*2c2f96dcSApple OSS Distributions  * baud rate constants and the <sys/ttydev.h> baud rate constants.  We
97*2c2f96dcSApple OSS Distributions  * cannot use those constants directly here because they occupy the same
98*2c2f96dcSApple OSS Distributions  * name space.
99*2c2f96dcSApple OSS Distributions  */
100*2c2f96dcSApple OSS Distributions static struct speedtab compatspeeds[] = {
101*2c2f96dcSApple OSS Distributions #define MAX_SPEED 17
102*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 115200, .sp_code = 17 },
103*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 57600, .sp_code = 16 },
104*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 38400, .sp_code = 15 },
105*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 19200, .sp_code = 14 },
106*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 9600, .sp_code = 13 },
107*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 4800, .sp_code = 12 },
108*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 2400, .sp_code = 11 },
109*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 1800, .sp_code = 10 },
110*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 1200, .sp_code = 9 },
111*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 600, .sp_code = 8 },
112*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 300, .sp_code = 7 },
113*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 200, .sp_code = 6 },
114*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 150, .sp_code = 5 },
115*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 134, .sp_code = 4 },
116*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 110, .sp_code = 3 },
117*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 75, .sp_code = 2 },
118*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 50, .sp_code = 1 },
119*2c2f96dcSApple OSS Distributions 	{ .sp_speed = 0, .sp_code = 0 },
120*2c2f96dcSApple OSS Distributions 	{ .sp_speed = -1, .sp_code = -1 },
121*2c2f96dcSApple OSS Distributions };
122*2c2f96dcSApple OSS Distributions static int compatspcodes[] = {
123*2c2f96dcSApple OSS Distributions 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
124*2c2f96dcSApple OSS Distributions 	1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
125*2c2f96dcSApple OSS Distributions };
126*2c2f96dcSApple OSS Distributions 
127*2c2f96dcSApple OSS Distributions /*
128*2c2f96dcSApple OSS Distributions  * ttcompatspeedtab
129*2c2f96dcSApple OSS Distributions  *
130*2c2f96dcSApple OSS Distributions  * Description:	Given a baud rate value as a speed_t, and a speed table,
131*2c2f96dcSApple OSS Distributions  *		convert the baud rate to a speed code integer, according to the
132*2c2f96dcSApple OSS Distributions  *		contents of the table.  This effectively changes termios.h
133*2c2f96dcSApple OSS Distributions  *		baud rate values into ttydev.h baud rate codes.
134*2c2f96dcSApple OSS Distributions  *
135*2c2f96dcSApple OSS Distributions  * Parameters:	speed_t speed  Baud rate
136*2c2f96dcSApple OSS Distributions  *		struct speedtab *table Baud rate table to speed code table
137*2c2f96dcSApple OSS Distributions  *
138*2c2f96dcSApple OSS Distributions  * Returns:	1              B50 speed code; returned if we can
139*2c2f96dcSApple OSS Distributions  *                         not find an answer in the table.
140*2c2f96dcSApple OSS Distributions  *          0              If a 0 was requested in order to
141*2c2f96dcSApple OSS Distributions  *                         trigger a hangup (250ms of line
142*2c2f96dcSApple OSS Distributions  *                         silence, per Bell 103C standard).
143*2c2f96dcSApple OSS Distributions  *          [2, MAX_SPEED] A speed code matching the requested
144*2c2f96dcSApple OSS Distributions  *                         baud rate (potentially rounded down,
145*2c2f96dcSApple OSS Distributions  *                         if there is no exact match).
146*2c2f96dcSApple OSS Distributions  *
147*2c2f96dcSApple OSS Distributions  * Notes:	This function is used for TIOCGETP, TIOCSETP, and TIOCSETN.
148*2c2f96dcSApple OSS Distributions  */
149*2c2f96dcSApple OSS Distributions static unsigned int
ttcompatspeedtab(speed_t speed,struct speedtab * table)150*2c2f96dcSApple OSS Distributions ttcompatspeedtab(speed_t speed, struct speedtab *table)
151*2c2f96dcSApple OSS Distributions {
152*2c2f96dcSApple OSS Distributions 	if (speed == 0) {
153*2c2f96dcSApple OSS Distributions 		return 0; /* hangup */
154*2c2f96dcSApple OSS Distributions 	}
155*2c2f96dcSApple OSS Distributions 	for (; table->sp_speed > 0; table++) {
156*2c2f96dcSApple OSS Distributions 		if (table->sp_speed <= speed) { /* nearest one, rounded down */
157*2c2f96dcSApple OSS Distributions 			return (unsigned int)table->sp_code;
158*2c2f96dcSApple OSS Distributions 		}
159*2c2f96dcSApple OSS Distributions 	}
160*2c2f96dcSApple OSS Distributions 	return 1; /* 50, min and not hangup */
161*2c2f96dcSApple OSS Distributions }
162*2c2f96dcSApple OSS Distributions 
163*2c2f96dcSApple OSS Distributions 
164*2c2f96dcSApple OSS Distributions /*
165*2c2f96dcSApple OSS Distributions  * ttsetcompat
166*2c2f96dcSApple OSS Distributions  *
167*2c2f96dcSApple OSS Distributions  * Description:	Convert backward compatability set command arguments as
168*2c2f96dcSApple OSS Distributions  *		follows:
169*2c2f96dcSApple OSS Distributions  *
170*2c2f96dcSApple OSS Distributions  *		TIOCSETP	->	TIOSETAF
171*2c2f96dcSApple OSS Distributions  *		TIOCSETN	->	TIOCSETA
172*2c2f96dcSApple OSS Distributions  *		TIOCSETC	->	TIOCSETA
173*2c2f96dcSApple OSS Distributions  *		TIOCSLTC	->	TIOCSETA
174*2c2f96dcSApple OSS Distributions  *		TIOCLBIS	->	TIOCSETA
175*2c2f96dcSApple OSS Distributions  *		TIOCLBIC	->	TIOCSETA
176*2c2f96dcSApple OSS Distributions  *		TIOCLSET	->	TIOCSETA
177*2c2f96dcSApple OSS Distributions  *
178*2c2f96dcSApple OSS Distributions  *	The converted command argument and potentially modified 'term'
179*2c2f96dcSApple OSS Distributions  *	argument are returned to ttcompat(), which will then call
180*2c2f96dcSApple OSS Distributions  *	ttioctl_locked(), if this function returns successfully.
181*2c2f96dcSApple OSS Distributions  *
182*2c2f96dcSApple OSS Distributions  * Parameters	struct tty *tp		The tty on which the operation is
183*2c2f96dcSApple OSS Distributions  *					being performed.
184*2c2f96dcSApple OSS Distributions  *		u_long *com		A pointer to the terminal input/output
185*2c2f96dcSApple OSS Distributions  *					command being requested; its contents
186*2c2f96dcSApple OSS Distributions  *					will be modified per the table above,
187*2c2f96dcSApple OSS Distributions  *					on a non-error return.
188*2c2f96dcSApple OSS Distributions  *		caddr_t data		Command specific parameter data; this
189*2c2f96dcSApple OSS Distributions  *					data is read but not modified.
190*2c2f96dcSApple OSS Distributions  *		struct termios *term	A local stack termios structure from
191*2c2f96dcSApple OSS Distributions  *					ttcompat(), whose contents are to be
192*2c2f96dcSApple OSS Distributions  *					modified based on *com and *data.
193*2c2f96dcSApple OSS Distributions  *
194*2c2f96dcSApple OSS Distributions  * Returns:	EINVAL			An input speed or output speed is
195*2c2f96dcSApple OSS Distributions  *					outside the allowable range for a
196*2c2f96dcSApple OSS Distributions  *					TIOCSETP or TIOCSETN command.
197*2c2f96dcSApple OSS Distributions  *		0			All other cases return 0.
198*2c2f96dcSApple OSS Distributions  *
199*2c2f96dcSApple OSS Distributions  * Notes:	This function may modify the contents of the tp->t_flags
200*2c2f96dcSApple OSS Distributions  *		field in a successful call to TIOCSETP, TIOCSETN, TIOCLBIS,
201*2c2f96dcSApple OSS Distributions  *		TIOCLBIC, or TIOCLSET.
202*2c2f96dcSApple OSS Distributions  *
203*2c2f96dcSApple OSS Distributions  *		All other tp fields will remain unmodifed, since the struct
204*2c2f96dcSApple OSS Distributions  *		termios is a local stack copy from ttcompat(), and not the
205*2c2f96dcSApple OSS Distributions  *		real thing.  A subsequent call to ttioctl_locked() in
206*2c2f96dcSApple OSS Distributions  *		ttcompat(), however, may result in subsequent changes.
207*2c2f96dcSApple OSS Distributions  *
208*2c2f96dcSApple OSS Distributions  * WARNING:	This compatibility code is not 64/32 clean; it will only
209*2c2f96dcSApple OSS Distributions  *		work for 32 bit processes on 32 bit kernels or 64 bit
210*2c2f96dcSApple OSS Distributions  *		processes on 64 bit kernels.  We are not addressing this
211*2c2f96dcSApple OSS Distributions  *		due to <rdar://6904053>.
212*2c2f96dcSApple OSS Distributions  */
213*2c2f96dcSApple OSS Distributions static int
ttsetcompat(struct tty * tp,u_long * com,caddr_t data,struct termios * term)214*2c2f96dcSApple OSS Distributions ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term)
215*2c2f96dcSApple OSS Distributions {
216*2c2f96dcSApple OSS Distributions 	switch (*com) {
217*2c2f96dcSApple OSS Distributions 	case TIOCSETP:
218*2c2f96dcSApple OSS Distributions 	/*
219*2c2f96dcSApple OSS Distributions 	 * Wait for all characters queued for output to drain, then
220*2c2f96dcSApple OSS Distributions 	 * Discard all characters queued for input, and then set
221*2c2f96dcSApple OSS Distributions 	 * the input and output speeds and device flags, per the
222*2c2f96dcSApple OSS Distributions 	 * contents of the struct sgttyb that 'data' points to.
223*2c2f96dcSApple OSS Distributions 	 */
224*2c2f96dcSApple OSS Distributions 	case TIOCSETN:
225*2c2f96dcSApple OSS Distributions 		/*
226*2c2f96dcSApple OSS Distributions 		 * Same as TIOCSETP, but the output is not drained, and any
227*2c2f96dcSApple OSS Distributions 		 * pending input is not discarded.
228*2c2f96dcSApple OSS Distributions 		 */
229*2c2f96dcSApple OSS Distributions 	{
230*2c2f96dcSApple OSS Distributions 		__IGNORE_WCASTALIGN(struct sgttyb *sg = (struct sgttyb *)data);
231*2c2f96dcSApple OSS Distributions 		if (sg->sg_ispeed < 0) {
232*2c2f96dcSApple OSS Distributions 			return EINVAL;
233*2c2f96dcSApple OSS Distributions 		}
234*2c2f96dcSApple OSS Distributions 		unsigned int ispeed = (unsigned int)sg->sg_ispeed;
235*2c2f96dcSApple OSS Distributions 		if (ispeed > MAX_SPEED) {
236*2c2f96dcSApple OSS Distributions 			return EINVAL;
237*2c2f96dcSApple OSS Distributions 		}
238*2c2f96dcSApple OSS Distributions 		if (ispeed != ttcompatspeedtab(tp->t_ispeed, compatspeeds)) {
239*2c2f96dcSApple OSS Distributions 			term->c_ispeed = compatspcodes[ispeed];
240*2c2f96dcSApple OSS Distributions 		} else {
241*2c2f96dcSApple OSS Distributions 			term->c_ispeed = tp->t_ispeed;
242*2c2f96dcSApple OSS Distributions 		}
243*2c2f96dcSApple OSS Distributions 
244*2c2f96dcSApple OSS Distributions 		/*
245*2c2f96dcSApple OSS Distributions 		 * Can't error out at the beginning due to potential for
246*2c2f96dcSApple OSS Distributions 		 * backwards-incompatibility.  For instance:
247*2c2f96dcSApple OSS Distributions 		 *
248*2c2f96dcSApple OSS Distributions 		 * struct sgttyb sg; // uninitialized
249*2c2f96dcSApple OSS Distributions 		 * sg.sg_ispeed = SOME_VALID_VALUE;
250*2c2f96dcSApple OSS Distributions 		 *
251*2c2f96dcSApple OSS Distributions 		 * Should still set the input speed.
252*2c2f96dcSApple OSS Distributions 		 */
253*2c2f96dcSApple OSS Distributions 		if (sg->sg_ospeed < 0) {
254*2c2f96dcSApple OSS Distributions 			return EINVAL;
255*2c2f96dcSApple OSS Distributions 		}
256*2c2f96dcSApple OSS Distributions 		unsigned int ospeed = (unsigned int)sg->sg_ospeed;
257*2c2f96dcSApple OSS Distributions 		if (ospeed > MAX_SPEED) {
258*2c2f96dcSApple OSS Distributions 			return EINVAL;
259*2c2f96dcSApple OSS Distributions 		}
260*2c2f96dcSApple OSS Distributions 		if (ospeed != ttcompatspeedtab(tp->t_ospeed, compatspeeds)) {
261*2c2f96dcSApple OSS Distributions 			term->c_ospeed = compatspcodes[ospeed];
262*2c2f96dcSApple OSS Distributions 		} else {
263*2c2f96dcSApple OSS Distributions 			term->c_ospeed = tp->t_ospeed;
264*2c2f96dcSApple OSS Distributions 		}
265*2c2f96dcSApple OSS Distributions 
266*2c2f96dcSApple OSS Distributions 		term->c_cc[VERASE] = sg->sg_erase;
267*2c2f96dcSApple OSS Distributions 		term->c_cc[VKILL] = sg->sg_kill;
268*2c2f96dcSApple OSS Distributions 		tp->t_flags = (tp->t_flags & 0xffff0000) | (sg->sg_flags & 0xffff);
269*2c2f96dcSApple OSS Distributions 		ttcompatsetflags(tp, term);
270*2c2f96dcSApple OSS Distributions 		*com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA;
271*2c2f96dcSApple OSS Distributions 		break;
272*2c2f96dcSApple OSS Distributions 	}
273*2c2f96dcSApple OSS Distributions 	case TIOCSETC:
274*2c2f96dcSApple OSS Distributions 		/*
275*2c2f96dcSApple OSS Distributions 		 * Set the terminal control characters per the contents of
276*2c2f96dcSApple OSS Distributions 		 * the struct tchars that 'data' points to.
277*2c2f96dcSApple OSS Distributions 		 */
278*2c2f96dcSApple OSS Distributions 	{
279*2c2f96dcSApple OSS Distributions 		__IGNORE_WCASTALIGN(struct tchars *tc = (struct tchars *)data);
280*2c2f96dcSApple OSS Distributions 		cc_t *cc;
281*2c2f96dcSApple OSS Distributions 
282*2c2f96dcSApple OSS Distributions 		cc = term->c_cc;
283*2c2f96dcSApple OSS Distributions 		cc[VINTR] = tc->t_intrc;
284*2c2f96dcSApple OSS Distributions 		cc[VQUIT] = tc->t_quitc;
285*2c2f96dcSApple OSS Distributions 		cc[VSTART] = tc->t_startc;
286*2c2f96dcSApple OSS Distributions 		cc[VSTOP] = tc->t_stopc;
287*2c2f96dcSApple OSS Distributions 		cc[VEOF] = tc->t_eofc;
288*2c2f96dcSApple OSS Distributions 		cc[VEOL] = tc->t_brkc;
289*2c2f96dcSApple OSS Distributions 		if (tc->t_brkc == -1) {
290*2c2f96dcSApple OSS Distributions 			cc[VEOL2] = _POSIX_VDISABLE;
291*2c2f96dcSApple OSS Distributions 		}
292*2c2f96dcSApple OSS Distributions 		*com = TIOCSETA;
293*2c2f96dcSApple OSS Distributions 		break;
294*2c2f96dcSApple OSS Distributions 	}
295*2c2f96dcSApple OSS Distributions 	case TIOCSLTC:
296*2c2f96dcSApple OSS Distributions 		/*
297*2c2f96dcSApple OSS Distributions 		 * Set the terminal control characters per the contents of
298*2c2f96dcSApple OSS Distributions 		 * the struct ltchars that 'data' points to.
299*2c2f96dcSApple OSS Distributions 		 */
300*2c2f96dcSApple OSS Distributions 	{
301*2c2f96dcSApple OSS Distributions 		__IGNORE_WCASTALIGN(struct ltchars *ltc = (struct ltchars *)data);
302*2c2f96dcSApple OSS Distributions 		cc_t *cc;
303*2c2f96dcSApple OSS Distributions 
304*2c2f96dcSApple OSS Distributions 		cc = term->c_cc;
305*2c2f96dcSApple OSS Distributions 		cc[VSUSP] = ltc->t_suspc;
306*2c2f96dcSApple OSS Distributions 		cc[VDSUSP] = ltc->t_dsuspc;
307*2c2f96dcSApple OSS Distributions 		cc[VREPRINT] = ltc->t_rprntc;
308*2c2f96dcSApple OSS Distributions 		cc[VDISCARD] = ltc->t_flushc;
309*2c2f96dcSApple OSS Distributions 		cc[VWERASE] = ltc->t_werasc;
310*2c2f96dcSApple OSS Distributions 		cc[VLNEXT] = ltc->t_lnextc;
311*2c2f96dcSApple OSS Distributions 		*com = TIOCSETA;
312*2c2f96dcSApple OSS Distributions 		break;
313*2c2f96dcSApple OSS Distributions 	}
314*2c2f96dcSApple OSS Distributions 	case TIOCLBIS:
315*2c2f96dcSApple OSS Distributions 	/*
316*2c2f96dcSApple OSS Distributions 	 * Set the bits in the terminal state local flags word
317*2c2f96dcSApple OSS Distributions 	 * (16 bits) for the terminal to the current bits OR
318*2c2f96dcSApple OSS Distributions 	 * those in the 16 bit value pointed to by 'data'.
319*2c2f96dcSApple OSS Distributions 	 */
320*2c2f96dcSApple OSS Distributions 	case TIOCLBIC:
321*2c2f96dcSApple OSS Distributions 	/*
322*2c2f96dcSApple OSS Distributions 	 * Clear the bits in the terminal state local flags word
323*2c2f96dcSApple OSS Distributions 	 * for the terminal to the current bits AND those bits NOT
324*2c2f96dcSApple OSS Distributions 	 * in the 16 bit value pointed to by 'data'.
325*2c2f96dcSApple OSS Distributions 	 */
326*2c2f96dcSApple OSS Distributions 	case TIOCLSET:
327*2c2f96dcSApple OSS Distributions 		/*
328*2c2f96dcSApple OSS Distributions 		 * Set the terminal state local flags word to exactly those
329*2c2f96dcSApple OSS Distributions 		 * bits that correspond to the 16 bit value pointed to by
330*2c2f96dcSApple OSS Distributions 		 * 'data'.
331*2c2f96dcSApple OSS Distributions 		 */
332*2c2f96dcSApple OSS Distributions 	{
333*2c2f96dcSApple OSS Distributions 		__IGNORE_WCASTALIGN(int set = *(int *)data);
334*2c2f96dcSApple OSS Distributions 		if (*com == TIOCLSET) {
335*2c2f96dcSApple OSS Distributions 			tp->t_flags = (tp->t_flags & 0xffff) | set << 16;
336*2c2f96dcSApple OSS Distributions 		} else {
337*2c2f96dcSApple OSS Distributions 			tp->t_flags =
338*2c2f96dcSApple OSS Distributions 			    (ttcompatgetflags(tp) & 0xffff0000) | (tp->t_flags & 0xffff);
339*2c2f96dcSApple OSS Distributions 			if (*com == TIOCLBIS) {
340*2c2f96dcSApple OSS Distributions 				tp->t_flags |= set << 16;
341*2c2f96dcSApple OSS Distributions 			} else {
342*2c2f96dcSApple OSS Distributions 				tp->t_flags &= ~(set << 16);
343*2c2f96dcSApple OSS Distributions 			}
344*2c2f96dcSApple OSS Distributions 		}
345*2c2f96dcSApple OSS Distributions 		ttcompatsetlflags(tp, term);
346*2c2f96dcSApple OSS Distributions 		*com = TIOCSETA;
347*2c2f96dcSApple OSS Distributions 		break;
348*2c2f96dcSApple OSS Distributions 	}
349*2c2f96dcSApple OSS Distributions 	}
350*2c2f96dcSApple OSS Distributions 	return 0;
351*2c2f96dcSApple OSS Distributions }
352*2c2f96dcSApple OSS Distributions 
353*2c2f96dcSApple OSS Distributions /*
354*2c2f96dcSApple OSS Distributions  * ttcompat
355*2c2f96dcSApple OSS Distributions  *
356*2c2f96dcSApple OSS Distributions  * Description:	For 'set' commands, convert the command and arguments as
357*2c2f96dcSApple OSS Distributions  *		necessary, and call ttioctl_locked(), returning the result
358*2c2f96dcSApple OSS Distributions  *		as our result; for 'get' commands, obtain the requested data
359*2c2f96dcSApple OSS Distributions  *		from the appropriate source, and return it in the expected
360*2c2f96dcSApple OSS Distributions  *		format.  If the command is not recognized, return EINVAL.
361*2c2f96dcSApple OSS Distributions  *
362*2c2f96dcSApple OSS Distributions  * Parameters	struct tty *tp		The tty on which the operation is
363*2c2f96dcSApple OSS Distributions  *					being performed.
364*2c2f96dcSApple OSS Distributions  *		u_long com		The terminal input/output command
365*2c2f96dcSApple OSS Distributions  *					being requested.
366*2c2f96dcSApple OSS Distributions  *		caddr_t	data		The pointer to the user data argument
367*2c2f96dcSApple OSS Distributions  *					provided with the command.
368*2c2f96dcSApple OSS Distributions  *		int flag		The file open flags (e.g. FREAD).
369*2c2f96dcSApple OSS Distributions  *		struct proc *p		The current process pointer for the
370*2c2f96dcSApple OSS Distributions  *					operation.
371*2c2f96dcSApple OSS Distributions  *
372*2c2f96dcSApple OSS Distributions  * Returns:	0			Most 'get' operations can't fail, and
373*2c2f96dcSApple OSS Distributions  *					therefore return this.
374*2c2f96dcSApple OSS Distributions  *		ENOTTY			TIOCGSID may return this when you
375*2c2f96dcSApple OSS Distributions  *					attempt to get the session ID for a
376*2c2f96dcSApple OSS Distributions  *					terminal with no associated session,
377*2c2f96dcSApple OSS Distributions  *					or for which there is a session, but
378*2c2f96dcSApple OSS Distributions  *					no session leader.
379*2c2f96dcSApple OSS Distributions  *		ENOTTY			If the command cannot be handled at
380*2c2f96dcSApple OSS Distributions  *					this layer, this will be returned.
381*2c2f96dcSApple OSS Distributions  *		*			Any value returned by ttioctl_locked(),
382*2c2f96dcSApple OSS Distributions  *					if a set command is requested.
383*2c2f96dcSApple OSS Distributions  *
384*2c2f96dcSApple OSS Distributions  * Notes:	The process pointer may be a proxy on whose behalf we are
385*2c2f96dcSApple OSS Distributions  *		operating, so it is not safe to simply use current_process()
386*2c2f96dcSApple OSS Distributions  *		instead.
387*2c2f96dcSApple OSS Distributions  */
388*2c2f96dcSApple OSS Distributions /*ARGSUSED*/
389*2c2f96dcSApple OSS Distributions __private_extern__ int
ttcompat(struct tty * tp,u_long com,caddr_t data,int flag,struct proc * p)390*2c2f96dcSApple OSS Distributions ttcompat(struct tty *tp, u_long com, caddr_t data, int flag, struct proc *p)
391*2c2f96dcSApple OSS Distributions {
392*2c2f96dcSApple OSS Distributions 	switch (com) {
393*2c2f96dcSApple OSS Distributions 	case TIOCSETP:
394*2c2f96dcSApple OSS Distributions 	case TIOCSETN:
395*2c2f96dcSApple OSS Distributions 	case TIOCSETC:
396*2c2f96dcSApple OSS Distributions 	case TIOCSLTC:
397*2c2f96dcSApple OSS Distributions 	case TIOCLBIS:
398*2c2f96dcSApple OSS Distributions 	case TIOCLBIC:
399*2c2f96dcSApple OSS Distributions 	case TIOCLSET:
400*2c2f96dcSApple OSS Distributions 		/*
401*2c2f96dcSApple OSS Distributions 		 * See ttsetcompat() for a full description of these command
402*2c2f96dcSApple OSS Distributions 		 * values and their meanings.
403*2c2f96dcSApple OSS Distributions 		 */
404*2c2f96dcSApple OSS Distributions 	{
405*2c2f96dcSApple OSS Distributions 		struct termios term;
406*2c2f96dcSApple OSS Distributions 		int error;
407*2c2f96dcSApple OSS Distributions 
408*2c2f96dcSApple OSS Distributions 		term = tp->t_termios;
409*2c2f96dcSApple OSS Distributions 		if ((error = ttsetcompat(tp, &com, data, &term)) != 0) {
410*2c2f96dcSApple OSS Distributions 			return error;
411*2c2f96dcSApple OSS Distributions 		}
412*2c2f96dcSApple OSS Distributions 		return ttioctl_locked(tp, com, (caddr_t) &term, flag, p);
413*2c2f96dcSApple OSS Distributions 	}
414*2c2f96dcSApple OSS Distributions 	case TIOCGETP:
415*2c2f96dcSApple OSS Distributions 		/*
416*2c2f96dcSApple OSS Distributions 		 * Get the current input and output speeds, and device
417*2c2f96dcSApple OSS Distributions 		 * flags, into the structure pointed to by 'data'.
418*2c2f96dcSApple OSS Distributions 		 */
419*2c2f96dcSApple OSS Distributions 	{
420*2c2f96dcSApple OSS Distributions 		__IGNORE_WCASTALIGN(struct sgttyb *sg = (struct sgttyb *)data);
421*2c2f96dcSApple OSS Distributions 		cc_t *cc = tp->t_cc;
422*2c2f96dcSApple OSS Distributions 
423*2c2f96dcSApple OSS Distributions 		static_assert(MAX_SPEED <= CHAR_MAX, "maximum speed fits in a char");
424*2c2f96dcSApple OSS Distributions 		sg->sg_ospeed = (char)ttcompatspeedtab(tp->t_ospeed, compatspeeds);
425*2c2f96dcSApple OSS Distributions 		if (tp->t_ispeed == 0) {
426*2c2f96dcSApple OSS Distributions 			sg->sg_ispeed = sg->sg_ospeed;
427*2c2f96dcSApple OSS Distributions 		} else {
428*2c2f96dcSApple OSS Distributions 			sg->sg_ispeed = (char)ttcompatspeedtab(tp->t_ispeed, compatspeeds);
429*2c2f96dcSApple OSS Distributions 		}
430*2c2f96dcSApple OSS Distributions 		sg->sg_erase = cc[VERASE];
431*2c2f96dcSApple OSS Distributions 		sg->sg_kill = cc[VKILL];
432*2c2f96dcSApple OSS Distributions 		tp->t_flags = ttcompatgetflags(tp);
433*2c2f96dcSApple OSS Distributions 		sg->sg_flags = (short)tp->t_flags;
434*2c2f96dcSApple OSS Distributions 		break;
435*2c2f96dcSApple OSS Distributions 	}
436*2c2f96dcSApple OSS Distributions 	case TIOCGETC:
437*2c2f96dcSApple OSS Distributions 		/*
438*2c2f96dcSApple OSS Distributions 		 * Get the terminal control characters into the struct
439*2c2f96dcSApple OSS Distributions 		 * tchars that 'data' points to.
440*2c2f96dcSApple OSS Distributions 		 */
441*2c2f96dcSApple OSS Distributions 	{
442*2c2f96dcSApple OSS Distributions 		struct tchars *tc = (struct tchars *)data;
443*2c2f96dcSApple OSS Distributions 		cc_t *cc = tp->t_cc;
444*2c2f96dcSApple OSS Distributions 
445*2c2f96dcSApple OSS Distributions 		tc->t_intrc = cc[VINTR];
446*2c2f96dcSApple OSS Distributions 		tc->t_quitc = cc[VQUIT];
447*2c2f96dcSApple OSS Distributions 		tc->t_startc = cc[VSTART];
448*2c2f96dcSApple OSS Distributions 		tc->t_stopc = cc[VSTOP];
449*2c2f96dcSApple OSS Distributions 		tc->t_eofc = cc[VEOF];
450*2c2f96dcSApple OSS Distributions 		tc->t_brkc = cc[VEOL];
451*2c2f96dcSApple OSS Distributions 		break;
452*2c2f96dcSApple OSS Distributions 	}
453*2c2f96dcSApple OSS Distributions 	case TIOCGLTC:
454*2c2f96dcSApple OSS Distributions 		/*
455*2c2f96dcSApple OSS Distributions 		 * Get the terminal control characters into the struct
456*2c2f96dcSApple OSS Distributions 		 * ltchars that 'data' points to.
457*2c2f96dcSApple OSS Distributions 		 */
458*2c2f96dcSApple OSS Distributions 	{
459*2c2f96dcSApple OSS Distributions 		struct ltchars *ltc = (struct ltchars *)data;
460*2c2f96dcSApple OSS Distributions 		cc_t *cc = tp->t_cc;
461*2c2f96dcSApple OSS Distributions 
462*2c2f96dcSApple OSS Distributions 		ltc->t_suspc = cc[VSUSP];
463*2c2f96dcSApple OSS Distributions 		ltc->t_dsuspc = cc[VDSUSP];
464*2c2f96dcSApple OSS Distributions 		ltc->t_rprntc = cc[VREPRINT];
465*2c2f96dcSApple OSS Distributions 		ltc->t_flushc = cc[VDISCARD];
466*2c2f96dcSApple OSS Distributions 		ltc->t_werasc = cc[VWERASE];
467*2c2f96dcSApple OSS Distributions 		ltc->t_lnextc = cc[VLNEXT];
468*2c2f96dcSApple OSS Distributions 		break;
469*2c2f96dcSApple OSS Distributions 	}
470*2c2f96dcSApple OSS Distributions 	case TIOCLGET:
471*2c2f96dcSApple OSS Distributions 		/*
472*2c2f96dcSApple OSS Distributions 		 * Get the terminal state local flags word into the 16 bit
473*2c2f96dcSApple OSS Distributions 		 * value pointed to by 'data'.
474*2c2f96dcSApple OSS Distributions 		 */
475*2c2f96dcSApple OSS Distributions 		tp->t_flags =
476*2c2f96dcSApple OSS Distributions 		    (ttcompatgetflags(tp) & 0xffff0000UL)
477*2c2f96dcSApple OSS Distributions 		    | (tp->t_flags & 0xffff);
478*2c2f96dcSApple OSS Distributions 		*(int *)data = tp->t_flags >> 16;
479*2c2f96dcSApple OSS Distributions 		break;
480*2c2f96dcSApple OSS Distributions 
481*2c2f96dcSApple OSS Distributions 	case OTIOCGETD:
482*2c2f96dcSApple OSS Distributions 		/*
483*2c2f96dcSApple OSS Distributions 		 * Get the current line discipline into the int pointed to
484*2c2f96dcSApple OSS Distributions 		 * by 'data'.
485*2c2f96dcSApple OSS Distributions 		 */
486*2c2f96dcSApple OSS Distributions 		*(int *)data = tp->t_line ? tp->t_line : 2;
487*2c2f96dcSApple OSS Distributions 		break;
488*2c2f96dcSApple OSS Distributions 
489*2c2f96dcSApple OSS Distributions 	case OTIOCSETD:
490*2c2f96dcSApple OSS Distributions 		/*
491*2c2f96dcSApple OSS Distributions 		 * Set the current line discipline based on the value of the
492*2c2f96dcSApple OSS Distributions 		 * int pointed to by 'data'.
493*2c2f96dcSApple OSS Distributions 		 */
494*2c2f96dcSApple OSS Distributions 	{
495*2c2f96dcSApple OSS Distributions 		int ldisczero = 0;
496*2c2f96dcSApple OSS Distributions 
497*2c2f96dcSApple OSS Distributions 		return ttioctl_locked(tp, TIOCSETD,
498*2c2f96dcSApple OSS Distributions 		           *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag, p);
499*2c2f96dcSApple OSS Distributions 	}
500*2c2f96dcSApple OSS Distributions 
501*2c2f96dcSApple OSS Distributions 	case OTIOCCONS:
502*2c2f96dcSApple OSS Distributions 		/*
503*2c2f96dcSApple OSS Distributions 		 * Become the console device.
504*2c2f96dcSApple OSS Distributions 		 */
505*2c2f96dcSApple OSS Distributions 		*(int *)data = 1;
506*2c2f96dcSApple OSS Distributions 		return ttioctl_locked(tp, TIOCCONS, data, flag, p);
507*2c2f96dcSApple OSS Distributions 
508*2c2f96dcSApple OSS Distributions 	case TIOCGSID:
509*2c2f96dcSApple OSS Distributions 		/*
510*2c2f96dcSApple OSS Distributions 		 * Get the current session ID (controlling process' PID).
511*2c2f96dcSApple OSS Distributions 		 */
512*2c2f96dcSApple OSS Distributions 		if (tp->t_session == NULL) {
513*2c2f96dcSApple OSS Distributions 			return ENOTTY;
514*2c2f96dcSApple OSS Distributions 		}
515*2c2f96dcSApple OSS Distributions 
516*2c2f96dcSApple OSS Distributions 		if (tp->t_session->s_leader == NULL) {
517*2c2f96dcSApple OSS Distributions 			return ENOTTY;
518*2c2f96dcSApple OSS Distributions 		}
519*2c2f96dcSApple OSS Distributions 
520*2c2f96dcSApple OSS Distributions 		*(int *) data =  proc_getpid(tp->t_session->s_leader);
521*2c2f96dcSApple OSS Distributions 		break;
522*2c2f96dcSApple OSS Distributions 
523*2c2f96dcSApple OSS Distributions 	default:
524*2c2f96dcSApple OSS Distributions 		/*
525*2c2f96dcSApple OSS Distributions 		 * This ioctl is not handled at this layer.
526*2c2f96dcSApple OSS Distributions 		 */
527*2c2f96dcSApple OSS Distributions 		return ENOTTY;
528*2c2f96dcSApple OSS Distributions 	}
529*2c2f96dcSApple OSS Distributions 
530*2c2f96dcSApple OSS Distributions 	/*
531*2c2f96dcSApple OSS Distributions 	 * Successful 'get' operation.
532*2c2f96dcSApple OSS Distributions 	 */
533*2c2f96dcSApple OSS Distributions 	return 0;
534*2c2f96dcSApple OSS Distributions }
535*2c2f96dcSApple OSS Distributions 
536*2c2f96dcSApple OSS Distributions /*
537*2c2f96dcSApple OSS Distributions  * ttcompatgetflags
538*2c2f96dcSApple OSS Distributions  *
539*2c2f96dcSApple OSS Distributions  * Description:	Get the terminal state local flags, device flags, and current
540*2c2f96dcSApple OSS Distributions  *		speed code for the device (all 32 bits are returned).
541*2c2f96dcSApple OSS Distributions  *
542*2c2f96dcSApple OSS Distributions  * Parameters	struct tty *tp		The tty on which the operation is
543*2c2f96dcSApple OSS Distributions  *					being performed.
544*2c2f96dcSApple OSS Distributions  *
545*2c2f96dcSApple OSS Distributions  * Returns:	*			Integer value corresponding to the
546*2c2f96dcSApple OSS Distributions  *					current terminal state local flags
547*2c2f96dcSApple OSS Distributions  *					word.
548*2c2f96dcSApple OSS Distributions  *
549*2c2f96dcSApple OSS Distributions  * Notes:	Caller is responsible for breaking these bits back out into
550*2c2f96dcSApple OSS Distributions  *		separate 16 bit filelds, if that's what was actually desired.
551*2c2f96dcSApple OSS Distributions  */
552*2c2f96dcSApple OSS Distributions static int
ttcompatgetflags(struct tty * tp)553*2c2f96dcSApple OSS Distributions ttcompatgetflags(struct tty *tp)
554*2c2f96dcSApple OSS Distributions {
555*2c2f96dcSApple OSS Distributions 	tcflag_t iflag  = tp->t_iflag;
556*2c2f96dcSApple OSS Distributions 	tcflag_t lflag  = tp->t_lflag;
557*2c2f96dcSApple OSS Distributions 	tcflag_t oflag  = tp->t_oflag;
558*2c2f96dcSApple OSS Distributions 	tcflag_t cflag  = tp->t_cflag;
559*2c2f96dcSApple OSS Distributions 	int flags = 0;
560*2c2f96dcSApple OSS Distributions 
561*2c2f96dcSApple OSS Distributions 	if (iflag & IXOFF) {
562*2c2f96dcSApple OSS Distributions 		flags |= TANDEM;
563*2c2f96dcSApple OSS Distributions 	}
564*2c2f96dcSApple OSS Distributions 	if (iflag & ICRNL || oflag & ONLCR) {
565*2c2f96dcSApple OSS Distributions 		flags |= CRMOD;
566*2c2f96dcSApple OSS Distributions 	}
567*2c2f96dcSApple OSS Distributions 	if ((cflag & CSIZE) == CS8) {
568*2c2f96dcSApple OSS Distributions 		flags |= PASS8;
569*2c2f96dcSApple OSS Distributions 		if (iflag & ISTRIP) {
570*2c2f96dcSApple OSS Distributions 			flags |= ANYP;
571*2c2f96dcSApple OSS Distributions 		}
572*2c2f96dcSApple OSS Distributions 	} else if (cflag & PARENB) {
573*2c2f96dcSApple OSS Distributions 		if (iflag & INPCK) {
574*2c2f96dcSApple OSS Distributions 			if (cflag & PARODD) {
575*2c2f96dcSApple OSS Distributions 				flags |= ODDP;
576*2c2f96dcSApple OSS Distributions 			} else {
577*2c2f96dcSApple OSS Distributions 				flags |= EVENP;
578*2c2f96dcSApple OSS Distributions 			}
579*2c2f96dcSApple OSS Distributions 		} else {
580*2c2f96dcSApple OSS Distributions 			flags |= EVENP | ODDP;
581*2c2f96dcSApple OSS Distributions 		}
582*2c2f96dcSApple OSS Distributions 	}
583*2c2f96dcSApple OSS Distributions 
584*2c2f96dcSApple OSS Distributions 	if ((lflag & ICANON) == 0) {
585*2c2f96dcSApple OSS Distributions 		/* fudge */
586*2c2f96dcSApple OSS Distributions 		if (iflag & (INPCK | ISTRIP | IXON) || lflag & (IEXTEN | ISIG)
587*2c2f96dcSApple OSS Distributions 		    || (cflag & (CSIZE | PARENB)) != CS8) {
588*2c2f96dcSApple OSS Distributions 			flags |= CBREAK;
589*2c2f96dcSApple OSS Distributions 		} else {
590*2c2f96dcSApple OSS Distributions 			flags |= RAW;
591*2c2f96dcSApple OSS Distributions 		}
592*2c2f96dcSApple OSS Distributions 	}
593*2c2f96dcSApple OSS Distributions 	if (!(flags & RAW) && !(oflag & OPOST) && (cflag & (CSIZE | PARENB)) == CS8) {
594*2c2f96dcSApple OSS Distributions 		flags |= LITOUT;
595*2c2f96dcSApple OSS Distributions 	}
596*2c2f96dcSApple OSS Distributions 	if (cflag & MDMBUF) {
597*2c2f96dcSApple OSS Distributions 		flags |= MDMBUF;
598*2c2f96dcSApple OSS Distributions 	}
599*2c2f96dcSApple OSS Distributions 	if ((cflag & HUPCL) == 0) {
600*2c2f96dcSApple OSS Distributions 		flags |= NOHANG;
601*2c2f96dcSApple OSS Distributions 	}
602*2c2f96dcSApple OSS Distributions 	if (oflag & OXTABS) {
603*2c2f96dcSApple OSS Distributions 		flags |= XTABS;
604*2c2f96dcSApple OSS Distributions 	}
605*2c2f96dcSApple OSS Distributions 	if (lflag & ECHOE) {
606*2c2f96dcSApple OSS Distributions 		flags |= CRTERA | CRTBS;
607*2c2f96dcSApple OSS Distributions 	}
608*2c2f96dcSApple OSS Distributions 	if (lflag & ECHOKE) {
609*2c2f96dcSApple OSS Distributions 		flags |= CRTKIL | CRTBS;
610*2c2f96dcSApple OSS Distributions 	}
611*2c2f96dcSApple OSS Distributions 	if (lflag & ECHOPRT) {
612*2c2f96dcSApple OSS Distributions 		flags |= PRTERA;
613*2c2f96dcSApple OSS Distributions 	}
614*2c2f96dcSApple OSS Distributions 	if (lflag & ECHOCTL) {
615*2c2f96dcSApple OSS Distributions 		flags |= CTLECH;
616*2c2f96dcSApple OSS Distributions 	}
617*2c2f96dcSApple OSS Distributions 	if ((iflag & IXANY) == 0) {
618*2c2f96dcSApple OSS Distributions 		flags |= DECCTQ;
619*2c2f96dcSApple OSS Distributions 	}
620*2c2f96dcSApple OSS Distributions 	flags |= lflag & (ECHO | TOSTOP | FLUSHO | PENDIN | NOFLSH);
621*2c2f96dcSApple OSS Distributions 	return flags;
622*2c2f96dcSApple OSS Distributions }
623*2c2f96dcSApple OSS Distributions 
624*2c2f96dcSApple OSS Distributions /*
625*2c2f96dcSApple OSS Distributions  * ttcompatsetflags
626*2c2f96dcSApple OSS Distributions  *
627*2c2f96dcSApple OSS Distributions  * Description:	Given a set of compatability flags, convert the compatability
628*2c2f96dcSApple OSS Distributions  *		flags in the terminal flags fields into canonical flags in the
629*2c2f96dcSApple OSS Distributions  *		provided termios struct.
630*2c2f96dcSApple OSS Distributions  *
631*2c2f96dcSApple OSS Distributions  * Parameters:	struct tty *tp		The tty on which the operation is
632*2c2f96dcSApple OSS Distributions  *					being performed.
633*2c2f96dcSApple OSS Distributions  *		struct termios *t	The termios structure into which to
634*2c2f96dcSApple OSS Distributions  *					return the converted flags.
635*2c2f96dcSApple OSS Distributions  *
636*2c2f96dcSApple OSS Distributions  * Returns:	void			(implicit: *t, modified)
637*2c2f96dcSApple OSS Distributions  */
638*2c2f96dcSApple OSS Distributions static void
ttcompatsetflags(struct tty * tp,struct termios * t)639*2c2f96dcSApple OSS Distributions ttcompatsetflags(struct tty *tp, struct termios *t)
640*2c2f96dcSApple OSS Distributions {
641*2c2f96dcSApple OSS Distributions 	int flags = tp->t_flags;
642*2c2f96dcSApple OSS Distributions 	tcflag_t iflag  = t->c_iflag;
643*2c2f96dcSApple OSS Distributions 	tcflag_t oflag  = t->c_oflag;
644*2c2f96dcSApple OSS Distributions 	tcflag_t lflag  = t->c_lflag;
645*2c2f96dcSApple OSS Distributions 	tcflag_t cflag  = t->c_cflag;
646*2c2f96dcSApple OSS Distributions 
647*2c2f96dcSApple OSS Distributions 	if (flags & RAW) {
648*2c2f96dcSApple OSS Distributions 		iflag = IGNBRK;
649*2c2f96dcSApple OSS Distributions 		lflag &= ~(ECHOCTL | ISIG | ICANON | IEXTEN);
650*2c2f96dcSApple OSS Distributions 	} else {
651*2c2f96dcSApple OSS Distributions 		iflag &= ~(PARMRK | IGNPAR | IGNCR | INLCR);
652*2c2f96dcSApple OSS Distributions 		iflag |= BRKINT | IXON | IMAXBEL;
653*2c2f96dcSApple OSS Distributions 		lflag |= ISIG | IEXTEN | ECHOCTL;   /* XXX was echoctl on ? */
654*2c2f96dcSApple OSS Distributions 		if (flags & XTABS) {
655*2c2f96dcSApple OSS Distributions 			oflag |= OXTABS;
656*2c2f96dcSApple OSS Distributions 		} else {
657*2c2f96dcSApple OSS Distributions 			oflag &= ~OXTABS;
658*2c2f96dcSApple OSS Distributions 		}
659*2c2f96dcSApple OSS Distributions 		if (flags & CBREAK) {
660*2c2f96dcSApple OSS Distributions 			lflag &= ~ICANON;
661*2c2f96dcSApple OSS Distributions 		} else {
662*2c2f96dcSApple OSS Distributions 			lflag |= ICANON;
663*2c2f96dcSApple OSS Distributions 		}
664*2c2f96dcSApple OSS Distributions 		if (flags & CRMOD) {
665*2c2f96dcSApple OSS Distributions 			iflag |= ICRNL;
666*2c2f96dcSApple OSS Distributions 			oflag |= ONLCR;
667*2c2f96dcSApple OSS Distributions 		} else {
668*2c2f96dcSApple OSS Distributions 			iflag &= ~ICRNL;
669*2c2f96dcSApple OSS Distributions 			oflag &= ~ONLCR;
670*2c2f96dcSApple OSS Distributions 		}
671*2c2f96dcSApple OSS Distributions 	}
672*2c2f96dcSApple OSS Distributions 	if (flags & ECHO) {
673*2c2f96dcSApple OSS Distributions 		lflag |= ECHO;
674*2c2f96dcSApple OSS Distributions 	} else {
675*2c2f96dcSApple OSS Distributions 		lflag &= ~ECHO;
676*2c2f96dcSApple OSS Distributions 	}
677*2c2f96dcSApple OSS Distributions 
678*2c2f96dcSApple OSS Distributions 	cflag &= ~(CSIZE | PARENB);
679*2c2f96dcSApple OSS Distributions 	if (flags & (RAW | LITOUT | PASS8)) {
680*2c2f96dcSApple OSS Distributions 		cflag |= CS8;
681*2c2f96dcSApple OSS Distributions 		if (!(flags & (RAW | PASS8))
682*2c2f96dcSApple OSS Distributions 		    || (flags & (RAW | PASS8 | ANYP)) == (PASS8 | ANYP)) {
683*2c2f96dcSApple OSS Distributions 			iflag |= ISTRIP;
684*2c2f96dcSApple OSS Distributions 		} else {
685*2c2f96dcSApple OSS Distributions 			iflag &= ~ISTRIP;
686*2c2f96dcSApple OSS Distributions 		}
687*2c2f96dcSApple OSS Distributions 		if (flags & (RAW | LITOUT)) {
688*2c2f96dcSApple OSS Distributions 			oflag &= ~OPOST;
689*2c2f96dcSApple OSS Distributions 		} else {
690*2c2f96dcSApple OSS Distributions 			oflag |= OPOST;
691*2c2f96dcSApple OSS Distributions 		}
692*2c2f96dcSApple OSS Distributions 	} else {
693*2c2f96dcSApple OSS Distributions 		cflag |= CS7 | PARENB;
694*2c2f96dcSApple OSS Distributions 		iflag |= ISTRIP;
695*2c2f96dcSApple OSS Distributions 		oflag |= OPOST;
696*2c2f96dcSApple OSS Distributions 	}
697*2c2f96dcSApple OSS Distributions 	/* XXX don't set INPCK if RAW or PASS8? */
698*2c2f96dcSApple OSS Distributions 	if ((flags & (EVENP | ODDP)) == EVENP) {
699*2c2f96dcSApple OSS Distributions 		iflag |= INPCK;
700*2c2f96dcSApple OSS Distributions 		cflag &= ~PARODD;
701*2c2f96dcSApple OSS Distributions 	} else if ((flags & (EVENP | ODDP)) == ODDP) {
702*2c2f96dcSApple OSS Distributions 		iflag |= INPCK;
703*2c2f96dcSApple OSS Distributions 		cflag |= PARODD;
704*2c2f96dcSApple OSS Distributions 	} else {
705*2c2f96dcSApple OSS Distributions 		iflag &= ~INPCK;
706*2c2f96dcSApple OSS Distributions 	}
707*2c2f96dcSApple OSS Distributions 	if (flags & TANDEM) {
708*2c2f96dcSApple OSS Distributions 		iflag |= IXOFF;
709*2c2f96dcSApple OSS Distributions 	} else {
710*2c2f96dcSApple OSS Distributions 		iflag &= ~IXOFF;
711*2c2f96dcSApple OSS Distributions 	}
712*2c2f96dcSApple OSS Distributions 	if ((flags & DECCTQ) == 0) {
713*2c2f96dcSApple OSS Distributions 		iflag |= IXANY;
714*2c2f96dcSApple OSS Distributions 	} else {
715*2c2f96dcSApple OSS Distributions 		iflag &= ~IXANY;
716*2c2f96dcSApple OSS Distributions 	}
717*2c2f96dcSApple OSS Distributions 	t->c_iflag = iflag;
718*2c2f96dcSApple OSS Distributions 	t->c_oflag = oflag;
719*2c2f96dcSApple OSS Distributions 	t->c_lflag = lflag;
720*2c2f96dcSApple OSS Distributions 	t->c_cflag = cflag;
721*2c2f96dcSApple OSS Distributions }
722*2c2f96dcSApple OSS Distributions 
723*2c2f96dcSApple OSS Distributions /*
724*2c2f96dcSApple OSS Distributions  * ttcompatsetlflags
725*2c2f96dcSApple OSS Distributions  *
726*2c2f96dcSApple OSS Distributions  * Description:	Given a set of compatability terminal state local flags,
727*2c2f96dcSApple OSS Distributions  *		convert the compatability flags in the terminal flags
728*2c2f96dcSApple OSS Distributions  *		fields into canonical flags in the provided termios struct.
729*2c2f96dcSApple OSS Distributions  *
730*2c2f96dcSApple OSS Distributions  * Parameters:	struct tty *tp		The tty on which the operation is
731*2c2f96dcSApple OSS Distributions  *					being performed.
732*2c2f96dcSApple OSS Distributions  *		struct termios *t	The termios structure into which to
733*2c2f96dcSApple OSS Distributions  *					return the converted local flags.
734*2c2f96dcSApple OSS Distributions  *
735*2c2f96dcSApple OSS Distributions  * Returns:	void			(implicit: *t, modified)
736*2c2f96dcSApple OSS Distributions  */
737*2c2f96dcSApple OSS Distributions static void
ttcompatsetlflags(struct tty * tp,struct termios * t)738*2c2f96dcSApple OSS Distributions ttcompatsetlflags(struct tty *tp, struct termios *t)
739*2c2f96dcSApple OSS Distributions {
740*2c2f96dcSApple OSS Distributions 	int flags = tp->t_flags;
741*2c2f96dcSApple OSS Distributions 	tcflag_t iflag  = t->c_iflag;
742*2c2f96dcSApple OSS Distributions 	tcflag_t oflag  = t->c_oflag;
743*2c2f96dcSApple OSS Distributions 	tcflag_t lflag  = t->c_lflag;
744*2c2f96dcSApple OSS Distributions 	tcflag_t cflag  = t->c_cflag;
745*2c2f96dcSApple OSS Distributions 
746*2c2f96dcSApple OSS Distributions 	iflag &= ~(PARMRK | IGNPAR | IGNCR | INLCR);
747*2c2f96dcSApple OSS Distributions 	if (flags & CRTERA) {
748*2c2f96dcSApple OSS Distributions 		lflag |= ECHOE;
749*2c2f96dcSApple OSS Distributions 	} else {
750*2c2f96dcSApple OSS Distributions 		lflag &= ~ECHOE;
751*2c2f96dcSApple OSS Distributions 	}
752*2c2f96dcSApple OSS Distributions 	if (flags & CRTKIL) {
753*2c2f96dcSApple OSS Distributions 		lflag |= ECHOKE;
754*2c2f96dcSApple OSS Distributions 	} else {
755*2c2f96dcSApple OSS Distributions 		lflag &= ~ECHOKE;
756*2c2f96dcSApple OSS Distributions 	}
757*2c2f96dcSApple OSS Distributions 	if (flags & PRTERA) {
758*2c2f96dcSApple OSS Distributions 		lflag |= ECHOPRT;
759*2c2f96dcSApple OSS Distributions 	} else {
760*2c2f96dcSApple OSS Distributions 		lflag &= ~ECHOPRT;
761*2c2f96dcSApple OSS Distributions 	}
762*2c2f96dcSApple OSS Distributions 	if (flags & CTLECH) {
763*2c2f96dcSApple OSS Distributions 		lflag |= ECHOCTL;
764*2c2f96dcSApple OSS Distributions 	} else {
765*2c2f96dcSApple OSS Distributions 		lflag &= ~ECHOCTL;
766*2c2f96dcSApple OSS Distributions 	}
767*2c2f96dcSApple OSS Distributions 	if (flags & TANDEM) {
768*2c2f96dcSApple OSS Distributions 		iflag |= IXOFF;
769*2c2f96dcSApple OSS Distributions 	} else {
770*2c2f96dcSApple OSS Distributions 		iflag &= ~IXOFF;
771*2c2f96dcSApple OSS Distributions 	}
772*2c2f96dcSApple OSS Distributions 	if ((flags & DECCTQ) == 0) {
773*2c2f96dcSApple OSS Distributions 		iflag |= IXANY;
774*2c2f96dcSApple OSS Distributions 	} else {
775*2c2f96dcSApple OSS Distributions 		iflag &= ~IXANY;
776*2c2f96dcSApple OSS Distributions 	}
777*2c2f96dcSApple OSS Distributions 	if (flags & MDMBUF) {
778*2c2f96dcSApple OSS Distributions 		cflag |= MDMBUF;
779*2c2f96dcSApple OSS Distributions 	} else {
780*2c2f96dcSApple OSS Distributions 		cflag &= ~MDMBUF;
781*2c2f96dcSApple OSS Distributions 	}
782*2c2f96dcSApple OSS Distributions 	if (flags & NOHANG) {
783*2c2f96dcSApple OSS Distributions 		cflag &= ~HUPCL;
784*2c2f96dcSApple OSS Distributions 	} else {
785*2c2f96dcSApple OSS Distributions 		cflag |= HUPCL;
786*2c2f96dcSApple OSS Distributions 	}
787*2c2f96dcSApple OSS Distributions 	lflag &= ~(TOSTOP | FLUSHO | PENDIN | NOFLSH);
788*2c2f96dcSApple OSS Distributions 	lflag |= flags & (TOSTOP | FLUSHO | PENDIN | NOFLSH);
789*2c2f96dcSApple OSS Distributions 
790*2c2f96dcSApple OSS Distributions 	/*
791*2c2f96dcSApple OSS Distributions 	 * The next if-else statement is copied from above so don't bother
792*2c2f96dcSApple OSS Distributions 	 * checking it separately.  We could avoid fiddlling with the
793*2c2f96dcSApple OSS Distributions 	 * character size if the mode is already RAW or if neither the
794*2c2f96dcSApple OSS Distributions 	 * LITOUT bit or the PASS8 bit is being changed, but the delta of
795*2c2f96dcSApple OSS Distributions 	 * the change is not available here and skipping the RAW case would
796*2c2f96dcSApple OSS Distributions 	 * make the code different from above.
797*2c2f96dcSApple OSS Distributions 	 */
798*2c2f96dcSApple OSS Distributions 	cflag &= ~(CSIZE | PARENB);
799*2c2f96dcSApple OSS Distributions 	if (flags & (RAW | LITOUT | PASS8)) {
800*2c2f96dcSApple OSS Distributions 		cflag |= CS8;
801*2c2f96dcSApple OSS Distributions 		if (!(flags & (RAW | PASS8))
802*2c2f96dcSApple OSS Distributions 		    || (flags & (RAW | PASS8 | ANYP)) == (PASS8 | ANYP)) {
803*2c2f96dcSApple OSS Distributions 			iflag |= ISTRIP;
804*2c2f96dcSApple OSS Distributions 		} else {
805*2c2f96dcSApple OSS Distributions 			iflag &= ~ISTRIP;
806*2c2f96dcSApple OSS Distributions 		}
807*2c2f96dcSApple OSS Distributions 		if (flags & (RAW | LITOUT)) {
808*2c2f96dcSApple OSS Distributions 			oflag &= ~OPOST;
809*2c2f96dcSApple OSS Distributions 		} else {
810*2c2f96dcSApple OSS Distributions 			oflag |= OPOST;
811*2c2f96dcSApple OSS Distributions 		}
812*2c2f96dcSApple OSS Distributions 	} else {
813*2c2f96dcSApple OSS Distributions 		cflag |= CS7 | PARENB;
814*2c2f96dcSApple OSS Distributions 		iflag |= ISTRIP;
815*2c2f96dcSApple OSS Distributions 		oflag |= OPOST;
816*2c2f96dcSApple OSS Distributions 	}
817*2c2f96dcSApple OSS Distributions 	t->c_iflag = iflag;
818*2c2f96dcSApple OSS Distributions 	t->c_oflag = oflag;
819*2c2f96dcSApple OSS Distributions 	t->c_lflag = lflag;
820*2c2f96dcSApple OSS Distributions 	t->c_cflag = cflag;
821*2c2f96dcSApple OSS Distributions }
822