1 /* $NetBSD: linux32_termios.c,v 1.13 2008/07/04 11:06:31 matthias Exp $ */
4 * Copyright (c) 1995-2006, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden, Eric Haszlakiewicz, and Emmanuel Dreyfus.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: linux32_termios.c,v 1.13 2008/07/04 11:06:31 matthias Exp $");
36 #include "opt_compat_linux32.h"
39 #include <sys/types.h>
40 #include <sys/param.h>
42 #include <sys/ucred.h>
46 #include <sys/filedesc.h>
47 #include <sys/fcntl.h>
48 #include <sys/termios.h>
49 #include <sys/kernel.h>
51 #include <compat/netbsd32/netbsd32.h>
52 #include <compat/netbsd32/netbsd32_syscallargs.h>
54 #include <compat/linux32/common/linux32_types.h>
55 #include <compat/linux32/common/linux32_signal.h>
56 #include <compat/linux32/common/linux32_ioctl.h>
57 #include <compat/linux32/common/linux32_machdep.h>
58 #include <compat/linux32/common/linux32_termios.h>
59 #include <compat/linux32/linux32_syscallargs.h>
61 #include <compat/linux/common/linux_types.h>
62 #include <compat/linux/common/linux_signal.h>
63 #include <compat/linux/common/linux_util.h>
64 #include <compat/linux/common/linux_termios.h>
65 #include <compat/linux/common/linux_ipc.h>
66 #include <compat/linux/common/linux_sem.h>
67 #include <compat/linux/linux_syscallargs.h>
70 linux32_ioctl_termios(struct lwp
*l
, const struct linux32_sys_ioctl_args
*uap
, register_t
*retval
)
74 syscallarg(netbsd32_u_long) com;
75 syscallarg(netbsd32_charp) data;
79 struct linux32_termio tmplt
;
80 struct linux32_termios tmplts
;
81 struct termios tmpbts
;
83 struct netbsd32_ioctl_args ia
;
86 int (*bsdioctl
)(file_t
*, u_long
, void *);
88 if ((fp
= fd_getfile(SCARG(uap
, fd
))) == NULL
)
91 if ((fp
->f_flag
& (FREAD
| FWRITE
)) == 0) {
92 fd_putfile(SCARG(uap
, fd
));
97 bsdioctl
= fp
->f_ops
->fo_ioctl
;
98 com
= SCARG(uap
, com
);
103 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
106 bsd_termios_to_linux32_termios(&tmpbts
, &tmplts
);
107 error
= copyout(&tmplts
, SCARG_P32(uap
, data
), sizeof tmplts
);
110 case LINUX32_TCSETSW
:
111 case LINUX32_TCSETSF
:
113 * First fill in all fields, so that we keep the current
114 * values for fields that Linux doesn't know about.
116 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
119 if ((error
= copyin(SCARG_P32(uap
, data
),
120 &tmplts
, sizeof tmplts
)) != 0)
122 linux32_termios_to_bsd_termios(&tmplts
, &tmpbts
);
127 case LINUX32_TCSETSW
:
130 case LINUX32_TCSETSF
:
134 error
= (*bsdioctl
)(fp
, com
, &tmpbts
);
137 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
140 bsd_termios_to_linux32_termio(&tmpbts
, &tmplt
);
141 error
= copyout(&tmplt
, SCARG_P32(uap
, data
), sizeof tmplt
);
144 case LINUX32_TCSETAW
:
145 case LINUX32_TCSETAF
:
147 * First fill in all fields, so that we keep the current
148 * values for fields that Linux doesn't know about.
150 error
= (*bsdioctl
)(fp
, TIOCGETA
, &tmpbts
);
153 if ((error
= copyin(SCARG_P32(uap
, data
),
154 &tmplt
, sizeof tmplt
)) != 0)
156 linux32_termio_to_bsd_termios(&tmplt
, &tmpbts
);
161 case LINUX32_TCSETAW
:
164 case LINUX32_TCSETAF
:
168 error
= (*bsdioctl
)(fp
, com
, &tmpbts
);
171 switch((u_long
)SCARG_P32(uap
, data
)) {
185 error
= (*bsdioctl
)(fp
, TIOCFLUSH
, &idat
);
187 case LINUX32_TIOCGETD
:
188 error
= (*bsdioctl
)(fp
, TIOCGETD
, &idat
);
202 idat
= LINUX_N_STRIP
;
205 * Linux does not have the tablet line discipline.
209 idat
= -1; /* XXX What should this be? */
212 error
= copyout(&idat
, SCARG_P32(uap
, data
), sizeof idat
);
214 case LINUX32_TIOCSETD
:
215 if ((error
= copyin(SCARG_P32(uap
, data
),
216 &idat
, sizeof idat
)) != 0)
232 * We can't handle the mouse line discipline Linux has.
242 error
= (*bsdioctl
)(fp
, TIOCSETD
, &idat
);
244 case LINUX32_TIOCLINUX
:
245 if ((error
= copyin(SCARG_P32(uap
, data
),
246 &tioclinux
, sizeof tioclinux
)) != 0)
249 case LINUX_TIOCLINUX_KERNMSG
:
251 * XXX needed to not fail for some things. Could
252 * try to use TIOCCONS, but the char argument
253 * specifies the VT #, not an fd.
257 case LINUX_TIOCLINUX_COPY
:
258 case LINUX_TIOCLINUX_PASTE
:
259 case LINUX_TIOCLINUX_UNBLANK
:
260 case LINUX_TIOCLINUX_LOADLUT
:
261 case LINUX_TIOCLINUX_READSHIFT
:
262 case LINUX_TIOCLINUX_READMOUSE
:
263 case LINUX_TIOCLINUX_VESABLANK
:
264 case LINUX_TIOCLINUX_CURCONS
: /* could use VT_GETACTIVE */
269 case LINUX32_TIOCGWINSZ
:
270 SCARG(&ia
, com
) = TIOCGWINSZ
;
272 case LINUX32_TIOCSWINSZ
:
273 SCARG(&ia
, com
) = TIOCSWINSZ
;
275 case LINUX32_TIOCGPGRP
:
276 SCARG(&ia
, com
) = TIOCGPGRP
;
278 case LINUX32_TIOCSPGRP
:
279 SCARG(&ia
, com
) = TIOCSPGRP
;
281 case LINUX32_FIONREAD
:
282 SCARG(&ia
, com
) = FIONREAD
;
284 case LINUX32_FIONBIO
:
285 SCARG(&ia
, com
) = FIONBIO
;
287 case LINUX32_FIOASYNC
:
288 SCARG(&ia
, com
) = FIOASYNC
;
290 case LINUX32_TIOCEXCL
:
291 SCARG(&ia
, com
) = TIOCEXCL
;
293 case LINUX32_TIOCNXCL
:
294 SCARG(&ia
, com
) = TIOCNXCL
;
296 case LINUX32_TIOCCONS
:
297 SCARG(&ia
, com
) = TIOCCONS
;
299 case LINUX32_TIOCNOTTY
:
300 SCARG(&ia
, com
) = TIOCNOTTY
;
303 idat
= (u_long
)SCARG_P32(uap
, data
);
305 SCARG(&ia
, com
) = TIOCDRAIN
;
307 if ((error
= (*bsdioctl
)(fp
, TIOCSBRK
, NULL
)) != 0)
309 error
= tsleep(&idat
, PZERO
| PCATCH
, "linux_tcsbrk", hz
/ 4);
310 if (error
== EINTR
|| error
== ERESTART
) {
311 (void)(*bsdioctl
)(fp
, TIOCCBRK
, NULL
);
314 error
= (*bsdioctl
)(fp
, TIOCCBRK
, NULL
);
318 case LINUX32_TIOCMGET
:
319 SCARG(&ia
, com
) = TIOCMGET
;
321 case LINUX32_TIOCMSET
:
322 SCARG(&ia
, com
) = TIOCMSET
;
324 case LINUX32_TIOCMBIC
:
325 SCARG(&ia
, com
) = TIOCMBIC
;
327 case LINUX32_TIOCMBIS
:
328 SCARG(&ia
, com
) = TIOCMBIS
;
330 #ifdef LINUX32_TIOCGPTN
331 case LINUX32_TIOCGPTN
:
336 error
= (*bsdioctl
)(fp
, TIOCPTSNAME
, &ptm
);
340 error
= copyout(&ptm
.sfd
, SCARG_P32(uap
, data
),
344 #endif /* NO_DEV_PTM */
345 #endif /* LINUX32_TIOCGPTN */
351 SCARG(&ia
, fd
) = SCARG(uap
, fd
);
352 SCARG(&ia
, data
) = SCARG(uap
, data
);
353 error
= netbsd32_ioctl(curlwp
, &ia
, retval
);
355 fd_putfile(SCARG(uap
, fd
));