irixioctl.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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