socksys.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: socksys.c,v 1.18 2001/02/13 01:16:44 davem Exp $
  2.  * socksys.c: /dev/inet/ stuff for Solaris emulation.
  3.  *
  4.  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  5.  * Copyright (C) 1997, 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
  6.  * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
  7.  */
  8. #include <linux/types.h>
  9. #include <linux/kernel.h>
  10. #include <linux/sched.h>
  11. #include <linux/smp.h>
  12. #include <linux/smp_lock.h>
  13. #include <linux/ioctl.h>
  14. #include <linux/fs.h>
  15. #include <linux/file.h>
  16. #include <linux/init.h>
  17. #include <linux/poll.h>
  18. #include <linux/slab.h>
  19. #include <linux/in.h>
  20. #include <linux/devfs_fs_kernel.h>
  21. #include <asm/uaccess.h>
  22. #include <asm/termios.h>
  23. #include "conv.h"
  24. #include "socksys.h"
  25. extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, 
  26. unsigned long arg);
  27. static int af_inet_protocols[] = {
  28. IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP,
  29. IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
  30. 0, 0, 0, 0, 0, 0,
  31. };
  32. #ifndef DEBUG_SOLARIS_KMALLOC
  33. #define mykmalloc kmalloc
  34. #define mykfree kfree
  35. #else
  36. extern void * mykmalloc(size_t s, int gfp);
  37. extern void mykfree(void *);
  38. #endif
  39. static unsigned int (*sock_poll)(struct file *, poll_table *);
  40. static struct file_operations socksys_file_ops = {
  41. /* Currently empty */
  42. };
  43. static int socksys_open(struct inode * inode, struct file * filp)
  44. {
  45. int family, type, protocol, fd;
  46. struct dentry *dentry;
  47. int (*sys_socket)(int,int,int) =
  48. (int (*)(int,int,int))SUNOS(97);
  49.         struct sol_socket_struct * sock;
  50. family = ((MINOR(inode->i_rdev) >> 4) & 0xf);
  51. switch (family) {
  52. case AF_UNIX:
  53. type = SOCK_STREAM;
  54. protocol = 0;
  55. break;
  56. case AF_INET:
  57. protocol = af_inet_protocols[MINOR(inode->i_rdev) & 0xf];
  58. switch (protocol) {
  59. case IPPROTO_TCP: type = SOCK_STREAM; break;
  60. case IPPROTO_UDP: type = SOCK_DGRAM; break;
  61. default: type = SOCK_RAW; break;
  62. }
  63. break;
  64. default:
  65. type = SOCK_RAW;
  66. protocol = 0;
  67. break;
  68. }
  69. fd = sys_socket(family, type, protocol);
  70. if (fd < 0)
  71. return fd;
  72. /*
  73.  * N.B. The following operations are not legal!
  74.  * Try instead:
  75.  * d_delete(filp->f_dentry), then d_instantiate with sock inode
  76.  */
  77. dentry = filp->f_dentry;
  78. filp->f_dentry = dget(fcheck(fd)->f_dentry);
  79. filp->f_dentry->d_inode->i_rdev = inode->i_rdev;
  80. filp->f_dentry->d_inode->i_flock = inode->i_flock;
  81. filp->f_dentry->d_inode->u.socket_i.file = filp;
  82. filp->f_op = &socksys_file_ops;
  83.         sock = (struct sol_socket_struct*) 
  84.          mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL);
  85.         if (!sock) return -ENOMEM;
  86. SOLDD(("sock=%016lx(%016lx)n", sock, filp));
  87.         sock->magic = SOLARIS_SOCKET_MAGIC;
  88.         sock->modcount = 0;
  89.         sock->state = TS_UNBND;
  90.         sock->offset = 0;
  91.         sock->pfirst = sock->plast = NULL;
  92.         filp->private_data = sock;
  93. SOLDD(("filp->private_data %016lxn", filp->private_data));
  94. sys_close(fd);
  95. dput(dentry);
  96. return 0;
  97. }
  98. static int socksys_release(struct inode * inode, struct file * filp)
  99. {
  100.         struct sol_socket_struct * sock;
  101.         struct T_primsg *it;
  102. /* XXX: check this */
  103. lock_kernel();
  104. sock = (struct sol_socket_struct *)filp->private_data;
  105. SOLDD(("sock release %016lx(%016lx)n", sock, filp));
  106. it = sock->pfirst;
  107. while (it) {
  108. struct T_primsg *next = it->next;
  109. SOLDD(("socksys_release %016lx->%016lxn", it, next));
  110. mykfree((char*)it);
  111. it = next;
  112. }
  113. filp->private_data = NULL;
  114. SOLDD(("socksys_release %016lxn", sock));
  115. mykfree((char*)sock);
  116. unlock_kernel();
  117. return 0;
  118. }
  119. static unsigned int socksys_poll(struct file * filp, poll_table * wait)
  120. {
  121. struct inode *ino;
  122. unsigned int mask = 0;
  123. ino=filp->f_dentry->d_inode;
  124. if (ino && ino->i_sock) {
  125. struct sol_socket_struct *sock;
  126. sock = (struct sol_socket_struct*)filp->private_data;
  127. if (sock && sock->pfirst) {
  128. mask |= POLLIN | POLLRDNORM;
  129. if (sock->pfirst->pri == MSG_HIPRI)
  130. mask |= POLLPRI;
  131. }
  132. }
  133. if (sock_poll)
  134. mask |= (*sock_poll)(filp, wait);
  135. return mask;
  136. }
  137. static struct file_operations socksys_fops = {
  138. open: socksys_open,
  139. release: socksys_release,
  140. };
  141. static devfs_handle_t devfs_handle;
  142. int __init
  143. init_socksys(void)
  144. {
  145. int ret;
  146. struct file * file;
  147. int (*sys_socket)(int,int,int) =
  148. (int (*)(int,int,int))SUNOS(97);
  149. int (*sys_close)(unsigned int) = 
  150. (int (*)(unsigned int))SYS(close);
  151. ret = devfs_register_chrdev (30, "socksys", &socksys_fops);
  152. if (ret < 0) {
  153. printk ("Couldn't register socksys character devicen");
  154. return ret;
  155. }
  156. ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  157. if (ret < 0) {
  158. printk ("Couldn't create socketn");
  159. return ret;
  160. }
  161. devfs_handle = devfs_register (NULL, "socksys", DEVFS_FL_DEFAULT,
  162.        30, 0,
  163.        S_IFCHR | S_IRUSR | S_IWUSR,
  164.        &socksys_fops, NULL);
  165. file = fcheck(ret);
  166. /* N.B. Is this valid? Suppose the f_ops are in a module ... */
  167. socksys_file_ops = *file->f_op;
  168. sys_close(ret);
  169. sock_poll = socksys_file_ops.poll;
  170. socksys_file_ops.poll = socksys_poll;
  171. socksys_file_ops.release = socksys_release;
  172. return 0;
  173. }
  174. void
  175. cleanup_socksys(void)
  176. {
  177. if (devfs_unregister_chrdev(30, "socksys"))
  178. printk ("Couldn't unregister socksys character devicen");
  179. devfs_unregister (devfs_handle);
  180. }