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