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