svr4_ioctl.c revision 255219
151694Sroger/*- 251694Sroger * Copyright (c) 1998 Mark Newton 351694Sroger * Copyright (c) 1994 Christos Zoulas 451694Sroger * All rights reserved. 551694Sroger * 651694Sroger * Redistribution and use in source and binary forms, with or without 751694Sroger * modification, are permitted provided that the following conditions 851694Sroger * are met: 951694Sroger * 1. Redistributions of source code must retain the above copyright 1051694Sroger * notice, this list of conditions and the following disclaimer. 1151694Sroger * 2. Redistributions in binary form must reproduce the above copyright 1251694Sroger * notice, this list of conditions and the following disclaimer in the 1351694Sroger * documentation and/or other materials provided with the distribution. 1451694Sroger * 3. The name of the author may not be used to endorse or promote products 1551694Sroger * derived from this software without specific prior written permission 1651694Sroger * 1751694Sroger * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1851694Sroger * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1951694Sroger * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2051694Sroger * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2151694Sroger * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2251694Sroger * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2351694Sroger * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2451694Sroger * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2551694Sroger * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2651694Sroger * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2751694Sroger */ 2851694Sroger 2951694Sroger#include <sys/cdefs.h> 3051694Sroger__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_ioctl.c 255219 2013-09-05 00:09:56Z pjd $"); 3151694Sroger 3251694Sroger#include <sys/param.h> 3351694Sroger#include <sys/proc.h> 3451694Sroger#include <sys/capability.h> 3551694Sroger#include <sys/file.h> 3651694Sroger#include <sys/filedesc.h> 3751694Sroger#include <sys/fcntl.h> 3851694Sroger#include <sys/socket.h> 3951694Sroger#include <sys/socketvar.h> 4051694Sroger#include <sys/systm.h> 4151694Sroger 4251694Sroger#include <compat/svr4/svr4.h> 4351694Sroger#include <compat/svr4/svr4_types.h> 4451694Sroger#include <compat/svr4/svr4_util.h> 4551694Sroger#include <compat/svr4/svr4_signal.h> 4651694Sroger#include <compat/svr4/svr4_proto.h> 4751694Sroger#include <compat/svr4/svr4_stropts.h> 4851694Sroger#include <compat/svr4/svr4_ioctl.h> 4951694Sroger#include <compat/svr4/svr4_termios.h> 5051694Sroger#include <compat/svr4/svr4_filio.h> 5151694Sroger#include <compat/svr4/svr4_sockio.h> 5251694Sroger 5351694Sroger#ifdef DEBUG_SVR4 5451694Srogerstatic void svr4_decode_cmd(u_long, char *, char *, int *, int *); 5551694Sroger/* 5659014Sroger * Decode an ioctl command symbolically 5751694Sroger */ 5851694Srogerstatic void 5951694Srogersvr4_decode_cmd(cmd, dir, c, num, argsiz) 6051694Sroger u_long cmd; 6162214Sroger char *dir, *c; 6262214Sroger int *num, *argsiz; 6362214Sroger{ 6462214Sroger if (cmd & SVR4_IOC_VOID) 6562214Sroger *dir++ = 'V'; 6662214Sroger if (cmd & SVR4_IOC_IN) 6751694Sroger *dir++ = 'R'; 6851694Sroger if (cmd & SVR4_IOC_OUT) 6951694Sroger *dir++ = 'W'; 7051694Sroger *dir = '\0'; 7151694Sroger if (cmd & SVR4_IOC_INOUT) 7251694Sroger *argsiz = (cmd >> 16) & 0xff; 7351694Sroger else 7451694Sroger *argsiz = -1; 7551694Sroger 7651694Sroger *c = (cmd >> 8) & 0xff; 7751694Sroger *num = cmd & 0xff; 7851694Sroger} 7951694Sroger#endif 8051694Sroger 8151694Srogerint 8251694Srogersvr4_sys_ioctl(td, uap) 8351694Sroger struct thread *td; 8451694Sroger struct svr4_sys_ioctl_args *uap; 8551694Sroger{ 8651694Sroger int *retval; 8751694Sroger cap_rights_t rights; 8851694Sroger struct file *fp; 8951694Sroger u_long cmd; 9051694Sroger int (*fun)(struct file *, struct thread *, register_t *, 9151694Sroger int, u_long, caddr_t); 9251694Sroger int error; 9359014Sroger#ifdef DEBUG_SVR4 9459014Sroger char dir[4]; 9559014Sroger char c; 9659014Sroger int num; 9759014Sroger int argsiz; 9859014Sroger 9951694Sroger svr4_decode_cmd(uap->com, dir, &c, &num, &argsiz); 10051694Sroger 10151694Sroger DPRINTF(("svr4_ioctl[%lx](%d, _IO%s(%c, %d, %d), %p);\n", uap->com, uap->fd, 10251694Sroger dir, c, num, argsiz, uap->data)); 10351694Sroger#endif 10459014Sroger retval = td->td_retval; 10551694Sroger cmd = uap->com; 10651694Sroger 10751694Sroger error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); 10851694Sroger if (error != 0) 10951694Sroger return (error); 11051694Sroger 11151694Sroger if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 11251694Sroger fdrop(fp, td); 11351694Sroger return EBADF; 11451694Sroger } 11551694Sroger 11651694Sroger#if defined(DEBUG_SVR4) 11751694Sroger if (fp->f_type == DTYPE_SOCKET) { 11859014Sroger struct socket *so = fp->f_data; 11951694Sroger DPRINTF(("<<< IN: so_state = 0x%x\n", so->so_state)); 12051694Sroger } 12151694Sroger#endif 12251694Sroger 12351694Sroger switch (cmd & 0xff00) { 12451694Sroger case SVR4_TIOC: 12559014Sroger DPRINTF(("term\n")); 12651694Sroger fun = svr4_term_ioctl; 12751694Sroger break; 12851694Sroger 12951694Sroger case SVR4_STR: 13051694Sroger DPRINTF(("stream\n")); 13162214Sroger fun = svr4_stream_ioctl; 13251694Sroger break; 13362214Sroger 13462214Sroger case SVR4_FIOC: 13551694Sroger DPRINTF(("file\n")); 13651694Sroger fun = svr4_fil_ioctl; 13751694Sroger break; 13851694Sroger 13951694Sroger case SVR4_SIOC: 14051694Sroger DPRINTF(("socket\n")); 14151694Sroger fun = svr4_sock_ioctl; 14251694Sroger break; 14351694Sroger 14451694Sroger case SVR4_XIOC: 14551694Sroger /* We do not support those */ 14662214Sroger fdrop(fp, td); 14762214Sroger return EINVAL; 14862214Sroger 14962214Sroger default: 15062214Sroger fdrop(fp, td); 15162214Sroger DPRINTF(("Unimplemented ioctl %lx\n", cmd)); 15262214Sroger return 0; /* XXX: really ENOSYS */ 15362214Sroger } 15462214Sroger#if defined(DEBUG_SVR4) 15562214Sroger if (fp->f_type == DTYPE_SOCKET) { 15662214Sroger struct socket *so; 15762214Sroger 15862214Sroger so = fp->f_data; 15962214Sroger DPRINTF((">>> OUT: so_state = 0x%x\n", so->so_state)); 16062214Sroger } 16162214Sroger#endif 16262214Sroger error = (*fun)(fp, td, retval, uap->fd, cmd, uap->data); 16362214Sroger fdrop(fp, td); 16462214Sroger return (error); 16562214Sroger} 16659014Sroger