socksys.c 5.2 KB

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