]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty_compat.c
xnu-1228.0.2.tar.gz
[apple/xnu.git] / bsd / kern / tty_compat.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
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
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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>
71 #include <sys/proc_internal.h>
72 #include <sys/tty.h>
73 #include <sys/termios.h>
74 #include <sys/file_internal.h>
75 #include <sys/conf.h>
76 #include <sys/kernel.h>
77 #include <sys/sysctl.h>
78 #include <sys/syslog.h>
79
80 /* NeXT Move define down here cause COMPAT_43_TTY not valid earlier */
81 #if COMPAT_43_TTY || defined(COMPAT_SUNOS)
82
83 static int ttcompatgetflags(struct tty *tp);
84 static void ttcompatsetflags(struct tty *tp, struct termios *t);
85 static void ttcompatsetlflags(struct tty *tp, struct termios *t);
86 static int ttcompatspeedtab(int speed, struct speedtab *table);
87
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 */
95 static 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 };
117 static int compatspcodes[] = {
118 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
119 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
120 };
121
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 */
144 static int
145 ttcompatspeedtab(int speed, struct speedtab *table)
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
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 */
199 __private_extern__ int
200 ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term)
201 {
202 switch (*com) {
203 case TIOCSETP:
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 {
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 }
238 case TIOCSETC:
239 /*
240 * Set the terminal control characters per the contents of
241 * the struct tchars that 'data' points to.
242 */
243 {
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 }
259 case TIOCSLTC:
260 /*
261 * Set the terminal control characters per the contents of
262 * the struct ltchars that 'data' points to.
263 */
264 {
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:
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 */
284 case TIOCLBIC:
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 */
290 case TIOCLSET:
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 */
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
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 */
348 /*ARGSUSED*/
349 __private_extern__ int
350 ttcompat(struct tty *tp, u_long com, caddr_t data, int flag, struct proc *p)
351 {
352 switch (com) {
353 case TIOCSETP:
354 case TIOCSETN:
355 case TIOCSETC:
356 case TIOCSLTC:
357 case TIOCLBIS:
358 case TIOCLBIC:
359 case TIOCLSET:
360 /*
361 * See ttsetcompat() for a full description of these command
362 * values and their meanings.
363 */
364 {
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;
371 return ttioctl(tp, com, (caddr_t) &term, flag, p);
372 }
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 {
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 }
392 case TIOCGETC:
393 /*
394 * Get the terminal control characters into the struct
395 * tchars that 'data' points to.
396 */
397 {
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 }
409 case TIOCGLTC:
410 /*
411 * Get the terminal control characters into the struct
412 * ltchars that 'data' points to.
413 */
414 {
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:
427 /*
428 * Get the terminal state local flags word into the 16 bit
429 * value pointed to by 'data'.
430 */
431 tp->t_flags =
432 (ttcompatgetflags(tp) & 0xffff0000UL)
433 | (tp->t_flags & 0xffff);
434 *(int *)data = tp->t_flags>>16;
435 break;
436
437 case OTIOCGETD:
438 /*
439 * Get the current line discipline into the int pointed to
440 * by 'data'.
441 */
442 *(int *)data = tp->t_line ? tp->t_line : 2;
443 break;
444
445 case OTIOCSETD:
446 /*
447 * Set the current line discipline based on the value of the
448 * int pointed to by 'data'.
449 */
450 {
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:
458 /*
459 * Become the console device.
460 */
461 *(int *)data = 1;
462 return (ttioctl(tp, TIOCCONS, data, flag, p));
463
464 case TIOCGSID:
465 /*
466 * Get the current session ID (controlling process' PID).
467 */
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;
476
477 default:
478 /*
479 * This ioctl is not handled at this layer.
480 */
481 return (ENOTTY);
482 }
483
484 /*
485 * Successful 'get' operation.
486 */
487 return (0);
488 }
489
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 */
506 static int
507 ttcompatgetflags(struct tty *tp)
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;
513 register int flags = 0;
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)
537 || (cflag&(CSIZE|PARENB)) != CS8)
538 flags |= CBREAK;
539 else
540 flags |= RAW;
541 }
542 if (!(flags&RAW) && !(oflag&OPOST) && (cflag&(CSIZE|PARENB)) == CS8)
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);
561 return (flags);
562 }
563
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 */
578 static void
579 ttcompatsetflags(struct tty *tp, struct termios *t)
580 {
581 register int flags = tp->t_flags;
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
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 */
669 static void
670 ttcompatsetlflags(struct tty *tp, struct termios *t)
671 {
672 register int flags = tp->t_flags;
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 }
744 #endif /* COMPAT_43_TTY || COMPAT_SUNOS */