1 /* $NetBSD: tty_43.c,v 1.28 2008/11/14 23:10:57 ad Exp $ */
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
30 * Copyright (c) 1982, 1986, 1991, 1993
31 * The Regents of the University of California. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * @(#)tty_compat.c 8.2 (Berkeley) 1/9/95
61 * mapping routines for old line discipline (yuck)
64 #include <sys/cdefs.h>
65 __KERNEL_RCSID(0, "$NetBSD: tty_43.c,v 1.28 2008/11/14 23:10:57 ad Exp $");
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/ioctl.h>
73 #include <sys/termios.h>
75 #include <sys/kernel.h>
76 #include <sys/syslog.h>
77 #include <sys/ioctl_compat.h>
81 static const struct speedtab compatspeeds
[] = {
103 static const int compatspcodes
[] = {
104 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
105 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200
108 static int ttcompatgetflags(struct tty
*);
109 static void ttcompatsetflags(struct tty
*, struct termios
*);
110 static void ttcompatsetlflags(struct tty
*, struct termios
*);
111 int ttcompat(struct tty
*, u_long
, void *, int, struct lwp
*);
115 ttcompat(struct tty
*tp
, u_long com
, void *data
, int flag
, struct lwp
*l
)
120 struct sgttyb
*sg
= (struct sgttyb
*)data
;
124 mutex_spin_enter(&tty_lock
);
126 speed
= ttspeedtab(tp
->t_ospeed
, compatspeeds
);
127 sg
->sg_ospeed
= (speed
== -1) ? MAX_SPEED
: speed
;
128 if (tp
->t_ispeed
== 0)
129 sg
->sg_ispeed
= sg
->sg_ospeed
;
131 speed
= ttspeedtab(tp
->t_ispeed
, compatspeeds
);
132 sg
->sg_ispeed
= (speed
== -1) ? MAX_SPEED
: speed
;
134 sg
->sg_erase
= cc
[VERASE
];
135 sg
->sg_kill
= cc
[VKILL
];
136 sg
->sg_flags
= ttcompatgetflags(tp
);
137 mutex_spin_exit(&tty_lock
);
143 struct sgttyb
*sg
= (struct sgttyb
*)data
;
147 mutex_spin_enter(&tty_lock
);
148 term
= tp
->t_termios
;
149 if ((speed
= sg
->sg_ispeed
) > MAX_SPEED
|| speed
< 0)
150 term
.c_ispeed
= speed
;
152 term
.c_ispeed
= compatspcodes
[speed
];
153 if ((speed
= sg
->sg_ospeed
) > MAX_SPEED
|| speed
< 0)
154 term
.c_ospeed
= speed
;
156 term
.c_ospeed
= compatspcodes
[speed
];
157 term
.c_cc
[VERASE
] = sg
->sg_erase
;
158 term
.c_cc
[VKILL
] = sg
->sg_kill
;
159 tp
->t_flags
= (ttcompatgetflags(tp
)&0xffff0000) | (sg
->sg_flags
&0xffff);
160 ttcompatsetflags(tp
, &term
);
161 mutex_spin_exit(&tty_lock
);
162 return (ttioctl(tp
, com
== TIOCSETP
? TIOCSETAF
: TIOCSETA
,
163 (void *)&term
, flag
, l
));
167 struct tchars
*tc
= (struct tchars
*)data
;
168 u_char
*cc
= tp
->t_cc
;
170 tc
->t_intrc
= cc
[VINTR
];
171 tc
->t_quitc
= cc
[VQUIT
];
172 tc
->t_startc
= cc
[VSTART
];
173 tc
->t_stopc
= cc
[VSTOP
];
174 tc
->t_eofc
= cc
[VEOF
];
175 tc
->t_brkc
= cc
[VEOL
];
179 struct tchars
*tc
= (struct tchars
*)data
;
180 u_char
*cc
= tp
->t_cc
;
182 cc
[VINTR
] = tc
->t_intrc
;
183 cc
[VQUIT
] = tc
->t_quitc
;
184 cc
[VSTART
] = tc
->t_startc
;
185 cc
[VSTOP
] = tc
->t_stopc
;
186 cc
[VEOF
] = tc
->t_eofc
;
187 cc
[VEOL
] = tc
->t_brkc
;
188 if (tc
->t_brkc
== (char)-1)
189 cc
[VEOL2
] = _POSIX_VDISABLE
;
193 struct ltchars
*ltc
= (struct ltchars
*)data
;
194 u_char
*cc
= tp
->t_cc
;
196 cc
[VSUSP
] = ltc
->t_suspc
;
197 cc
[VDSUSP
] = ltc
->t_dsuspc
;
198 cc
[VREPRINT
] = ltc
->t_rprntc
;
199 cc
[VDISCARD
] = ltc
->t_flushc
;
200 cc
[VWERASE
] = ltc
->t_werasc
;
201 cc
[VLNEXT
] = ltc
->t_lnextc
;
205 struct ltchars
*ltc
= (struct ltchars
*)data
;
206 u_char
*cc
= tp
->t_cc
;
208 ltc
->t_suspc
= cc
[VSUSP
];
209 ltc
->t_dsuspc
= cc
[VDSUSP
];
210 ltc
->t_rprntc
= cc
[VREPRINT
];
211 ltc
->t_flushc
= cc
[VDISCARD
];
212 ltc
->t_werasc
= cc
[VWERASE
];
213 ltc
->t_lnextc
= cc
[VLNEXT
];
222 mutex_spin_enter(&tty_lock
);
223 term
= tp
->t_termios
;
224 flags
= ttcompatgetflags(tp
);
227 tp
->t_flags
= (flags
&0xffff) | (*(int *)data
<<16);
230 tp
->t_flags
= flags
| (*(int *)data
<<16);
233 tp
->t_flags
= flags
& ~(*(int *)data
<<16);
236 ttcompatsetlflags(tp
, &term
);
237 mutex_spin_exit(&tty_lock
);
238 return (ttioctl(tp
, TIOCSETA
, (void *)&term
, flag
, l
));
241 mutex_spin_enter(&tty_lock
);
242 *(int *)data
= ttcompatgetflags(tp
)>>16;
243 mutex_spin_exit(&tty_lock
);
245 printf("CLGET: returning %x\n", *(int *)data
);
249 mutex_spin_enter(&tty_lock
);
250 *(int *)data
= (tp
->t_linesw
== NULL
) ?
251 2 /* XXX old NTTYDISC */ : tp
->t_linesw
->l_no
;
252 mutex_spin_exit(&tty_lock
);
258 return (ttioctl(tp
, TIOCSETD
,
259 *(int *)data
== 2 ? (void *)&ldisczero
: data
, flag
,
265 return (ttioctl(tp
, TIOCCONS
, data
, flag
, l
));
268 mutex_spin_enter(&tty_lock
);
269 SET(tp
->t_cflag
, HUPCL
);
270 mutex_spin_exit(&tty_lock
);
274 mutex_enter(proc_lock
);
275 if (tp
->t_session
== NULL
) {
276 mutex_exit(proc_lock
);
279 if (tp
->t_session
->s_leader
== NULL
) {
280 mutex_exit(proc_lock
);
283 *(int *) data
= tp
->t_session
->s_leader
->p_pid
;
284 mutex_exit(proc_lock
);
288 return (EPASSTHROUGH
);
294 ttcompatgetflags(struct tty
*tp
)
296 tcflag_t iflag
= tp
->t_iflag
;
297 tcflag_t lflag
= tp
->t_lflag
;
298 tcflag_t oflag
= tp
->t_oflag
;
299 tcflag_t cflag
= tp
->t_cflag
;
302 KASSERT(mutex_owned(&tty_lock
));
304 if (ISSET(iflag
, IXOFF
))
306 if (ISSET(iflag
, ICRNL
) || ISSET(oflag
, ONLCR
))
308 if (ISSET(cflag
, PARENB
)) {
309 if (ISSET(iflag
, INPCK
)) {
310 if (ISSET(cflag
, PARODD
))
318 if (!ISSET(lflag
, ICANON
)) {
320 if (ISSET(iflag
, IXON
) || ISSET(lflag
, ISIG
|IEXTEN
) ||
321 ISSET(cflag
, PARENB
))
327 if (ISSET(flags
, RAW
))
328 SET(flags
, ISSET(tp
->t_flags
, LITOUT
|PASS8
));
329 else if (ISSET(cflag
, CSIZE
) == CS8
) {
330 if (!ISSET(oflag
, OPOST
))
332 if (!ISSET(iflag
, ISTRIP
))
336 if (ISSET(cflag
, MDMBUF
))
338 if (!ISSET(cflag
, HUPCL
))
340 if (ISSET(oflag
, OXTABS
))
342 if (ISSET(lflag
, ECHOE
))
343 SET(flags
, CRTERA
|CRTBS
);
344 if (ISSET(lflag
, ECHOKE
))
345 SET(flags
, CRTKIL
|CRTBS
);
346 if (ISSET(lflag
, ECHOPRT
))
348 if (ISSET(lflag
, ECHOCTL
))
350 if (!ISSET(iflag
, IXANY
))
352 SET(flags
, ISSET(lflag
, ECHO
|TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
));
354 printf("getflags: %x\n", flags
);
359 ttcompatsetflags(struct tty
*tp
, struct termios
*t
)
361 int flags
= tp
->t_flags
;
363 KASSERT(mutex_owned(&tty_lock
));
365 tcflag_t iflag
= t
->c_iflag
;
366 tcflag_t oflag
= t
->c_oflag
;
367 tcflag_t lflag
= t
->c_lflag
;
368 tcflag_t cflag
= t
->c_cflag
;
370 if (ISSET(flags
, TANDEM
))
374 if (ISSET(flags
, ECHO
))
378 if (ISSET(flags
, CRMOD
)) {
385 if (ISSET(flags
, XTABS
))
391 if (ISSET(flags
, RAW
)) {
393 CLR(lflag
, ISIG
|ICANON
|IEXTEN
);
396 SET(iflag
, BRKINT
|IXON
|IMAXBEL
);
397 SET(lflag
, ISIG
|IEXTEN
);
398 if (ISSET(flags
, CBREAK
))
402 switch (ISSET(flags
, ANYP
)) {
423 if (ISSET(flags
, RAW
|LITOUT
|PASS8
)) {
426 if (!ISSET(flags
, RAW
|PASS8
))
430 if (!ISSET(flags
, RAW
|LITOUT
))
448 ttcompatsetlflags(struct tty
*tp
, struct termios
*t
)
450 int flags
= tp
->t_flags
;
451 tcflag_t iflag
= t
->c_iflag
;
452 tcflag_t oflag
= t
->c_oflag
;
453 tcflag_t lflag
= t
->c_lflag
;
454 tcflag_t cflag
= t
->c_cflag
;
456 KASSERT(mutex_owned(&tty_lock
));
458 /* Nothing we can do with CRTBS. */
459 if (ISSET(flags
, PRTERA
))
463 if (ISSET(flags
, CRTERA
))
467 /* Nothing we can do with TILDE. */
468 if (ISSET(flags
, MDMBUF
))
472 if (ISSET(flags
, NOHANG
))
476 if (ISSET(flags
, CRTKIL
))
480 if (ISSET(flags
, CTLECH
))
484 if (!ISSET(flags
, DECCTQ
))
488 CLR(lflag
, TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
);
489 SET(lflag
, ISSET(flags
, TOSTOP
|FLUSHO
|PENDIN
|NOFLSH
));
491 if (ISSET(flags
, RAW
|LITOUT
|PASS8
)) {
494 if (!ISSET(flags
, RAW
|PASS8
))
498 if (!ISSET(flags
, RAW
|LITOUT
))