socksys.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /* $Id: socksys.c,v 1.21 2002/02/08 03:57:14 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. /*
  9. * Dave, _please_ give me specifications on this fscking mess so that I
  10. * could at least get it into the state when it wouldn't screw the rest of
  11. * the kernel over. socksys.c and timod.c _stink_ and we are not talking
  12. * H2S here, it's isopropilmercaptan in concentrations way over LD50. -- AV
  13. */
  14. #include <linux/types.h>
  15. #include <linux/kernel.h>
  16. #include <linux/sched.h>
  17. #include <linux/smp.h>
  18. #include <linux/smp_lock.h>
  19. #include <linux/ioctl.h>
  20. #include <linux/fs.h>
  21. #include <linux/file.h>
  22. #include <linux/init.h>
  23. #include <linux/poll.h>
  24. #include <linux/slab.h>
  25. #include <linux/syscalls.h>
  26. #include <linux/in.h>
  27. #include <net/sock.h>
  28. #include <asm/uaccess.h>
  29. #include <asm/termios.h>
  30. #include "conv.h"
  31. #include "socksys.h"
  32. static int af_inet_protocols[] = {
  33. IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP,
  34. IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
  35. 0, 0, 0, 0, 0, 0,
  36. };
  37. #ifndef DEBUG_SOLARIS_KMALLOC
  38. #define mykmalloc kmalloc
  39. #define mykfree kfree
  40. #else
  41. extern void * mykmalloc(size_t s, gfp_t gfp);
  42. extern void mykfree(void *);
  43. #endif
  44. static unsigned int (*sock_poll)(struct file *, poll_table *);
  45. static struct file_operations socksys_file_ops = {
  46. /* Currently empty */
  47. };
  48. static int socksys_open(struct inode * inode, struct file * filp)
  49. {
  50. int family, type, protocol, fd;
  51. struct dentry *dentry;
  52. int (*sys_socket)(int,int,int) =
  53. (int (*)(int,int,int))SUNOS(97);
  54. struct sol_socket_struct * sock;
  55. family = ((iminor(inode) >> 4) & 0xf);
  56. switch (family) {
  57. case AF_UNIX:
  58. type = SOCK_STREAM;
  59. protocol = 0;
  60. break;
  61. case AF_INET:
  62. protocol = af_inet_protocols[iminor(inode) & 0xf];
  63. switch (protocol) {
  64. case IPPROTO_TCP: type = SOCK_STREAM; break;
  65. case IPPROTO_UDP: type = SOCK_DGRAM; break;
  66. default: type = SOCK_RAW; break;
  67. }
  68. break;
  69. default:
  70. type = SOCK_RAW;
  71. protocol = 0;
  72. break;
  73. }
  74. fd = sys_socket(family, type, protocol);
  75. if (fd < 0)
  76. return fd;
  77. /*
  78. * N.B. The following operations are not legal!
  79. *
  80. * No shit. WTF is it supposed to do, anyway?
  81. *
  82. * Try instead:
  83. * d_delete(filp->f_path.dentry), then d_instantiate with sock inode
  84. */
  85. dentry = filp->f_path.dentry;
  86. filp->f_path.dentry = dget(fcheck(fd)->f_path.dentry);
  87. filp->f_path.dentry->d_inode->i_rdev = inode->i_rdev;
  88. filp->f_path.dentry->d_inode->i_flock = inode->i_flock;
  89. SOCKET_I(filp->f_path.dentry->d_inode)->file = filp;
  90. filp->f_op = &socksys_file_ops;
  91. sock = (struct sol_socket_struct*)
  92. mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL);
  93. if (!sock) return -ENOMEM;
  94. SOLDD(("sock=%016lx(%016lx)\n", sock, filp));
  95. sock->magic = SOLARIS_SOCKET_MAGIC;
  96. sock->modcount = 0;
  97. sock->state = TS_UNBND;
  98. sock->offset = 0;
  99. sock->pfirst = sock->plast = NULL;
  100. filp->private_data = sock;
  101. SOLDD(("filp->private_data %016lx\n", filp->private_data));
  102. sys_close(fd);
  103. dput(dentry);
  104. return 0;
  105. }
  106. static int socksys_release(struct inode * inode, struct file * filp)
  107. {
  108. struct sol_socket_struct * sock;
  109. struct T_primsg *it;
  110. /* XXX: check this */
  111. sock = (struct sol_socket_struct *)filp->private_data;
  112. SOLDD(("sock release %016lx(%016lx)\n", sock, filp));
  113. it = sock->pfirst;
  114. while (it) {
  115. struct T_primsg *next = it->next;
  116. SOLDD(("socksys_release %016lx->%016lx\n", it, next));
  117. mykfree((char*)it);
  118. it = next;
  119. }
  120. filp->private_data = NULL;
  121. SOLDD(("socksys_release %016lx\n", sock));
  122. mykfree((char*)sock);
  123. return 0;
  124. }
  125. static unsigned int socksys_poll(struct file * filp, poll_table * wait)
  126. {
  127. struct inode *ino;
  128. unsigned int mask = 0;
  129. ino=filp->f_path.dentry->d_inode;
  130. if (ino && S_ISSOCK(ino->i_mode)) {
  131. struct sol_socket_struct *sock;
  132. sock = (struct sol_socket_struct*)filp->private_data;
  133. if (sock && sock->pfirst) {
  134. mask |= POLLIN | POLLRDNORM;
  135. if (sock->pfirst->pri == MSG_HIPRI)
  136. mask |= POLLPRI;
  137. }
  138. }
  139. if (sock_poll)
  140. mask |= (*sock_poll)(filp, wait);
  141. return mask;
  142. }
  143. static struct file_operations socksys_fops = {
  144. .open = socksys_open,
  145. .release = socksys_release,
  146. };
  147. int __init init_socksys(void)
  148. {
  149. int ret;
  150. struct file * file;
  151. int (*sys_socket)(int,int,int) =
  152. (int (*)(int,int,int))SUNOS(97);
  153. int (*sys_close)(unsigned int) =
  154. (int (*)(unsigned int))SYS(close);
  155. ret = register_chrdev (30, "socksys", &socksys_fops);
  156. if (ret < 0) {
  157. printk ("Couldn't register socksys character device\n");
  158. return ret;
  159. }
  160. ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  161. if (ret < 0) {
  162. printk ("Couldn't create socket\n");
  163. return ret;
  164. }
  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 __exit cleanup_socksys(void)
  175. {
  176. if (unregister_chrdev(30, "socksys"))
  177. printk ("Couldn't unregister socksys character device\n");
  178. }