Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at c9a28fa7b9ac19b676deefa0a171ce7df8755c08 250 lines 5.2 kB view raw
1/* 2 * irixioctl.c: A fucking mess... 3 * 4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 5 */ 6 7#include <linux/kernel.h> 8#include <linux/sched.h> 9#include <linux/fs.h> 10#include <linux/mm.h> 11#include <linux/smp.h> 12#include <linux/sockios.h> 13#include <linux/syscalls.h> 14#include <linux/tty.h> 15#include <linux/file.h> 16#include <linux/rcupdate.h> 17 18#include <asm/uaccess.h> 19#include <asm/ioctl.h> 20#include <asm/ioctls.h> 21 22#undef DEBUG_IOCTLS 23#undef DEBUG_MISSING_IOCTL 24 25struct irix_termios { 26 tcflag_t c_iflag, c_oflag, c_cflag, c_lflag; 27 cc_t c_cc[NCCS]; 28}; 29 30extern void start_tty(struct tty_struct *tty); 31static struct tty_struct *get_tty(int fd) 32{ 33 struct file *filp; 34 struct tty_struct *ttyp = NULL; 35 36 rcu_read_lock(); 37 filp = fcheck(fd); 38 if(filp && filp->private_data) { 39 ttyp = (struct tty_struct *) filp->private_data; 40 41 if(ttyp->magic != TTY_MAGIC) 42 ttyp =NULL; 43 } 44 rcu_read_unlock(); 45 return ttyp; 46} 47 48static struct tty_struct *get_real_tty(struct tty_struct *tp) 49{ 50 if (tp->driver->type == TTY_DRIVER_TYPE_PTY && 51 tp->driver->subtype == PTY_TYPE_MASTER) 52 return tp->link; 53 else 54 return tp; 55} 56 57asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg) 58{ 59 struct tty_struct *tp, *rtp; 60 mm_segment_t old_fs; 61 int i, error = 0; 62 63#ifdef DEBUG_IOCTLS 64 printk("[%s:%d] irix_ioctl(%d, ", current->comm, current->pid, fd); 65#endif 66 switch(cmd) { 67 case 0x00005401: 68#ifdef DEBUG_IOCTLS 69 printk("TCGETA, %08lx) ", arg); 70#endif 71 error = sys_ioctl(fd, TCGETA, arg); 72 break; 73 74 case 0x0000540d: { 75 struct termios kt; 76 struct irix_termios __user *it = 77 (struct irix_termios __user *) arg; 78 79#ifdef DEBUG_IOCTLS 80 printk("TCGETS, %08lx) ", arg); 81#endif 82 if (!access_ok(VERIFY_WRITE, it, sizeof(*it))) { 83 error = -EFAULT; 84 break; 85 } 86 old_fs = get_fs(); set_fs(get_ds()); 87 error = sys_ioctl(fd, TCGETS, (unsigned long) &kt); 88 set_fs(old_fs); 89 if (error) 90 break; 91 92 error = __put_user(kt.c_iflag, &it->c_iflag); 93 error |= __put_user(kt.c_oflag, &it->c_oflag); 94 error |= __put_user(kt.c_cflag, &it->c_cflag); 95 error |= __put_user(kt.c_lflag, &it->c_lflag); 96 97 for (i = 0; i < NCCS; i++) 98 error |= __put_user(kt.c_cc[i], &it->c_cc[i]); 99 break; 100 } 101 102 case 0x0000540e: { 103 struct termios kt; 104 struct irix_termios *it = (struct irix_termios *) arg; 105 106#ifdef DEBUG_IOCTLS 107 printk("TCSETS, %08lx) ", arg); 108#endif 109 if (!access_ok(VERIFY_READ, it, sizeof(*it))) { 110 error = -EFAULT; 111 break; 112 } 113 old_fs = get_fs(); set_fs(get_ds()); 114 error = sys_ioctl(fd, TCGETS, (unsigned long) &kt); 115 set_fs(old_fs); 116 if (error) 117 break; 118 119 error = __get_user(kt.c_iflag, &it->c_iflag); 120 error |= __get_user(kt.c_oflag, &it->c_oflag); 121 error |= __get_user(kt.c_cflag, &it->c_cflag); 122 error |= __get_user(kt.c_lflag, &it->c_lflag); 123 124 for (i = 0; i < NCCS; i++) 125 error |= __get_user(kt.c_cc[i], &it->c_cc[i]); 126 127 if (error) 128 break; 129 old_fs = get_fs(); set_fs(get_ds()); 130 error = sys_ioctl(fd, TCSETS, (unsigned long) &kt); 131 set_fs(old_fs); 132 break; 133 } 134 135 case 0x0000540f: 136#ifdef DEBUG_IOCTLS 137 printk("TCSETSW, %08lx) ", arg); 138#endif 139 error = sys_ioctl(fd, TCSETSW, arg); 140 break; 141 142 case 0x00005471: 143#ifdef DEBUG_IOCTLS 144 printk("TIOCNOTTY, %08lx) ", arg); 145#endif 146 error = sys_ioctl(fd, TIOCNOTTY, arg); 147 break; 148 149 case 0x00007416: 150#ifdef DEBUG_IOCTLS 151 printk("TIOCGSID, %08lx) ", arg); 152#endif 153 tp = get_tty(fd); 154 if(!tp) { 155 error = -EINVAL; 156 break; 157 } 158 rtp = get_real_tty(tp); 159#ifdef DEBUG_IOCTLS 160 printk("rtp->session=%d ", rtp->session); 161#endif 162 error = put_user(rtp->session, (unsigned long __user *) arg); 163 break; 164 165 case 0x746e: 166 /* TIOCSTART, same effect as hitting ^Q */ 167#ifdef DEBUG_IOCTLS 168 printk("TIOCSTART, %08lx) ", arg); 169#endif 170 tp = get_tty(fd); 171 if(!tp) { 172 error = -EINVAL; 173 break; 174 } 175 rtp = get_real_tty(tp); 176 start_tty(rtp); 177 break; 178 179 case 0x20006968: 180#ifdef DEBUG_IOCTLS 181 printk("SIOCGETLABEL, %08lx) ", arg); 182#endif 183 error = -ENOPKG; 184 break; 185 186 case 0x40047477: 187#ifdef DEBUG_IOCTLS 188 printk("TIOCGPGRP, %08lx) ", arg); 189#endif 190 error = sys_ioctl(fd, TIOCGPGRP, arg); 191#ifdef DEBUG_IOCTLS 192 printk("arg=%d ", *(int *)arg); 193#endif 194 break; 195 196 case 0x40087468: 197#ifdef DEBUG_IOCTLS 198 printk("TIOCGWINSZ, %08lx) ", arg); 199#endif 200 error = sys_ioctl(fd, TIOCGWINSZ, arg); 201 break; 202 203 case 0x8004667e: 204 error = sys_ioctl(fd, FIONBIO, arg); 205 break; 206 207 case 0x80047476: 208 error = sys_ioctl(fd, TIOCSPGRP, arg); 209 break; 210 211 case 0x8020690c: 212 error = sys_ioctl(fd, SIOCSIFADDR, arg); 213 break; 214 215 case 0x80206910: 216 error = sys_ioctl(fd, SIOCSIFFLAGS, arg); 217 break; 218 219 case 0xc0206911: 220 error = sys_ioctl(fd, SIOCGIFFLAGS, arg); 221 break; 222 223 case 0xc020691b: 224 error = sys_ioctl(fd, SIOCGIFMETRIC, arg); 225 break; 226 227 default: { 228#ifdef DEBUG_MISSING_IOCTL 229 char *msg = "Unimplemented IOCTL cmd tell linux-mips@linux-mips.org\n"; 230 231#ifdef DEBUG_IOCTLS 232 printk("UNIMP_IOCTL, %08lx)\n", arg); 233#endif 234 old_fs = get_fs(); set_fs(get_ds()); 235 sys_write(2, msg, strlen(msg)); 236 set_fs(old_fs); 237 printk("[%s:%d] Does unimplemented IRIX ioctl cmd %08lx\n", 238 current->comm, current->pid, cmd); 239 do_exit(255); 240#else 241 error = sys_ioctl(fd, cmd, arg); 242#endif 243 } 244 245 }; 246#ifdef DEBUG_IOCTLS 247 printk("error=%d\n", error); 248#endif 249 return error; 250}