]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/tty_compat.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved */
24 * Copyright (c) 1982, 1986, 1991, 1993
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93
59 * mapping routines for old line discipline (yuck)
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/ioctl.h>
67 #include <sys/termios.h>
70 #include <sys/kernel.h>
71 #include <sys/sysctl.h>
72 #include <sys/syslog.h>
74 /* NeXT Move define down here cause COMPAT_43 not valid earlier */
75 #if COMPAT_43 || defined(COMPAT_SUNOS)
77 static int ttcompatgetflags
__P((struct tty
*tp
));
78 static void ttcompatsetflags
__P((struct tty
*tp
, struct termios
*t
));
79 static void ttcompatsetlflags
__P((struct tty
*tp
, struct termios
*t
));
80 static int ttcompatspeedtab
__P((int speed
, struct speedtab
*table
));
83 static int ttydebug
= 0;
86 SYSCTL_INT(_debug
, OID_AUTO
, ttydebug
, CTLFLAG_RW
, &ttydebug
, 0, "");
89 static struct speedtab compatspeeds
[] = {
111 static int compatspcodes
[] = {
112 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
113 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200,
117 ttcompatspeedtab(speed
, table
)
119 register struct speedtab
*table
;
122 return (0); /* hangup */
123 for ( ; table
->sp_speed
> 0; table
++)
124 if (table
->sp_speed
<= speed
) /* nearest one, rounded down */
125 return (table
->sp_code
);
126 return (1); /* 50, min and not hangup */
131 ttsetcompat(tp
, com
, data
, term
)
132 register struct tty
*tp
;
135 struct termios
*term
;
137 __private_extern__
int
138 ttsetcompat(tp
, com
, data
, term
)
139 register struct tty
*tp
;
142 struct termios
*term
;
148 register struct sgttyb
*sg
= (struct sgttyb
*)data
;
151 if ((speed
= sg
->sg_ispeed
) > MAX_SPEED
|| speed
< 0)
153 else if (speed
!= ttcompatspeedtab(tp
->t_ispeed
, compatspeeds
))
154 term
->c_ispeed
= compatspcodes
[speed
];
156 term
->c_ispeed
= tp
->t_ispeed
;
157 if ((speed
= sg
->sg_ospeed
) > MAX_SPEED
|| speed
< 0)
159 else if (speed
!= ttcompatspeedtab(tp
->t_ospeed
, compatspeeds
))
160 term
->c_ospeed
= compatspcodes
[speed
];
162 term
->c_ospeed
= tp
->t_ospeed
;
163 term
->c_cc
[VERASE
] = sg
->sg_erase
;
164 term
->c_cc
[VKILL
] = sg
->sg_kill
;
165 tp
->t_flags
= (tp
->t_flags
&0xffff0000) | (sg
->sg_flags
&0xffff);
166 ttcompatsetflags(tp
, term
);
167 *com
= (*com
== TIOCSETP
) ? TIOCSETAF
: TIOCSETA
;
171 struct tchars
*tc
= (struct tchars
*)data
;
175 cc
[VINTR
] = tc
->t_intrc
;
176 cc
[VQUIT
] = tc
->t_quitc
;
177 cc
[VSTART
] = tc
->t_startc
;
178 cc
[VSTOP
] = tc
->t_stopc
;
179 cc
[VEOF
] = tc
->t_eofc
;
180 cc
[VEOL
] = tc
->t_brkc
;
181 if (tc
->t_brkc
== -1)
182 cc
[VEOL2
] = _POSIX_VDISABLE
;
187 struct ltchars
*ltc
= (struct ltchars
*)data
;
191 cc
[VSUSP
] = ltc
->t_suspc
;
192 cc
[VDSUSP
] = ltc
->t_dsuspc
;
193 cc
[VREPRINT
] = ltc
->t_rprntc
;
194 cc
[VDISCARD
] = ltc
->t_flushc
;
195 cc
[VWERASE
] = ltc
->t_werasc
;
196 cc
[VLNEXT
] = ltc
->t_lnextc
;
203 if (*com
== TIOCLSET
)
204 tp
->t_flags
= (tp
->t_flags
&0xffff) | *(int *)data
<<16;
207 (ttcompatgetflags(tp
)&0xffff0000)|(tp
->t_flags
&0xffff);
208 if (*com
== TIOCLBIS
)
209 tp
->t_flags
|= *(int *)data
<<16;
211 tp
->t_flags
&= ~(*(int *)data
<<16);
213 ttcompatsetlflags(tp
, term
);
223 ttcompat(tp
, com
, data
, flag
)
224 register struct tty
*tp
;
229 __private_extern__
int
230 ttcompat(tp
, com
, data
, flag
, p
)
231 register struct tty
*tp
;
249 term
= tp
->t_termios
;
250 if ((error
= ttsetcompat(tp
, &com
, data
, &term
)) != 0)
253 return ttioctl(tp
, com
, (caddr_t
) &term
, flag
, p
);
255 return ttioctl(tp
, com
, &term
, flag
);
259 register struct sgttyb
*sg
= (struct sgttyb
*)data
;
260 register cc_t
*cc
= tp
->t_cc
;
262 sg
->sg_ospeed
= ttcompatspeedtab(tp
->t_ospeed
, compatspeeds
);
263 if (tp
->t_ispeed
== 0)
264 sg
->sg_ispeed
= sg
->sg_ospeed
;
266 sg
->sg_ispeed
= ttcompatspeedtab(tp
->t_ispeed
, compatspeeds
);
267 sg
->sg_erase
= cc
[VERASE
];
268 sg
->sg_kill
= cc
[VKILL
];
269 sg
->sg_flags
= tp
->t_flags
= ttcompatgetflags(tp
);
273 struct tchars
*tc
= (struct tchars
*)data
;
274 register cc_t
*cc
= tp
->t_cc
;
276 tc
->t_intrc
= cc
[VINTR
];
277 tc
->t_quitc
= cc
[VQUIT
];
278 tc
->t_startc
= cc
[VSTART
];
279 tc
->t_stopc
= cc
[VSTOP
];
280 tc
->t_eofc
= cc
[VEOF
];
281 tc
->t_brkc
= cc
[VEOL
];
285 struct ltchars
*ltc
= (struct ltchars
*)data
;
286 register cc_t
*cc
= tp
->t_cc
;
288 ltc
->t_suspc
= cc
[VSUSP
];
289 ltc
->t_dsuspc
= cc
[VDSUSP
];
290 ltc
->t_rprntc
= cc
[VREPRINT
];
291 ltc
->t_flushc
= cc
[VDISCARD
];
292 ltc
->t_werasc
= cc
[VWERASE
];
293 ltc
->t_lnextc
= cc
[VLNEXT
];
298 (ttcompatgetflags(tp
) & 0xffff0000UL
)
299 | (tp
->t_flags
& 0xffff);
300 *(int *)data
= tp
->t_flags
>>16;
303 printf("CLGET: returning %x\n", *(int *)data
);
308 *(int *)data
= tp
->t_line
? tp
->t_line
: 2;
315 return (ttioctl(tp
, TIOCSETD
,
316 *(int *)data
== 2 ? (caddr_t
)&ldisczero
: data
, flag
));
321 return (ttioctl(tp
, TIOCCONS
, data
, flag
));
326 return (ttioctl(tp
, TIOCSETD
,
327 *(int *)data
== 2 ? (caddr_t
)&ldisczero
: data
, flag
, p
));
332 return (ttioctl(tp
, TIOCCONS
, data
, flag
, p
));
335 if (tp
->t_session
== NULL
)
338 if (tp
->t_session
->s_leader
== NULL
)
341 *(int *) data
= tp
->t_session
->s_leader
->p_pid
;
353 register struct tty
*tp
;
355 register tcflag_t iflag
= tp
->t_iflag
;
356 register tcflag_t lflag
= tp
->t_lflag
;
357 register tcflag_t oflag
= tp
->t_oflag
;
358 register tcflag_t cflag
= tp
->t_cflag
;
363 if (iflag
&ICRNL
|| oflag
&ONLCR
)
365 if ((cflag
&CSIZE
) == CS8
) {
370 else if (cflag
&PARENB
) {
377 flags
|= EVENP
| ODDP
;
380 if ((lflag
&ICANON
) == 0) {
382 if (iflag
&(INPCK
|ISTRIP
|IXON
) || lflag
&(IEXTEN
|ISIG
)
383 || cflag
&(CSIZE
|PARENB
) != CS8
)
388 if (!(flags
&RAW
) && !(oflag
&OPOST
) && cflag
&(CSIZE
|PARENB
) == CS8
)
392 if ((cflag
&HUPCL
) == 0)
397 flags
|= CRTERA
|CRTBS
;
399 flags
|= CRTKIL
|CRTBS
;
404 if ((iflag
&IXANY
) == 0)
406 flags
|= lflag
&(ECHO
|TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
);
409 printf("getflags: %x\n", flags
);
415 ttcompatsetflags(tp
, t
)
416 register struct tty
*tp
;
417 register struct termios
*t
;
419 register flags
= tp
->t_flags
;
420 register tcflag_t iflag
= t
->c_iflag
;
421 register tcflag_t oflag
= t
->c_oflag
;
422 register tcflag_t lflag
= t
->c_lflag
;
423 register tcflag_t cflag
= t
->c_cflag
;
427 lflag
&= ~(ECHOCTL
|ISIG
|ICANON
|IEXTEN
);
429 iflag
&= ~(PARMRK
|IGNPAR
|IGNCR
|INLCR
);
430 iflag
|= BRKINT
|IXON
|IMAXBEL
;
431 lflag
|= ISIG
|IEXTEN
|ECHOCTL
; /* XXX was echoctl on ? */
453 cflag
&= ~(CSIZE
|PARENB
);
454 if (flags
&(RAW
|LITOUT
|PASS8
)) {
456 if (!(flags
&(RAW
|PASS8
))
457 || (flags
&(RAW
|PASS8
|ANYP
)) == (PASS8
|ANYP
))
461 if (flags
&(RAW
|LITOUT
))
470 /* XXX don't set INPCK if RAW or PASS8? */
471 if ((flags
&(EVENP
|ODDP
)) == EVENP
) {
474 } else if ((flags
&(EVENP
|ODDP
)) == ODDP
) {
483 if ((flags
&DECCTQ
) == 0)
494 ttcompatsetlflags(tp
, t
)
495 register struct tty
*tp
;
496 register struct termios
*t
;
498 register flags
= tp
->t_flags
;
499 register tcflag_t iflag
= t
->c_iflag
;
500 register tcflag_t oflag
= t
->c_oflag
;
501 register tcflag_t lflag
= t
->c_lflag
;
502 register tcflag_t cflag
= t
->c_cflag
;
504 iflag
&= ~(PARMRK
|IGNPAR
|IGNCR
|INLCR
);
525 if ((flags
&DECCTQ
) == 0)
537 lflag
&= ~(TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
);
538 lflag
|= flags
&(TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
);
541 * The next if-else statement is copied from above so don't bother
542 * checking it separately. We could avoid fiddlling with the
543 * character size if the mode is already RAW or if neither the
544 * LITOUT bit or the PASS8 bit is being changed, but the delta of
545 * the change is not available here and skipping the RAW case would
546 * make the code different from above.
548 cflag
&= ~(CSIZE
|PARENB
);
549 if (flags
&(RAW
|LITOUT
|PASS8
)) {
551 if (!(flags
&(RAW
|PASS8
))
552 || (flags
&(RAW
|PASS8
|ANYP
)) == (PASS8
|ANYP
))
556 if (flags
&(RAW
|LITOUT
))
570 #endif /* COMPAT_43 || COMPAT_SUNOS */