Home | History | Annotate | Line # | Download | only in common
linux32_termios.c revision 1.1.4.1
      1  1.1.4.1  yamt /*	$NetBSD: linux32_termios.c,v 1.1.4.1 2006/09/03 15:23:46 yamt Exp $ */
      2      1.1  manu 
      3      1.1  manu /*-
      4      1.1  manu  * Copyright (c) 1995-2006  The NetBSD Foundation, Inc.
      5      1.1  manu  * All rights reserved.
      6      1.1  manu  *
      7      1.1  manu  * This code is derived from software contributed to The NetBSD Foundation
      8      1.1  manu  * by Frank van der Linden, Eric Haszlakiewicz, and Emmanuel Dreyfus.
      9      1.1  manu  *
     10      1.1  manu  * Redistribution and use in source and binary forms, with or without
     11      1.1  manu  * modification, are permitted provided that the following conditions
     12      1.1  manu  * are met:
     13      1.1  manu  * 1. Redistributions of source code must retain the above copyright
     14      1.1  manu  *    notice, this list of conditions and the following disclaimer.
     15      1.1  manu  * 2. Redistributions in binary form must reproduce the above copyright
     16      1.1  manu  *    notice, this list of conditions and the following disclaimer in the
     17      1.1  manu  *    documentation and/or other materials provided with the distribution.
     18      1.1  manu  * 3. All advertising materials mentioning features or use of this software
     19      1.1  manu  *    must display the following acknowledgement:
     20      1.1  manu  *	This product includes software developed by the NetBSD
     21      1.1  manu  *	Foundation, Inc. and its contributors.
     22      1.1  manu  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23      1.1  manu  *    contributors may be used to endorse or promote products derived
     24      1.1  manu  *    from this software without specific prior written permission.
     25      1.1  manu  *
     26      1.1  manu  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27      1.1  manu  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28      1.1  manu  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29      1.1  manu  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30      1.1  manu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31      1.1  manu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32      1.1  manu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33      1.1  manu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34      1.1  manu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35      1.1  manu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36      1.1  manu  * POSSIBILITY OF SUCH DAMAGE.
     37      1.1  manu  */
     38      1.1  manu 
     39      1.1  manu #include <sys/cdefs.h>
     40  1.1.4.1  yamt __KERNEL_RCSID(0, "$NetBSD: linux32_termios.c,v 1.1.4.1 2006/09/03 15:23:46 yamt Exp $");
     41      1.1  manu 
     42      1.1  manu #include "opt_compat_linux32.h"
     43      1.1  manu 
     44      1.1  manu #include <sys/types.h>
     45      1.1  manu #include <sys/param.h>
     46      1.1  manu #include <sys/time.h>
     47      1.1  manu #include <sys/ucred.h>
     48      1.1  manu #include <sys/proc.h>
     49      1.1  manu #include <sys/lwp.h>
     50      1.1  manu #include <sys/file.h>
     51      1.1  manu #include <sys/filedesc.h>
     52      1.1  manu #include <sys/fcntl.h>
     53      1.1  manu #include <sys/termios.h>
     54      1.1  manu 
     55      1.1  manu #include <compat/netbsd32/netbsd32.h>
     56      1.1  manu #include <compat/netbsd32/netbsd32_syscallargs.h>
     57      1.1  manu 
     58      1.1  manu #include <compat/linux32/common/linux32_types.h>
     59      1.1  manu #include <compat/linux32/common/linux32_signal.h>
     60      1.1  manu #include <compat/linux32/common/linux32_ioctl.h>
     61      1.1  manu #include <compat/linux32/common/linux32_machdep.h>
     62      1.1  manu #include <compat/linux32/common/linux32_termios.h>
     63      1.1  manu #include <compat/linux32/linux32_syscallargs.h>
     64      1.1  manu 
     65      1.1  manu #include <compat/linux/common/linux_types.h>
     66      1.1  manu #include <compat/linux/common/linux_signal.h>
     67      1.1  manu #include <compat/linux/common/linux_util.h>
     68      1.1  manu #include <compat/linux/common/linux_termios.h>
     69      1.1  manu #include <compat/linux/linux_syscallargs.h>
     70      1.1  manu 
     71      1.1  manu int
     72      1.1  manu linux32_ioctl_termios(l, uap, retval)
     73      1.1  manu 	struct lwp *l;
     74      1.1  manu 	struct linux32_sys_ioctl_args /* {
     75      1.1  manu 		syscallarg(int) fd;
     76      1.1  manu 		syscallarg(netbsd32_u_long) com;
     77      1.1  manu 		syscallarg(netbsd32_charp) data;
     78      1.1  manu 	} */ *uap;
     79      1.1  manu 	register_t *retval;
     80      1.1  manu {
     81      1.1  manu 	struct file *fp;
     82      1.1  manu 	struct filedesc *fdp;
     83      1.1  manu 	u_long com;
     84      1.1  manu 	struct linux32_termio tmplt;
     85      1.1  manu 	struct linux32_termios tmplts;
     86      1.1  manu 	struct termios tmpbts;
     87      1.1  manu 	int idat;
     88  1.1.4.1  yamt 	struct netbsd32_ioctl_args ia;
     89      1.1  manu 	int error;
     90      1.1  manu 	char tioclinux;
     91      1.1  manu 	int (*bsdioctl)(struct file *, u_long, void *, struct lwp *);
     92      1.1  manu 
     93      1.1  manu 	fdp = l->l_proc->p_fd;
     94      1.1  manu 	if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
     95      1.1  manu 		return (EBADF);
     96      1.1  manu 
     97      1.1  manu 	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
     98      1.1  manu 		error = EBADF;
     99      1.1  manu 		goto out;
    100      1.1  manu 	}
    101      1.1  manu 
    102      1.1  manu 	FILE_USE(fp);
    103      1.1  manu 
    104      1.1  manu 	bsdioctl = fp->f_ops->fo_ioctl;
    105      1.1  manu 	com = SCARG(uap, com);
    106      1.1  manu 	retval[0] = 0;
    107      1.1  manu 
    108      1.1  manu 	switch (com & 0xffff) {
    109      1.1  manu 	case LINUX32_TCGETS:
    110      1.1  manu 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, l);
    111      1.1  manu 		if (error)
    112      1.1  manu 			goto out;
    113      1.1  manu 		bsd_termios_to_linux32_termios(&tmpbts, &tmplts);
    114      1.1  manu 		error = copyout(&tmplts,
    115      1.1  manu 		    NETBSD32PTR64(SCARG(uap, data)),
    116      1.1  manu 		    sizeof tmplts);
    117      1.1  manu 		goto out;
    118      1.1  manu 	case LINUX32_TCSETS:
    119      1.1  manu 	case LINUX32_TCSETSW:
    120      1.1  manu 	case LINUX32_TCSETSF:
    121      1.1  manu 		/*
    122      1.1  manu 		 * First fill in all fields, so that we keep the current
    123      1.1  manu 		 * values for fields that Linux doesn't know about.
    124      1.1  manu 		 */
    125      1.1  manu 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, l);
    126      1.1  manu 		if (error)
    127      1.1  manu 			goto out;
    128      1.1  manu 		if ((error = copyin(NETBSD32PTR64(SCARG(uap, data)),
    129      1.1  manu 		    &tmplts, sizeof tmplts)) != 0)
    130      1.1  manu 			goto out;
    131      1.1  manu 		linux32_termios_to_bsd_termios(&tmplts, &tmpbts);
    132      1.1  manu 		switch (com) {
    133      1.1  manu 		case LINUX32_TCSETS:
    134      1.1  manu 			com = TIOCSETA;
    135      1.1  manu 			break;
    136      1.1  manu 		case LINUX32_TCSETSW:
    137      1.1  manu 			com = TIOCSETAW;
    138      1.1  manu 			break;
    139      1.1  manu 		case LINUX32_TCSETSF:
    140      1.1  manu 			com = TIOCSETAF;
    141      1.1  manu 			break;
    142      1.1  manu 		}
    143      1.1  manu 		error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, l);
    144      1.1  manu 		goto out;
    145      1.1  manu 	case LINUX32_TCGETA:
    146      1.1  manu 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, l);
    147      1.1  manu 		if (error)
    148      1.1  manu 			goto out;
    149      1.1  manu 		bsd_termios_to_linux32_termio(&tmpbts, &tmplt);
    150      1.1  manu 		error = copyout(&tmplt,
    151      1.1  manu 		    NETBSD32PTR64(SCARG(uap, data)),
    152      1.1  manu 		    sizeof tmplt);
    153      1.1  manu 		goto out;
    154      1.1  manu 	case LINUX32_TCSETA:
    155      1.1  manu 	case LINUX32_TCSETAW:
    156      1.1  manu 	case LINUX32_TCSETAF:
    157      1.1  manu 		/*
    158      1.1  manu 		 * First fill in all fields, so that we keep the current
    159      1.1  manu 		 * values for fields that Linux doesn't know about.
    160      1.1  manu 		 */
    161      1.1  manu 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, l);
    162      1.1  manu 		if (error)
    163      1.1  manu 			goto out;
    164      1.1  manu 		if ((error = copyin(NETBSD32PTR64(SCARG(uap, data)),
    165      1.1  manu 		    &tmplt, sizeof tmplt)) != 0)
    166      1.1  manu 			goto out;
    167      1.1  manu 		linux32_termio_to_bsd_termios(&tmplt, &tmpbts);
    168      1.1  manu 		switch (com) {
    169      1.1  manu 		case LINUX32_TCSETA:
    170      1.1  manu 			com = TIOCSETA;
    171      1.1  manu 			break;
    172      1.1  manu 		case LINUX32_TCSETAW:
    173      1.1  manu 			com = TIOCSETAW;
    174      1.1  manu 			break;
    175      1.1  manu 		case LINUX32_TCSETAF:
    176      1.1  manu 			com = TIOCSETAF;
    177      1.1  manu 			break;
    178      1.1  manu 		}
    179      1.1  manu 		error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, l);
    180      1.1  manu 		goto out;
    181      1.1  manu 	case LINUX32_TCFLSH:
    182      1.1  manu 		switch((u_long)NETBSD32PTR64(SCARG(uap, data))) {
    183      1.1  manu 		case 0:
    184      1.1  manu 			idat = FREAD;
    185      1.1  manu 			break;
    186      1.1  manu 		case 1:
    187      1.1  manu 			idat = FWRITE;
    188      1.1  manu 			break;
    189      1.1  manu 		case 2:
    190      1.1  manu 			idat = 0;
    191      1.1  manu 			break;
    192      1.1  manu 		default:
    193      1.1  manu 			error = EINVAL;
    194      1.1  manu 			goto out;
    195      1.1  manu 		}
    196      1.1  manu 		error = (*bsdioctl)(fp, TIOCFLUSH, (caddr_t)&idat, l);
    197      1.1  manu 		goto out;
    198      1.1  manu 	case LINUX32_TIOCGETD:
    199      1.1  manu 		error = (*bsdioctl)(fp, TIOCGETD, (caddr_t)&idat, l);
    200      1.1  manu 		if (error)
    201      1.1  manu 			goto out;
    202      1.1  manu 		switch (idat) {
    203      1.1  manu 		case TTYDISC:
    204      1.1  manu 			idat = LINUX_N_TTY;
    205      1.1  manu 			break;
    206      1.1  manu 		case SLIPDISC:
    207      1.1  manu 			idat = LINUX_N_SLIP;
    208      1.1  manu 			break;
    209      1.1  manu 		case PPPDISC:
    210      1.1  manu 			idat = LINUX_N_PPP;
    211      1.1  manu 			break;
    212      1.1  manu 		case STRIPDISC:
    213      1.1  manu 			idat = LINUX_N_STRIP;
    214      1.1  manu 			break;
    215      1.1  manu 		/*
    216      1.1  manu 		 * Linux does not have the tablet line discipline.
    217      1.1  manu 		 */
    218      1.1  manu 		case TABLDISC:
    219      1.1  manu 		default:
    220      1.1  manu 			idat = -1;	/* XXX What should this be? */
    221      1.1  manu 			break;
    222      1.1  manu 		}
    223      1.1  manu 		error = copyout(&idat,
    224      1.1  manu 		    NETBSD32PTR64(SCARG(uap, data)), sizeof idat);
    225      1.1  manu 		goto out;
    226      1.1  manu 	case LINUX32_TIOCSETD:
    227      1.1  manu 		if ((error = copyin(NETBSD32PTR64(SCARG(uap, data)),
    228      1.1  manu 		    &idat, sizeof idat)) != 0)
    229      1.1  manu 			goto out;
    230      1.1  manu 		switch (idat) {
    231      1.1  manu 		case LINUX_N_TTY:
    232      1.1  manu 			idat = TTYDISC;
    233      1.1  manu 			break;
    234      1.1  manu 		case LINUX_N_SLIP:
    235      1.1  manu 			idat = SLIPDISC;
    236      1.1  manu 			break;
    237      1.1  manu 		case LINUX_N_PPP:
    238      1.1  manu 			idat = PPPDISC;
    239      1.1  manu 			break;
    240      1.1  manu 		case LINUX_N_STRIP:
    241      1.1  manu 			idat = STRIPDISC;
    242      1.1  manu 			break;
    243      1.1  manu 		/*
    244      1.1  manu 		 * We can't handle the mouse line discipline Linux has.
    245      1.1  manu 		 */
    246      1.1  manu 		case LINUX_N_MOUSE:
    247      1.1  manu 		case LINUX_N_AX25:
    248      1.1  manu 		case LINUX_N_X25:
    249      1.1  manu 		case LINUX_N_6PACK:
    250      1.1  manu 		default:
    251      1.1  manu 			error = EINVAL;
    252      1.1  manu 			goto out;
    253      1.1  manu 		}
    254      1.1  manu 		error = (*bsdioctl)(fp, TIOCSETD, (caddr_t)&idat, l);
    255      1.1  manu 		goto out;
    256      1.1  manu 	case LINUX32_TIOCLINUX:
    257      1.1  manu 		if ((error = copyin(NETBSD32PTR64(SCARG(uap, data)),
    258      1.1  manu 		    &tioclinux, sizeof tioclinux)) != 0)
    259      1.1  manu 			goto out;
    260      1.1  manu 		switch (tioclinux) {
    261      1.1  manu 		case LINUX_TIOCLINUX_KERNMSG:
    262      1.1  manu 			/*
    263      1.1  manu 			 * XXX needed to not fail for some things. Could
    264      1.1  manu 			 * try to use TIOCCONS, but the char argument
    265      1.1  manu 			 * specifies the VT #, not an fd.
    266      1.1  manu 			 */
    267      1.1  manu 			error = 0;
    268      1.1  manu 			goto out;
    269      1.1  manu 		case LINUX_TIOCLINUX_COPY:
    270      1.1  manu 		case LINUX_TIOCLINUX_PASTE:
    271      1.1  manu 		case LINUX_TIOCLINUX_UNBLANK:
    272      1.1  manu 		case LINUX_TIOCLINUX_LOADLUT:
    273      1.1  manu 		case LINUX_TIOCLINUX_READSHIFT:
    274      1.1  manu 		case LINUX_TIOCLINUX_READMOUSE:
    275      1.1  manu 		case LINUX_TIOCLINUX_VESABLANK:
    276      1.1  manu 		case LINUX_TIOCLINUX_CURCONS:	/* could use VT_GETACTIVE */
    277      1.1  manu 			error = EINVAL;
    278      1.1  manu 			goto out;
    279      1.1  manu 		}
    280      1.1  manu 		break;
    281      1.1  manu 	case LINUX32_TIOCGWINSZ:
    282      1.1  manu 		SCARG(&ia, com) = TIOCGWINSZ;
    283      1.1  manu 		break;
    284      1.1  manu 	case LINUX32_TIOCSWINSZ:
    285      1.1  manu 		SCARG(&ia, com) = TIOCSWINSZ;
    286      1.1  manu 		break;
    287      1.1  manu 	case LINUX32_TIOCGPGRP:
    288      1.1  manu 		SCARG(&ia, com) = TIOCGPGRP;
    289      1.1  manu 		break;
    290      1.1  manu 	case LINUX32_TIOCSPGRP:
    291      1.1  manu 		SCARG(&ia, com) = TIOCSPGRP;
    292      1.1  manu 		break;
    293      1.1  manu 	case LINUX32_FIONREAD:
    294      1.1  manu 		SCARG(&ia, com) = FIONREAD;
    295      1.1  manu 		break;
    296      1.1  manu 	case LINUX32_FIONBIO:
    297      1.1  manu 		SCARG(&ia, com) = FIONBIO;
    298      1.1  manu 		break;
    299      1.1  manu 	case LINUX32_FIOASYNC:
    300      1.1  manu 		SCARG(&ia, com) = FIOASYNC;
    301      1.1  manu 		break;
    302      1.1  manu 	case LINUX32_TIOCEXCL:
    303      1.1  manu 		SCARG(&ia, com) = TIOCEXCL;
    304      1.1  manu 		break;
    305      1.1  manu 	case LINUX32_TIOCNXCL:
    306      1.1  manu 		SCARG(&ia, com) = TIOCNXCL;
    307      1.1  manu 		break;
    308      1.1  manu 	case LINUX32_TIOCCONS:
    309      1.1  manu 		SCARG(&ia, com) = TIOCCONS;
    310      1.1  manu 		break;
    311      1.1  manu 	case LINUX32_TIOCNOTTY:
    312      1.1  manu 		SCARG(&ia, com) = TIOCNOTTY;
    313      1.1  manu 		break;
    314      1.1  manu 	case LINUX32_TCSBRK:
    315      1.1  manu 		SCARG(&ia, com) =
    316      1.1  manu 		    NETBSD32PTR64(SCARG(uap, data)) ? TIOCDRAIN : TIOCSBRK;
    317      1.1  manu 		break;
    318      1.1  manu 	case LINUX32_TIOCMGET:
    319      1.1  manu 		SCARG(&ia, com) = TIOCMGET;
    320      1.1  manu 		break;
    321      1.1  manu 	case LINUX32_TIOCMSET:
    322      1.1  manu 		SCARG(&ia, com) = TIOCMSET;
    323      1.1  manu 		break;
    324      1.1  manu 	case LINUX32_TIOCMBIC:
    325      1.1  manu 		SCARG(&ia, com) = TIOCMBIC;
    326      1.1  manu 		break;
    327      1.1  manu 	case LINUX32_TIOCMBIS:
    328      1.1  manu 		SCARG(&ia, com) = TIOCMBIS;
    329      1.1  manu 		break;
    330      1.1  manu #ifdef LINUX32_TIOCGPTN
    331      1.1  manu 	case LINUX32_TIOCGPTN:
    332      1.1  manu #ifndef NO_DEV_PTM
    333      1.1  manu 		{
    334      1.1  manu 			caddr_t sg = stackgap_init(l->l_proc, 0);
    335      1.1  manu 			struct ptmget ptm;
    336      1.1  manu 			struct ptmget *ptmp = stackgap_alloc(l->l_proc, &sg,
    337      1.1  manu 				sizeof(*ptmp));
    338      1.1  manu 
    339      1.1  manu 			SCARG(&ia, fd) = SCARG(uap, fd);
    340      1.1  manu 			SCARG(&ia, com) = TIOCPTSNAME;
    341  1.1.4.1  yamt 			SCARG(&ia, data) = (netbsd32_u_long)(u_long)ptmp;
    342      1.1  manu 
    343      1.1  manu 			if ((error = sys_ioctl(curlwp, &ia, retval)) != 0)
    344      1.1  manu 				goto out;
    345      1.1  manu 
    346      1.1  manu 			if ((error = copyin(ptmp, &ptm, sizeof(ptm))) != 0)
    347      1.1  manu 				printf("copyin %d\n", error);
    348      1.1  manu 
    349      1.1  manu 			error = copyout(&ptm.sfd,
    350      1.1  manu 			    NETBSD32PTR64(SCARG(uap, data)),
    351      1.1  manu 			    sizeof(ptm.sfd));
    352      1.1  manu 			goto out;
    353      1.1  manu 		}
    354      1.1  manu #endif /* NO_DEV_PTM */
    355      1.1  manu #endif /* LINUX32_TIOCGPTN */
    356      1.1  manu 	default:
    357      1.1  manu 		error = EINVAL;
    358      1.1  manu 		goto out;
    359      1.1  manu 	}
    360      1.1  manu 
    361      1.1  manu 	SCARG(&ia, fd) = SCARG(uap, fd);
    362  1.1.4.1  yamt 	SCARG(&ia, data) = SCARG(uap, data);
    363      1.1  manu 	/* XXX NJWLWP */
    364      1.1  manu 	error = netbsd32_ioctl(curlwp, &ia, retval);
    365      1.1  manu out:
    366      1.1  manu 	FILE_UNUSE(fp, l);
    367      1.1  manu 	return error;
    368      1.1  manu }
    369