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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: timod.c,v 1.16.2.1 2001/12/18 22:15:25 davem Exp $
  2.  * timod.c: timod emulation.
  3.  *
  4.  * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
  5.  *
  6.  * Streams & timod emulation based on code
  7.  * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
  8.  *
  9.  */
  10.  
  11. #include <linux/types.h>
  12. #include <linux/kernel.h>
  13. #include <linux/sched.h>
  14. #include <linux/smp.h>
  15. #include <linux/smp_lock.h>
  16. #include <linux/ioctl.h>
  17. #include <linux/fs.h>
  18. #include <linux/file.h>
  19. #include <linux/netdevice.h>
  20. #include <linux/poll.h>
  21. #include <net/sock.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/termios.h>
  24. #include "conv.h"
  25. #include "socksys.h"
  26. extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, 
  27. unsigned long arg);
  28. extern asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd,
  29. u32 arg);
  30. asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
  31. static spinlock_t timod_pagelock = SPIN_LOCK_UNLOCKED;
  32. static char * page = NULL ;
  33. #ifndef DEBUG_SOLARIS_KMALLOC
  34. #define mykmalloc kmalloc
  35. #define mykfree kfree
  36. #else
  37. void * mykmalloc(size_t s, int gfp)
  38. {
  39. static char * page;
  40. static size_t free = 0;
  41. void * r;
  42. s = ((s + 63) & ~63);
  43. if( s > PAGE_SIZE ) {
  44. SOLD("too big size, calling real kmalloc");
  45. return kmalloc(s, gfp);
  46. }
  47. if( s > free ) {
  48. /* we are wasting memory, but we don't care */
  49. page = (char *)__get_free_page(gfp);
  50. free = PAGE_SIZE;
  51. }
  52. r = page;
  53. page += s;
  54. free -= s;
  55. return r;
  56. }
  57. void mykfree(void *p)
  58. {
  59. }
  60. #endif
  61. #ifndef DEBUG_SOLARIS
  62. #define BUF_SIZE PAGE_SIZE
  63. #define PUT_MAGIC(a,m)
  64. #define SCHECK_MAGIC(a,m)
  65. #define BUF_OFFSET 0
  66. #define MKCTL_TRAILER 0
  67. #else
  68. #define BUF_SIZE (PAGE_SIZE-2*sizeof(u64))
  69. #define BUFPAGE_MAGIC 0xBADC0DEDDEADBABEL
  70. #define MKCTL_MAGIC 0xDEADBABEBADC0DEDL
  71. #define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0)
  72. #define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!n",
  73. __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0)
  74. #define BUF_OFFSET sizeof(u64)
  75. #define MKCTL_TRAILER sizeof(u64)
  76. #endif
  77. static char *getpage( void )
  78. {
  79. char *r;
  80. SOLD("getting page");
  81. spin_lock(&timod_pagelock);
  82. if (page) {
  83. r = page;
  84. page = NULL;
  85. spin_unlock(&timod_pagelock);
  86. SOLD("got cached");
  87. return r + BUF_OFFSET;
  88. }
  89. spin_unlock(&timod_pagelock);
  90. SOLD("getting new");
  91. r = (char *)__get_free_page(GFP_KERNEL);
  92. PUT_MAGIC(r,BUFPAGE_MAGIC);
  93. PUT_MAGIC(r+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
  94. return r + BUF_OFFSET;
  95. }
  96. static void putpage(char *p)
  97. {
  98. SOLD("putting page");
  99. p = p - BUF_OFFSET;
  100. SCHECK_MAGIC(p,BUFPAGE_MAGIC);
  101. SCHECK_MAGIC(p+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
  102. spin_lock(&timod_pagelock);
  103. if (page) {
  104. spin_unlock(&timod_pagelock);
  105. free_page((unsigned long)p);
  106. SOLD("freed it");
  107. } else {
  108. page = p;
  109. spin_unlock(&timod_pagelock);
  110. SOLD("cached it");
  111. }
  112. }
  113. static struct T_primsg *timod_mkctl(int size)
  114. {
  115. struct T_primsg *it;
  116. SOLD("creating primsg");
  117. it = (struct T_primsg *)mykmalloc(size+sizeof(*it)-sizeof(s32)+2*MKCTL_TRAILER, GFP_KERNEL);
  118. if (it) {
  119. SOLD("got it");
  120. it->pri = MSG_HIPRI;
  121. it->length = size;
  122. PUT_MAGIC((char*)((u64)(((char *)&it->type)+size+7)&~7),MKCTL_MAGIC);
  123. }
  124. return it;
  125. }
  126. static void timod_wake_socket(unsigned int fd)
  127. {
  128. struct socket *sock;
  129. SOLD("wakeing socket");
  130. sock = &current->files->fd[fd]->f_dentry->d_inode->u.socket_i;
  131. wake_up_interruptible(&sock->wait);
  132. read_lock(&sock->sk->callback_lock);
  133. if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
  134. __kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
  135. read_unlock(&sock->sk->callback_lock);
  136. SOLD("done");
  137. }
  138. static void timod_queue(unsigned int fd, struct T_primsg *it)
  139. {
  140. struct sol_socket_struct *sock;
  141. SOLD("queuing primsg");
  142. sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data;
  143. it->next = sock->pfirst;
  144. sock->pfirst = it;
  145. if (!sock->plast)
  146. sock->plast = it;
  147. timod_wake_socket(fd);
  148. SOLD("done");
  149. }
  150. static void timod_queue_end(unsigned int fd, struct T_primsg *it)
  151. {
  152. struct sol_socket_struct *sock;
  153. SOLD("queuing primsg at end");
  154. sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data;
  155. it->next = NULL;
  156. if (sock->plast)
  157. sock->plast->next = it;
  158. else
  159. sock->pfirst = it;
  160. sock->plast = it;
  161. SOLD("done");
  162. }
  163. static void timod_error(unsigned int fd, int prim, int terr, int uerr)
  164. {
  165. struct T_primsg *it;
  166. SOLD("making error");
  167. it = timod_mkctl(sizeof(struct T_error_ack));
  168. if (it) {
  169. struct T_error_ack *err = (struct T_error_ack *)&it->type;
  170. SOLD("got it");
  171. err->PRIM_type = T_ERROR_ACK;
  172. err->ERROR_prim = prim;
  173. err->TLI_error = terr;
  174. err->UNIX_error = uerr; /* FIXME: convert this */
  175. timod_queue(fd, it);
  176. }
  177. SOLD("done");
  178. }
  179. static void timod_ok(unsigned int fd, int prim)
  180. {
  181. struct T_primsg *it;
  182. struct T_ok_ack *ok;
  183. SOLD("creating ok ack");
  184. it = timod_mkctl(sizeof(*ok));
  185. if (it) {
  186. SOLD("got it");
  187. ok = (struct T_ok_ack *)&it->type;
  188. ok->PRIM_type = T_OK_ACK;
  189. ok->CORRECT_prim = prim;
  190. timod_queue(fd, it);
  191. }
  192. SOLD("done");
  193. }
  194. static int timod_optmgmt(unsigned int fd, int flag, char *opt_buf, int opt_len, int do_ret)
  195. {
  196. int error, failed;
  197. int ret_space, ret_len;
  198. long args[5];
  199. char *ret_pos,*ret_buf;
  200. int (*sys_socketcall)(int, unsigned long *) =
  201. (int (*)(int, unsigned long *))SYS(socketcall);
  202. mm_segment_t old_fs = get_fs();
  203. SOLD("entry");
  204. SOLDD(("fd %u flg %u buf %p len %u doret %u",fd,flag,opt_buf,opt_len,do_ret));
  205. if (!do_ret && (!opt_buf || opt_len <= 0))
  206. return 0;
  207. SOLD("getting page");
  208. ret_pos = ret_buf = getpage();
  209. ret_space = BUF_SIZE;
  210. ret_len = 0;
  211. error = failed = 0;
  212. SOLD("looping");
  213. while(opt_len >= sizeof(struct opthdr)) {
  214. struct opthdr *opt;
  215. int orig_opt_len; 
  216. SOLD("loop start");
  217. opt = (struct opthdr *)ret_pos; 
  218. if (ret_space < sizeof(struct opthdr)) {
  219. failed = TSYSERR;
  220. break;
  221. }
  222. SOLD("getting opthdr");
  223. if (copy_from_user(opt, opt_buf, sizeof(struct opthdr)) ||
  224. opt->len > opt_len) {
  225. failed = TBADOPT;
  226. break;
  227. }
  228. SOLD("got opthdr");
  229. if (flag == T_NEGOTIATE) {
  230. char *buf;
  231. SOLD("handling T_NEGOTIATE");
  232. buf = ret_pos + sizeof(struct opthdr);
  233. if (ret_space < opt->len + sizeof(struct opthdr) ||
  234. copy_from_user(buf, opt_buf+sizeof(struct opthdr), opt->len)) {
  235. failed = TSYSERR;
  236. break;
  237. }
  238. SOLD("got optdata");
  239. args[0] = fd;
  240. args[1] = opt->level;
  241. args[2] = opt->name;
  242. args[3] = (long)buf;
  243. args[4] = opt->len;
  244. SOLD("calling SETSOCKOPT");
  245. set_fs(KERNEL_DS);
  246. error = sys_socketcall(SYS_SETSOCKOPT, args);
  247. set_fs(old_fs);
  248. if (error) {
  249. failed = TBADOPT;
  250. break;
  251. }
  252. SOLD("SETSOCKOPT ok");
  253. }
  254. orig_opt_len = opt->len;
  255. opt->len = ret_space - sizeof(struct opthdr);
  256. if (opt->len < 0) {
  257. failed = TSYSERR;
  258. break;
  259. }
  260. args[0] = fd;
  261. args[1] = opt->level;
  262. args[2] = opt->name;
  263. args[3] = (long)(ret_pos+sizeof(struct opthdr));
  264. args[4] = (long)&opt->len;
  265. SOLD("calling GETSOCKOPT");
  266. set_fs(KERNEL_DS);
  267. error = sys_socketcall(SYS_GETSOCKOPT, args);
  268. set_fs(old_fs);;
  269. if (error) {
  270. failed = TBADOPT;
  271. break;
  272. }
  273. SOLD("GETSOCKOPT ok");
  274. ret_space -= sizeof(struct opthdr) + opt->len;
  275. ret_len += sizeof(struct opthdr) + opt->len;
  276. ret_pos += sizeof(struct opthdr) + opt->len;
  277. opt_len -= sizeof(struct opthdr) + orig_opt_len;
  278. opt_buf += sizeof(struct opthdr) + orig_opt_len;
  279. SOLD("loop end");
  280. }
  281. SOLD("loop done");
  282. if (do_ret) {
  283. SOLD("generating ret msg");
  284. if (failed)
  285. timod_error(fd, T_OPTMGMT_REQ, failed, -error);
  286. else {
  287. struct T_primsg *it;
  288. it = timod_mkctl(sizeof(struct T_optmgmt_ack) + ret_len);
  289. if (it) {
  290. struct T_optmgmt_ack *ack =
  291. (struct T_optmgmt_ack *)&it->type;
  292. SOLD("got primsg");
  293. ack->PRIM_type = T_OPTMGMT_ACK;
  294. ack->OPT_length = ret_len;
  295. ack->OPT_offset = sizeof(struct T_optmgmt_ack);
  296. ack->MGMT_flags = (failed ? T_FAILURE : flag);
  297. memcpy(((char*)ack)+sizeof(struct T_optmgmt_ack),
  298. ret_buf, ret_len);
  299. timod_queue(fd, it);
  300. }
  301. }
  302. }
  303. SOLDD(("put_page %pn", ret_buf));
  304. putpage(ret_buf);
  305. SOLD("done");
  306. return 0;
  307. }
  308. int timod_putmsg(unsigned int fd, char *ctl_buf, int ctl_len,
  309. char *data_buf, int data_len, int flags)
  310. {
  311. int ret, error, terror;
  312. char *buf;
  313. struct file *filp;
  314. struct inode *ino;
  315. struct sol_socket_struct *sock;
  316. mm_segment_t old_fs = get_fs();
  317. long args[6];
  318. int (*sys_socketcall)(int, unsigned long *) =
  319. (int (*)(int, unsigned long *))SYS(socketcall);
  320. int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int) =
  321. (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int))SYS(sendto);
  322. filp = current->files->fd[fd];
  323. ino = filp->f_dentry->d_inode;
  324. sock = (struct sol_socket_struct *)filp->private_data;
  325. SOLD("entry");
  326. if (get_user(ret, (int *)A(ctl_buf)))
  327. return -EFAULT;
  328. switch (ret) {
  329. case T_BIND_REQ:
  330. {
  331. struct T_bind_req req;
  332. SOLDD(("bind %016lx(%016lx)n", sock, filp));
  333. SOLD("T_BIND_REQ");
  334. if (sock->state != TS_UNBND) {
  335. timod_error(fd, T_BIND_REQ, TOUTSTATE, 0);
  336. return 0;
  337. }
  338. SOLD("state ok");
  339. if (copy_from_user(&req, ctl_buf, sizeof(req))) {
  340. timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
  341. return 0;
  342. }
  343. SOLD("got ctl req");
  344. if (req.ADDR_offset && req.ADDR_length) {
  345. if (req.ADDR_length > BUF_SIZE) {
  346. timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
  347. return 0;
  348. }
  349. SOLD("req size ok");
  350. buf = getpage();
  351. if (copy_from_user(buf, ctl_buf + req.ADDR_offset, req.ADDR_length)) {
  352. timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
  353. putpage(buf);
  354. return 0;
  355. }
  356. SOLD("got ctl data");
  357. args[0] = fd;
  358. args[1] = (long)buf;
  359. args[2] = req.ADDR_length;
  360. SOLD("calling BIND");
  361. set_fs(KERNEL_DS);
  362. error = sys_socketcall(SYS_BIND, args);
  363. set_fs(old_fs);
  364. putpage(buf);
  365. SOLD("BIND returned");
  366. } else 
  367. error = 0;
  368. if (!error) {
  369. struct T_primsg *it;
  370. if (req.CONIND_number) {
  371.    args[0] = fd;
  372.    args[1] = req.CONIND_number;
  373.    SOLD("calling LISTEN");
  374.    set_fs(KERNEL_DS);
  375.    error = sys_socketcall(SYS_LISTEN, args);
  376.    set_fs(old_fs);
  377.    SOLD("LISTEN done");
  378.    }
  379. it = timod_mkctl(sizeof(struct T_bind_ack)+sizeof(struct sockaddr));
  380. if (it) {
  381. struct T_bind_ack *ack;
  382. ack = (struct T_bind_ack *)&it->type;
  383. ack->PRIM_type = T_BIND_ACK;
  384. ack->ADDR_offset = sizeof(*ack);
  385. ack->ADDR_length = sizeof(struct sockaddr);
  386. ack->CONIND_number = req.CONIND_number;
  387. args[0] = fd;
  388. args[1] = (long)(ack+sizeof(*ack));
  389. args[2] = (long)&ack->ADDR_length;
  390. set_fs(KERNEL_DS);
  391. sys_socketcall(SYS_GETSOCKNAME,args);
  392. set_fs(old_fs);
  393. sock->state = TS_IDLE;
  394. timod_ok(fd, T_BIND_REQ);
  395. timod_queue_end(fd, it);
  396. SOLD("BIND done");
  397. return 0;
  398. }
  399. }
  400. SOLD("some error");
  401. switch (error) {
  402. case -EINVAL:
  403. terror = TOUTSTATE;
  404. error = 0;
  405. break;
  406. case -EACCES:
  407. terror = TACCES;
  408. error = 0;
  409. break;
  410. case -EADDRNOTAVAIL:
  411. case -EADDRINUSE:
  412. terror = TNOADDR;
  413. error = 0;
  414. break;
  415. default:
  416. terror = TSYSERR;
  417. break;
  418. }
  419. timod_error(fd, T_BIND_REQ, terror, -error);
  420. SOLD("BIND done");
  421. return 0;
  422. }
  423. case T_CONN_REQ:
  424. {
  425. struct T_conn_req req;
  426. unsigned short oldflags;
  427. struct T_primsg *it;
  428. SOLD("T_CONN_REQ");
  429. if (sock->state != TS_UNBND && sock->state != TS_IDLE) {
  430. timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
  431. return 0;
  432. }
  433. SOLD("state ok");
  434. if (copy_from_user(&req, ctl_buf, sizeof(req))) {
  435. timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
  436. return 0;
  437. }
  438. SOLD("got ctl req");
  439. if (ctl_len > BUF_SIZE) {
  440. timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
  441. return 0;
  442. }
  443. SOLD("req size ok");
  444. buf = getpage();
  445. if (copy_from_user(buf, ctl_buf, ctl_len)) {
  446. timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
  447. putpage(buf);
  448. return 0;
  449. }
  450. #ifdef DEBUG_SOLARIS
  451. {
  452. char * ptr = buf;
  453. int len = ctl_len;
  454. printk("returned data (%d bytes): ",len);
  455. while( len-- ) {
  456. if (!(len & 7))
  457. printk(" ");
  458. printk("%02x",(unsigned char)*ptr++);
  459. }
  460. printk("n");
  461. }
  462. #endif
  463. SOLD("got ctl data");
  464. args[0] = fd;
  465. args[1] = (long)buf+req.DEST_offset;
  466. args[2] = req.DEST_length;
  467. oldflags = filp->f_flags;
  468. filp->f_flags &= ~O_NONBLOCK;
  469. SOLD("calling CONNECT");
  470. set_fs(KERNEL_DS);
  471. error = sys_socketcall(SYS_CONNECT, args);
  472. set_fs(old_fs);
  473. filp->f_flags = oldflags;
  474. SOLD("CONNECT done");
  475. if (!error) {
  476. struct T_conn_con *con;
  477. SOLD("no error");
  478. it = timod_mkctl(ctl_len);
  479. if (!it) {
  480. putpage(buf);
  481. return -ENOMEM;
  482. }
  483. con = (struct T_conn_con *)&it->type;
  484. #ifdef DEBUG_SOLARIS
  485. {
  486. char * ptr = buf;
  487. int len = ctl_len;
  488. printk("returned data (%d bytes): ",len);
  489. while( len-- ) {
  490. if (!(len & 7))
  491. printk(" ");
  492. printk("%02x",(unsigned char)*ptr++);
  493. }
  494. printk("n");
  495. }
  496. #endif
  497. memcpy(con, buf, ctl_len);
  498. SOLD("copied ctl_buf");
  499. con->PRIM_type = T_CONN_CON;
  500. sock->state = TS_DATA_XFER;
  501. } else {
  502. struct T_discon_ind *dis;
  503. SOLD("some error");
  504. it = timod_mkctl(sizeof(*dis));
  505. if (!it) {
  506. putpage(buf);
  507. return -ENOMEM;
  508. }
  509. SOLD("got primsg");
  510. dis = (struct T_discon_ind *)&it->type;
  511. dis->PRIM_type = T_DISCON_IND;
  512. dis->DISCON_reason = -error; /* FIXME: convert this as in iABI_errors() */
  513. dis->SEQ_number = 0;
  514. }
  515. putpage(buf);
  516. timod_ok(fd, T_CONN_REQ);
  517. it->pri = 0;
  518. timod_queue_end(fd, it);
  519. SOLD("CONNECT done");
  520. return 0;
  521. }
  522. case T_OPTMGMT_REQ:
  523. {
  524. struct T_optmgmt_req req;
  525. SOLD("OPTMGMT_REQ");
  526. if (copy_from_user(&req, ctl_buf, sizeof(req)))
  527. return -EFAULT;
  528. SOLD("got req");
  529. return timod_optmgmt(fd, req.MGMT_flags,
  530. req.OPT_offset > 0 ? ctl_buf + req.OPT_offset : NULL,
  531. req.OPT_length, 1);
  532. }
  533. case T_UNITDATA_REQ:
  534. {
  535. struct T_unitdata_req req;
  536. int err;
  537. SOLD("T_UNITDATA_REQ");
  538. if (sock->state != TS_IDLE && sock->state != TS_DATA_XFER) {
  539. timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
  540. return 0;
  541. }
  542. SOLD("state ok");
  543. if (copy_from_user(&req, ctl_buf, sizeof(req))) {
  544. timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
  545. return 0;
  546. }
  547. SOLD("got ctl req");
  548. #ifdef DEBUG_SOLARIS
  549. {
  550. char * ptr = ctl_buf+req.DEST_offset;
  551. int len = req.DEST_length;
  552. printk("socket address (%d bytes): ",len);
  553. while( len-- ) {
  554. char c;
  555. if (get_user(c,ptr))
  556. printk("??");
  557. else
  558. printk("%02x",(unsigned char)c);
  559. ptr++;
  560. }
  561. printk("n");
  562. }
  563. #endif
  564. err = sys_sendto(fd, data_buf, data_len, 0, req.DEST_length > 0 ? (struct sockaddr*)(ctl_buf+req.DEST_offset) : NULL, req.DEST_length);
  565. if (err == data_len)
  566. return 0;
  567. if(err >= 0) {
  568. printk("timod: sendto failed to send all the datan");
  569. return 0;
  570. }
  571. timod_error(fd, T_CONN_REQ, TSYSERR, -err);
  572. return 0;
  573. }
  574. default:
  575. printk(KERN_INFO "timod_putmsg: unsupported command %u.n", ret);
  576. break;
  577. }
  578. return -EINVAL;
  579. }
  580. int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len,
  581. char *data_buf, int data_maxlen, s32 *data_len, int *flags_p)
  582. {
  583. int error;
  584. int oldflags;
  585. struct file *filp;
  586. struct inode *ino;
  587. struct sol_socket_struct *sock;
  588. struct T_unitdata_ind udi;
  589. mm_segment_t old_fs = get_fs();
  590. long args[6];
  591. char *tmpbuf;
  592. int tmplen;
  593. int (*sys_socketcall)(int, unsigned long *) =
  594. (int (*)(int, unsigned long *))SYS(socketcall);
  595. int (*sys_recvfrom)(int, void *, size_t, unsigned, struct sockaddr *, int *);
  596. SOLD("entry");
  597. SOLDD(("%u %p %d %p %p %d %p %dn", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p));
  598. filp = current->files->fd[fd];
  599. ino = filp->f_dentry->d_inode;
  600. sock = (struct sol_socket_struct *)filp->private_data;
  601. SOLDD(("%p %pn", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
  602. if ( ctl_maxlen > 0 && !sock->pfirst && ino->u.socket_i.type == SOCK_STREAM
  603. && sock->state == TS_IDLE) {
  604. SOLD("calling LISTEN");
  605. args[0] = fd;
  606. args[1] = -1;
  607. set_fs(KERNEL_DS);
  608. sys_socketcall(SYS_LISTEN, args);
  609. set_fs(old_fs);
  610. SOLD("LISTEN done");
  611. }
  612. if (!(filp->f_flags & O_NONBLOCK)) {
  613. poll_table wait_table, *wait;
  614. poll_initwait(&wait_table);
  615. wait = &wait_table;
  616. for(;;) {
  617. SOLD("loop");
  618. set_current_state(TASK_INTERRUPTIBLE);
  619. /* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ 
  620. /* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ 
  621. /* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */ 
  622. /* ( l>=0 && ( l<0 || ( pfirst && ! (flags == HIPRI && pri != HIPRI) ) ) ) */ 
  623. /* ( l>=0 && ( l<0 || ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) ) */ 
  624. /* ( l>=0 && ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) */ 
  625. if (ctl_maxlen >= 0 && sock->pfirst && (*flags_p != MSG_HIPRI || sock->pfirst->pri == MSG_HIPRI))
  626. break;
  627. SOLD("cond 1 passed");
  628. if (
  629. #if 1
  630. *flags_p != MSG_HIPRI &&
  631. #endif
  632. ((filp->f_op->poll(filp, wait) & POLLIN) ||
  633. (filp->f_op->poll(filp, NULL) & POLLIN) ||
  634. signal_pending(current))
  635. ) {
  636. break;
  637. }
  638. if( *flags_p == MSG_HIPRI ) {
  639. SOLD("avoiding lockup");
  640. break ;
  641. }
  642. if(wait_table.error) {
  643. SOLD("wait-table error");
  644. poll_freewait(&wait_table);
  645. return wait_table.error;
  646. }
  647. SOLD("scheduling");
  648. schedule();
  649. }
  650. SOLD("loop done");
  651. current->state = TASK_RUNNING;
  652. poll_freewait(&wait_table);
  653. if (signal_pending(current)) {
  654. SOLD("signal pending");
  655. return -EINTR;
  656. }
  657. }
  658. if (ctl_maxlen >= 0 && sock->pfirst) {
  659. struct T_primsg *it = sock->pfirst;
  660. int l = min_t(int, ctl_maxlen, it->length);
  661. SCHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC);
  662. SOLD("purting ctl data");
  663. if(copy_to_user(ctl_buf,
  664. (char*)&it->type + sock->offset, l))
  665. return -EFAULT;
  666. SOLD("pur it");
  667. if(put_user(l, ctl_len))
  668. return -EFAULT;
  669. SOLD("set ctl_len");
  670. *flags_p = it->pri;
  671. it->length -= l;
  672. if (it->length) {
  673. SOLD("more ctl");
  674. sock->offset += l;
  675. return MORECTL;
  676. } else {
  677. SOLD("removing message");
  678. sock->pfirst = it->next;
  679. if (!sock->pfirst)
  680. sock->plast = NULL;
  681. SOLDD(("getmsg kfree %016lx->%016lxn", it, sock->pfirst));
  682. mykfree(it);
  683. sock->offset = 0;
  684. SOLD("ctl done");
  685. return 0;
  686. }
  687. }
  688. *flags_p = 0;
  689. if (ctl_maxlen >= 0) {
  690. SOLD("ACCEPT perhaps?");
  691. if (ino->u.socket_i.type == SOCK_STREAM && sock->state == TS_IDLE) {
  692. struct T_conn_ind ind;
  693. char *buf = getpage();
  694. int len = BUF_SIZE;
  695. SOLD("trying ACCEPT");
  696. if (put_user(ctl_maxlen - sizeof(ind), ctl_len))
  697. return -EFAULT;
  698. args[0] = fd;
  699. args[1] = (long)buf;
  700. args[2] = (long)&len;
  701. oldflags = filp->f_flags;
  702. filp->f_flags |= O_NONBLOCK;
  703. SOLD("calling ACCEPT");
  704. set_fs(KERNEL_DS);
  705. error = sys_socketcall(SYS_ACCEPT, args);
  706. set_fs(old_fs);
  707. filp->f_flags = oldflags;
  708. if (error < 0) {
  709. SOLD("some error");
  710. putpage(buf);
  711. return error;
  712. }
  713. if (error) {
  714. SOLD("connect");
  715. putpage(buf);
  716. if (sizeof(ind) > ctl_maxlen) {
  717. SOLD("generating CONN_IND");
  718. ind.PRIM_type = T_CONN_IND;
  719. ind.SRC_length = len;
  720. ind.SRC_offset = sizeof(ind);
  721. ind.OPT_length = ind.OPT_offset = 0;
  722. ind.SEQ_number = error;
  723. if(copy_to_user(ctl_buf, &ind, sizeof(ind))||
  724.    put_user(sizeof(ind)+ind.SRC_length,ctl_len))
  725. return -EFAULT;
  726. SOLD("CONN_IND created");
  727. }
  728. if (data_maxlen >= 0)
  729. put_user(0, data_len);
  730. SOLD("CONN_IND done");
  731. return 0;
  732. }
  733. if (len>ctl_maxlen) {
  734. SOLD("data don't fit");
  735. putpage(buf);
  736. return -EFAULT; /* XXX - is this ok ? */
  737. }
  738. if(copy_to_user(ctl_buf,buf,len) || put_user(len,ctl_len)){
  739. SOLD("can't copy data");
  740. putpage(buf);
  741. return -EFAULT;
  742. }
  743. SOLD("ACCEPT done");
  744. putpage(buf);
  745. }
  746. }
  747. SOLD("checking data req");
  748. if (data_maxlen <= 0) {
  749. if (data_maxlen == 0)
  750. put_user(0, data_len);
  751. if (ctl_maxlen >= 0)
  752. put_user(0, ctl_len);
  753. return -EAGAIN;
  754. }
  755. SOLD("wants data");
  756. if (ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
  757. SOLD("udi fits");
  758. tmpbuf = ctl_buf + sizeof(udi);
  759. tmplen = ctl_maxlen - sizeof(udi);
  760. } else {
  761. SOLD("udi does not fit");
  762. tmpbuf = NULL;
  763. tmplen = 0;
  764. }
  765. if (put_user(tmplen, ctl_len))
  766. return -EFAULT;
  767. SOLD("set ctl_len");
  768. oldflags = filp->f_flags;
  769. filp->f_flags |= O_NONBLOCK;
  770. SOLD("calling recvfrom");
  771. sys_recvfrom = (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(recvfrom);
  772. error = sys_recvfrom(fd, data_buf, data_maxlen, 0, (struct sockaddr*)tmpbuf, ctl_len);
  773. filp->f_flags = oldflags;
  774. if (error < 0)
  775. return error;
  776. SOLD("error >= 0" ) ;
  777. if (error && ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
  778. SOLD("generating udi");
  779. udi.PRIM_type = T_UNITDATA_IND;
  780. get_user(udi.SRC_length, ctl_len);
  781. udi.SRC_offset = sizeof(udi);
  782. udi.OPT_length = udi.OPT_offset = 0;
  783. copy_to_user(ctl_buf, &udi, sizeof(udi));
  784. put_user(sizeof(udi)+udi.SRC_length, ctl_len);
  785. SOLD("udi done");
  786. } else
  787. put_user(0, ctl_len);
  788. put_user(error, data_len);
  789. SOLD("done");
  790. return 0;
  791. }
  792. asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
  793. {
  794. struct file *filp;
  795. struct inode *ino;
  796. struct strbuf *ctlptr, *datptr;
  797. struct strbuf ctl, dat;
  798. int *flgptr;
  799. int flags;
  800. int error = -EBADF;
  801. SOLD("entry");
  802. lock_kernel();
  803. if(fd >= NR_OPEN) goto out;
  804. filp = current->files->fd[fd];
  805. if(!filp) goto out;
  806. ino = filp->f_dentry->d_inode;
  807. if (!ino) goto out;
  808. if (!ino->i_sock)
  809. goto out;
  810. ctlptr = (struct strbuf *)A(arg1);
  811. datptr = (struct strbuf *)A(arg2);
  812. flgptr = (int *)A(arg3);
  813. error = -EFAULT;
  814. if (ctlptr) {
  815. if (copy_from_user(&ctl,ctlptr,sizeof(struct strbuf)) || 
  816.     put_user(-1,&ctlptr->len))
  817. goto out;
  818. } else
  819. ctl.maxlen = -1;
  820. if (datptr) {
  821. if (copy_from_user(&dat,datptr,sizeof(struct strbuf)) || 
  822.     put_user(-1,&datptr->len))
  823. goto out;
  824. } else
  825. dat.maxlen = -1;
  826. if (get_user(flags,flgptr))
  827. goto out;
  828. switch (flags) {
  829. case 0:
  830. case MSG_HIPRI:
  831. case MSG_ANY:
  832. case MSG_BAND:
  833. break;
  834. default:
  835. error = -EINVAL;
  836. goto out;
  837. }
  838. error = timod_getmsg(fd,(char*)A(ctl.buf),ctl.maxlen,&ctlptr->len,
  839. (char*)A(dat.buf),dat.maxlen,&datptr->len,&flags);
  840. if (!error && put_user(flags,flgptr))
  841. error = -EFAULT;
  842. out:
  843. unlock_kernel();
  844. SOLD("done");
  845. return error;
  846. }
  847. asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
  848. {
  849. struct file *filp;
  850. struct inode *ino;
  851. struct strbuf *ctlptr, *datptr;
  852. struct strbuf ctl, dat;
  853. int flags = (int) arg3;
  854. int error = -EBADF;
  855. SOLD("entry");
  856. lock_kernel();
  857. if(fd >= NR_OPEN) goto out;
  858. filp = current->files->fd[fd];
  859. if(!filp) goto out;
  860. ino = filp->f_dentry->d_inode;
  861. if (!ino) goto out;
  862. if (!ino->i_sock &&
  863. (MAJOR(ino->i_rdev) != 30 || MINOR(ino->i_rdev) != 1))
  864. goto out;
  865. ctlptr = (struct strbuf *)A(arg1);
  866. datptr = (struct strbuf *)A(arg2);
  867. error = -EFAULT;
  868. if (ctlptr) {
  869. if (copy_from_user(&ctl,ctlptr,sizeof(ctl)))
  870. goto out;
  871. if (ctl.len < 0 && flags) {
  872. error = -EINVAL;
  873. goto out;
  874. }
  875. } else {
  876. ctl.len = 0;
  877. ctl.buf = 0;
  878. }
  879. if (datptr) {
  880. if (copy_from_user(&dat,datptr,sizeof(dat)))
  881. goto out;
  882. } else {
  883. dat.len = 0;
  884. dat.buf = 0;
  885. }
  886. error = timod_putmsg(fd,(char*)A(ctl.buf),ctl.len,
  887. (char*)A(dat.buf),dat.len,flags);
  888. out:
  889. unlock_kernel();
  890. SOLD("done");
  891. return error;
  892. }