fd_sysv.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:24k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* ==== fd_sysv.c ============================================================
  2.  * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *  This product includes software developed by Chris Provenzano.
  16.  * 4. The name of Chris Provenzano may not be used to endorse or promote 
  17.  *   products derived from this software without specific prior written
  18.  *   permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``AS IS'' AND
  21.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED.  IN NO EVENT SHALL CHRIS PROVENZANO BE LIABLE FOR ANY 
  24.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  25.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  26.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  28.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  30.  * SUCH DAMAGE.
  31.  *
  32.  * Description : Transforms BSD socket calls to SYSV streams.
  33.  *
  34.  *  1.00 94/11/19 proven
  35.  *      -Started coding this file.
  36.  */
  37. #ifndef lint
  38. static const char rcsid[] = "$Id$";
  39. #endif
  40. #include <config.h>
  41. #include <pthread.h>
  42. #include <fcntl.h>
  43. #include <errno.h>
  44. #if defined (HAVE_SYSCALL_PUTMSG) && defined (HAVE_SYSCALL_GETMSG) && !defined(HAVE_SYSCALL_SOCKETCALL) && !defined(HAVE_SYSCALL_SOCKET)
  45. #define HAVE_STREAMS 1
  46. #include <sys/types.h>
  47. #include <sys/uio.h>
  48. #include <sys/socket.h>
  49. #include <sys/stream.h>
  50. #include <sys/stropts.h>
  51. #include <tiuser.h>
  52. #include <sys/tihdr.h>
  53. #include <netinet/in.h>
  54. #include <sys/timod.h>
  55. #define STREAM_BUF_SIZE sizeof(union T_primitives) + sizeof(struct sockaddr)
  56. extern struct pthread_queue fd_wait_read, fd_wait_write;
  57. /* ==========================================================================
  58.  * putmsg_timedwait_basic()
  59.  */
  60. static int putmsg_timedwait_basic(int fd, struct strbuf * ctlptr, 
  61.   struct strbuf * dataptr, int flags, struct timespec * timeout)
  62. {
  63. int ret;
  64.     pthread_run->sighandled=0; /* Added by monty */
  65.     while ((ret = machdep_sys_putmsg(fd_table[fd]->fd.i,
  66.       ctlptr,  dataptr, flags)) < OK) {
  67.         if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
  68.           ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
  69.             pthread_sched_prevent();
  70.             /* queue pthread for a FDW_WAIT */
  71. SET_PF_WAIT_EVENT(pthread_run);
  72.             pthread_run->data.fd.fd = fd_table[fd]->fd.i;
  73. pthread_queue_enq(&fd_wait_write, pthread_run);
  74.             if (timeout) {
  75.                 /* get current time */
  76.                 struct timespec current_time;
  77.                 machdep_gettimeofday(&current_time);
  78.                 sleep_schedule(& current_time, timeout);
  79.                 pthread_resched_resume(PS_FDW_WAIT);
  80.                 /* We're awake */
  81.                 pthread_sched_prevent();
  82. if (sleep_cancel(pthread_run) == NOTOK) {
  83.   CLEAR_PF_DONE_EVENT(pthread_run);
  84.                     pthread_sched_resume();
  85.                     SET_ERRNO(ETIMEDOUT);
  86.                     ret = -ETIMEDOUT;
  87.                     break;
  88.                 }
  89.                 pthread_sched_resume();
  90.             } else {
  91.                 pthread_resched_resume(PS_FDW_WAIT);
  92.             }
  93. CLEAR_PF_DONE_EVENT(pthread_run);
  94.     if (pthread_run->sighandled) /* Added by monty */
  95.     { /* We where aborted */
  96.       SET_ERRNO(EINTR);
  97.       ret= -EINTR;
  98.       break;
  99.     }
  100.         } else {
  101.             SET_ERRNO(-ret);
  102.             break;
  103.         }
  104.     }
  105.     return(ret);
  106. }
  107. /* ==========================================================================
  108.  * putmsg_timedwait()
  109.  */
  110. int putmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
  111.   int flags, struct timespec * timeout)
  112. {
  113. int ret;
  114. if ((ret = fd_lock(fd, FD_WRITE, timeout)) == OK) {
  115. ret = putmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout);
  116.      fd_unlock(fd, FD_WRITE);
  117. }
  118. return(ret);
  119. }
  120. /* ==========================================================================
  121.  * putmsg()
  122.  */
  123. int putmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
  124.   int flags)
  125. {
  126. return(putmsg_timedwait(fd, ctlptr, dataptr, flags, NULL));
  127. }
  128. /* ==========================================================================
  129.  * getmsg_timedwait_basic()
  130.  */
  131. int getmsg_timedwait_basic(int fd, struct strbuf * ctlptr, 
  132.   struct strbuf * dataptr, int * flags, struct timespec * timeout)
  133. {
  134. int ret;
  135.     pthread_run->sighandled=0; /* Added by monty */
  136.     while ((ret = machdep_sys_getmsg(fd_table[fd]->fd.i,
  137.       ctlptr, dataptr, flags)) < OK) {
  138.         if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
  139.           ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) {
  140.             pthread_sched_prevent();
  141.             /* queue pthread for a FDR_WAIT */
  142. SET_PF_WAIT_EVENT(pthread_run);
  143.             pthread_run->data.fd.fd = fd_table[fd]->fd.i;
  144. pthread_queue_enq(&fd_wait_read, pthread_run);
  145.             if (timeout) {
  146.                 /* get current time */
  147.                 struct timespec current_time;
  148.                 machdep_gettimeofday(&current_time);
  149.                 sleep_schedule(& current_time, timeout);
  150.                 pthread_resched_resume(PS_FDR_WAIT);
  151.                 /* We're awake */
  152.                 pthread_sched_prevent();
  153.                 if (sleep_cancel(pthread_run) == NOTOK) {
  154. CLEAR_PF_DONE_EVENT(pthread_run);
  155.                     pthread_sched_resume();
  156.                     SET_ERRNO(ETIMEDOUT);
  157.                     ret = -ETIMEDOUT;
  158.                     break;
  159.                 }
  160.                 pthread_sched_resume();
  161.             } else {
  162.                 pthread_resched_resume(PS_FDR_WAIT);
  163.             }
  164. CLEAR_PF_DONE_EVENT(pthread_run);
  165.     if (pthread_run->sighandled) /* Added by monty */
  166.     { /* We where aborted */
  167.       SET_ERRNO(EINTR);
  168.       ret= -EINTR;
  169.       break;
  170.     }
  171.         } else {
  172.             SET_ERRNO(-ret);
  173.             break;
  174.         }
  175.     }
  176. return(ret);
  177. }
  178. /* ==========================================================================
  179.  * getmsg_timedwait()
  180.  */
  181. int getmsg_timedwait(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
  182.   int * flags, struct timespec * timeout)
  183. {
  184. int ret;
  185.     if ((ret = fd_lock(fd, FD_READ, timeout)) == OK) {
  186. ret = getmsg_timedwait_basic(fd, ctlptr, dataptr, flags, timeout);
  187.         fd_unlock(fd, FD_READ);
  188. }
  189. return (ret);
  190. }
  191. /* ==========================================================================
  192.  * getmsg()
  193.  */
  194. int getmsg(int fd, struct strbuf * ctlptr, struct strbuf * dataptr,
  195.   int * flags)
  196. {
  197. return(getmsg_timedwait(fd, ctlptr, dataptr, flags, NULL));
  198. }
  199. #endif
  200. /* ==========================================================================
  201.  * Here are the berkeley socket functions implemented with stream calls.
  202.  * These are not POSIX.
  203.  * ======================================================================= */
  204. #if (!defined (HAVE_SYSCALL_BIND)) && defined(HAVE_STREAMS)
  205. /* ==========================================================================
  206.  * bind()
  207.  */
  208. int bind(int fd, const struct sockaddr *name, int namelen)
  209. {
  210.   char buf[STREAM_BUF_SIZE];
  211.   union T_primitives * res;
  212.   struct T_bind_req * req;
  213.   struct T_bind_ack * ack;
  214.   struct strbuf strbuf;
  215.   int flags, ret;
  216.   if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
  217.   {
  218.     req = (struct T_bind_req *)buf;
  219.     req->PRIM_type = T_BIND_REQ;
  220.     req->ADDR_length = namelen;
  221.     req->ADDR_offset = sizeof(struct T_bind_req);
  222.     req->CONIND_number = 4;
  223.     memcpy(buf + sizeof(struct T_bind_req), name, namelen);
  224.     strbuf.len = sizeof(struct T_bind_req) + namelen;
  225.     strbuf.maxlen = STREAM_BUF_SIZE;
  226.     strbuf.buf = buf;
  227.     if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) == OK)
  228.     {
  229.       memset(buf, 0, STREAM_BUF_SIZE);
  230.       strbuf.len = sizeof(struct T_bind_ack) + namelen;
  231.       strbuf.maxlen = STREAM_BUF_SIZE;
  232.       strbuf.buf = buf;
  233.       flags = 0;
  234.       if ((ret = getmsg_timedwait_basic(fd, &strbuf, NULL,
  235. &flags, NULL)) >= OK)
  236.       {
  237. res = (union T_primitives *)buf;
  238. switch(res->type) {
  239. case T_BIND_ACK:
  240.   ret = OK;
  241.   break;
  242. default:
  243.   SET_ERRNO(EPROTO); /* What should this be? */
  244.   ret = NOTOK;
  245.   break;
  246. }
  247.       }
  248.       else
  249.       {
  250. SET_ERRNO(-ret);
  251. ret = NOTOK;
  252.       }
  253.     }
  254.     else
  255.     {
  256.       SET_ERRNO(-ret);
  257.       ret = NOTOK;
  258.     }
  259.     fd_unlock(fd, FD_RDWR);
  260.   }
  261.   return(ret);
  262. }
  263. #endif
  264. #if (!defined (HAVE_SYSCALL_CONNECT)) && defined(HAVE_STREAMS)
  265. /* ==========================================================================
  266.  * connect()
  267.  */
  268. int connect(int fd, const struct sockaddr *name, int namelen)
  269. {
  270.   char buf[STREAM_BUF_SIZE];
  271.   union T_primitives * res;
  272.   struct T_conn_req * req;
  273.   struct T_conn_con * con;
  274.   struct T_ok_ack * ok;
  275.   struct strbuf strbuf;
  276.   int flags, ret;
  277.   if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
  278.   {
  279.     req = (struct T_conn_req *)buf;
  280.     req->PRIM_type = T_CONN_REQ;
  281.     req->DEST_length = namelen;
  282.     req->DEST_offset = sizeof(struct T_conn_req);
  283.     req->OPT_length = 0;
  284.     req->OPT_offset = 0;
  285.     memcpy(buf + sizeof(struct T_conn_req), name, namelen);
  286.     strbuf.len = sizeof(struct T_conn_req) + namelen;
  287.     strbuf.maxlen = STREAM_BUF_SIZE;
  288.     strbuf.buf = buf;
  289.     if ((ret=putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL)) != OK)
  290.       goto err;
  291.     
  292.     memset(buf, 0, STREAM_BUF_SIZE);
  293.     ok = (struct T_ok_ack *)buf;
  294.     strbuf.maxlen = STREAM_BUF_SIZE;
  295.     strbuf.len = STREAM_BUF_SIZE;
  296.     strbuf.buf = buf;
  297.     flags = 0;
  298.     if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK)
  299.       goto err; /* Fixed by monty */
  300.     if (ok->PRIM_type != T_OK_ACK)
  301.     {
  302.       ret= -EPROTO; /* What should this be? */
  303.       goto err;
  304.     }
  305.     memset(buf, 0, STREAM_BUF_SIZE);
  306.     strbuf.maxlen = STREAM_BUF_SIZE;
  307.     strbuf.len = STREAM_BUF_SIZE;
  308.     strbuf.buf = buf;
  309.     flags = 0;
  310.     if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL) < OK))
  311.       goto err;
  312.     res = (union T_primitives *) buf;
  313.     switch(res->type) {
  314.     case T_CONN_CON:
  315.       ret = OK;
  316.       break;
  317.     case T_DISCON_IND:
  318.       ret= -ECONNREFUSED;
  319.       goto err;
  320.     default:
  321.       ret= -EPROTO; /* What should this be? */
  322.       goto err;
  323.     }
  324.     fd_unlock(fd, FD_RDWR);
  325.   }
  326.   return(ret);
  327.  err:
  328.   fd_unlock(fd, FD_RDWR);
  329.   SET_ERRNO(-ret); /* Proably not needed... */
  330.   return NOTOK;
  331. }
  332. #endif
  333. #if (!defined (HAVE_SYSCALL_LISTEN)) && defined(HAVE_STREAMS)
  334. /* ==========================================================================
  335.  * listen()
  336.  */
  337. int listen(int fd, int backlog)
  338. {
  339. return(OK);
  340. }
  341. #endif
  342. #if (!defined (HAVE_SYSCALL_SOCKET)) && defined(HAVE_STREAMS)
  343. extern ssize_t  __fd_kern_write();
  344. static pthread_ssize_t  __fd_sysv_read();
  345. extern int __fd_kern_close();
  346. extern int __fd_kern_fcntl();
  347. extern int __fd_kern_writev();
  348. extern int __fd_kern_readv();
  349. extern off_t __fd_kern_lseek();
  350. /* Normal file operations */
  351. static struct fd_ops __fd_sysv_ops = {
  352.     __fd_kern_write, __fd_sysv_read, __fd_kern_close, __fd_kern_fcntl,
  353.     __fd_kern_writev, __fd_kern_readv, __fd_kern_lseek, 1
  354. };
  355. /* ==========================================================================
  356.  * read()   
  357.  */         
  358. static pthread_ssize_t __fd_sysv_read(union fd_data fd_data, int flags,
  359.   void *buf, size_t nbytes, struct timespec * timeout)
  360. {           
  361. struct strbuf dataptr;
  362.     int fd = fd_data.i;
  363.     int getmsg_flags;
  364.     int ret;    
  365.     getmsg_flags = 0;
  366. dataptr.len = 0;
  367. dataptr.buf = buf;
  368. dataptr.maxlen = nbytes;
  369.     pthread_run->sighandled=0; /* Added by monty */
  370.     while ((ret = machdep_sys_getmsg(fd, NULL, &dataptr, &getmsg_flags)) < OK) {
  371.         if (!(fd_table[fd]->flags & __FD_NONBLOCK) &&
  372.           ((ret == -EWOULDBLOCK) || (ret == -EAGAIN))) { 
  373.             pthread_sched_prevent();
  374.  
  375.             /* queue pthread for a FDR_WAIT */
  376.             pthread_run->data.fd.fd = fd;
  377.             SET_PF_WAIT_EVENT(pthread_run);
  378. pthread_queue_enq(&fd_wait_read, pthread_run);
  379.             if (timeout) {
  380.                 /* get current time */
  381.                 struct timespec current_time;
  382.                 machdep_gettimeofday(&current_time);
  383.                 sleep_schedule(& current_time, timeout);
  384.             
  385.                 pthread_resched_resume(PS_FDR_WAIT);
  386.  
  387.                 /* We're awake */
  388.                 pthread_sched_prevent();
  389.                 if (sleep_cancel(pthread_run) == NOTOK) {
  390.                     CLEAR_PF_DONE_EVENT(pthread_run);
  391.                     pthread_sched_resume();
  392.                     SET_ERRNO(ETIMEDOUT);
  393.                     ret = -ETIMEDOUT;
  394.                     break;
  395.                 }
  396.                 pthread_sched_resume();
  397.             } else {
  398.                 pthread_resched_resume(PS_FDR_WAIT);
  399.             }
  400.             CLEAR_PF_DONE_EVENT(pthread_run);
  401.     if (pthread_run->sighandled) /* Added by monty */
  402.     { /* We where aborted */
  403.       SET_ERRNO(EINTR);
  404.       return(NOTOK);
  405.     }
  406.         } else {
  407.             SET_ERRNO(-ret);
  408.     return(NOTOK);
  409.             break;
  410.         }
  411.     }
  412.     return(dataptr.len);
  413. }   
  414. /* ==========================================================================
  415.  * socket_tcp()
  416.  */
  417. static int socket_tcp(int fd)
  418. {
  419. int ret;
  420. if ((ret = machdep_sys_open("/dev/tcp", O_RDWR | O_NONBLOCK, 0)) >= OK) {
  421.         /* Should fstat the file to determine what type it is */
  422.         fd_table[fd]->ops   = & __fd_sysv_ops;
  423.         fd_table[fd]->type  = FD_FULL_DUPLEX;
  424.         fd_table[fd]->fd.i  = ret;
  425.         fd_table[fd]->flags = 0;
  426.     }
  427.     return(ret);
  428. }
  429. /* ==========================================================================
  430.  * socket()
  431.  */
  432. int socket(int af, int type, int protocol)
  433. {
  434.   int fd, fd_kern;
  435.   if ((fd = fd_allocate()) < OK)
  436.     return (fd);
  437.   switch(af) {
  438.   case AF_INET:
  439.     switch(type) {
  440.     case SOCK_STREAM:
  441.       if ((fd_kern = socket_tcp(fd)) >= OK)
  442. return(fd);
  443.       SET_ERRNO(-fd_kern);
  444.       break;
  445.     case SOCK_DGRAM:
  446.       if ((fd_kern = machdep_sys_open("/dev/udp",
  447.       O_RDWR | O_NONBLOCK, 0)) >= OK) {
  448. /* Should fstat the file to determine what type it is */
  449. fd_table[fd]->ops   = & __fd_sysv_ops;
  450. fd_table[fd]->type  = FD_FULL_DUPLEX;
  451. fd_table[fd]->fd.i  = fd_kern;
  452. fd_table[fd]->flags = 0;
  453. return(fd);
  454.       }
  455.       SET_ERRNO(-fd_kern);
  456.       break;
  457.     default:
  458.       SET_ERRNO(EPROTONOSUPPORT);
  459.       break;
  460.     }
  461.     break;
  462.   case AF_UNIX:
  463.   case AF_ISO:
  464.   case AF_NS:
  465.   default:
  466.     SET_ERRNO(EPROTONOSUPPORT);
  467.     break;
  468.   }
  469.   fd_table[fd]->count = 0;
  470.   return(NOTOK); /* Fixed by monty */
  471. }
  472. #endif
  473. #if (!defined (HAVE_SYSCALL_ACCEPT)) && defined(HAVE_STREAMS)
  474. /* ==========================================================================
  475.  * accept_fd()
  476.  */
  477. static int accept_fd(int fd, struct sockaddr *name, int *namelen, char * buf,
  478.      int SEQ_number)
  479. {
  480.   struct T_conn_res * res;
  481.   struct strbuf strbuf;
  482.   int fd_new, fd_kern;
  483.   /* Get a new table entry */
  484.   if ((fd_new = fd_allocate()) < OK)
  485.     return(NOTOK);
  486.   /* Get the new kernel entry */
  487.   if (!((fd_kern = socket_tcp(fd_new)) < OK)) { 
  488.     res = (struct T_conn_res *)buf;
  489.     res->PRIM_type = T_CONN_RES;
  490.     /* res->QUEUE_ptr = (queue_t *)&fd_kern; */
  491.     res->OPT_length = 0;
  492.     res->OPT_offset = 0;
  493.     res->SEQ_number = SEQ_number;
  494.     strbuf.maxlen = sizeof(union T_primitives) +sizeof(struct sockaddr);
  495.     strbuf.len = sizeof(struct T_conn_ind) + (*namelen);
  496.     strbuf.buf = buf;
  497.     {
  498.       struct strfdinsert insert;
  499.       insert.ctlbuf.maxlen = (sizeof(union T_primitives) +
  500.       sizeof(struct sockaddr));
  501.       insert.ctlbuf.len =  sizeof(struct T_conn_ind);
  502.       insert.ctlbuf.buf = buf;
  503.       insert.databuf.maxlen = 0;
  504.       insert.databuf.len = 0;
  505.       insert.databuf.buf = NULL;
  506.       insert.flags = 0;
  507.       insert.fildes = fd_kern;
  508.       insert.offset = 4;
  509.       /* Should the following be checked ? */
  510.       machdep_sys_ioctl(fd_table[fd]->fd.i,  I_FDINSERT, &insert);
  511.     }
  512.     /* if (putmsg_timedwait_basic(fd, &strbuf, NULL, 0, NULL) == OK) {
  513. /*  return(fd_new); */
  514.     {
  515.       int flags = 0;
  516.       int ret;
  517.       /* Should the following be checked ? */
  518.       ret = getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL); 
  519.       return(fd_new);
  520.     }
  521.     machdep_sys_close(fd_kern);
  522.   }
  523.   fd_table[fd_new]->count = 0;
  524.   return(NOTOK);
  525. }
  526. /* ==========================================================================
  527.  * accept()
  528.  */
  529. int accept(int fd, struct sockaddr *name, int *namelen)
  530. {
  531.   char buf[sizeof(union T_primitives) + sizeof(struct sockaddr)];
  532.   struct T_conn_ind * ind;
  533.   struct strbuf strbuf;
  534.   int flags, ret;
  535.   if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK)
  536.   {
  537.     ind = (struct T_conn_ind *)buf;
  538.     ind->PRIM_type = T_CONN_IND;
  539.     ind->SRC_length = (*namelen);
  540.     ind->SRC_offset = sizeof(struct T_conn_ind);
  541.     ind->OPT_length = 0;
  542.     ind->OPT_offset = 0;
  543.     ind->SEQ_number = 0;
  544.     strbuf.maxlen = sizeof(union T_primitives) + sizeof(struct sockaddr);
  545.     strbuf.len = sizeof(struct T_conn_ind) + (*namelen);
  546.     strbuf.buf = buf;
  547.     flags = 0;
  548.     if ((ret=getmsg_timedwait_basic(fd, &strbuf, NULL, &flags, NULL)) < OK)
  549.     {
  550.       SET_ERRNO(-ret);
  551.       ret= NOTOK;
  552.     }
  553.     else
  554.       ret = accept_fd(fd, name, namelen, buf, ind->SEQ_number);
  555.     fd_unlock(fd, FD_RDWR);
  556.   }
  557.   return(ret);
  558. }
  559. #endif /* HAVE_SYSCALL_ACCEPT */
  560. #if (!defined (HAVE_SYSCALL_SENDTO)) && defined (HAVE_STREAMS)
  561. /* ==========================================================================
  562.  * sendto_timedwait()
  563.  */
  564. ssize_t sendto_timedwait(int fd, const void * msg, size_t len, int flags, 
  565.   const struct sockaddr *name, int namelen, struct timespec * timeout)
  566. {
  567. char buf[STREAM_BUF_SIZE];
  568. struct T_unitdata_req * req;
  569. struct strbuf dataptr;
  570. struct strbuf ctlptr;
  571.     ssize_t ret, prio;
  572. req = (struct T_unitdata_req *)buf;
  573. req->PRIM_type = T_UNITDATA_REQ;
  574. req->DEST_length = namelen;
  575. req->DEST_offset = sizeof(struct T_unitdata_req);
  576. req->OPT_length = 0;
  577. req->OPT_offset = 0;
  578. memcpy(buf + sizeof(struct T_unitdata_req), name, namelen);
  579. ctlptr.len = sizeof(struct T_unitdata_req) + namelen;
  580. ctlptr.maxlen = STREAM_BUF_SIZE;
  581. ctlptr.buf = buf;
  582. dataptr.len = len;
  583. dataptr.maxlen = len;
  584. dataptr.buf = (void *)msg;
  585. if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) {
  586. ret = len;
  587. }
  588. return(ret);
  589. }
  590. /* ==========================================================================
  591.  * sendto()
  592.  */
  593. ssize_t sendto(int fd, const void * msg, size_t len, int flags,
  594.   const struct sockaddr *to, int to_len)
  595. {
  596. return(sendto_timedwait(fd, msg, len, flags, to, to_len, NULL));
  597. }
  598. #endif
  599. #if (!defined (HAVE_SYSCALL_SEND)) && defined (HAVE_STREAMS)
  600. /* ==========================================================================
  601.  * send_timedwait()
  602.  */
  603. ssize_t send_timedwait(int fd, const void * msg, size_t len, int flags, 
  604.   struct timespec * timeout)
  605. {
  606. char buf[STREAM_BUF_SIZE];
  607. struct T_unitdata_req * req;
  608. struct strbuf dataptr;
  609. struct strbuf ctlptr;
  610. ssize_t ret, prio;
  611. req = (struct T_unitdata_req *)buf;
  612. req->PRIM_type = T_UNITDATA_REQ;
  613. req->DEST_length = 0;
  614. req->DEST_offset = 0;
  615. req->OPT_length = 0;
  616. req->OPT_offset = 0;
  617. ctlptr.len = sizeof(struct T_unitdata_req);
  618. ctlptr.maxlen = STREAM_BUF_SIZE;
  619. ctlptr.buf = buf;
  620. dataptr.len = len;
  621. dataptr.maxlen = len;
  622. dataptr.buf = (void *)msg;
  623. if ((ret = putmsg_timedwait(fd, &ctlptr, &dataptr, 0, timeout)) == OK) {
  624. ret = len;
  625. }
  626. return(ret);
  627. }
  628. /* ==========================================================================
  629.  * send()
  630.  */
  631. ssize_t send(int fd, const void * msg, size_t len, int flags)
  632. {
  633. return(send_timedwait(fd, msg, len, flags, NULL));
  634. }
  635. #endif
  636. #if (!defined (HAVE_SYSCALL_RECVFROM)) && defined(HAVE_STREAMS)
  637. /* ==========================================================================
  638.  * recvfrom_timedwait()
  639.  */
  640. ssize_t recvfrom_timedwait(int fd, void * msg, size_t len, int flags,
  641.   struct sockaddr * name, int * namelen, struct timespec * timeout)
  642. {
  643. char buf[STREAM_BUF_SIZE];
  644. struct T_unitdata_ind * ind;
  645. struct strbuf dataptr;
  646. struct strbuf ctlptr;
  647. int ret, prio;
  648. ctlptr.len = 0;
  649. ctlptr.maxlen = STREAM_BUF_SIZE;
  650. ctlptr.buf = buf;
  651. dataptr.maxlen = len;
  652. dataptr.len = 0;
  653. dataptr.buf = msg;
  654. prio = 0;
  655. ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout);
  656. if (ret >= OK) {
  657. if (name != NULL) {
  658. ind = (struct T_unitdata_ind *)buf;
  659. if (*namelen > ind->SRC_length)
  660. *namelen = ind->SRC_length;
  661. memcpy(name, buf + ind->SRC_offset, *namelen);
  662. }
  663. ret = dataptr.len;
  664. }
  665. return(ret);
  666. }
  667. /* ==========================================================================
  668.  * recvfrom()
  669.  */
  670. ssize_t recvfrom(int fd, void * buf, size_t len, int flags,
  671.   struct sockaddr * from, int * from_len)
  672. {
  673. return(recvfrom_timedwait(fd, buf, len, flags, from, from_len, NULL));
  674. }
  675. #endif
  676. #if (!defined (HAVE_SYSCALL_RECV)) && defined(HAVE_STREAMS)
  677. /* ==========================================================================
  678.  * recv_timedwait()
  679.  */
  680. ssize_t recv_timedwait(int fd, void * msg, size_t len, int flags,
  681.   struct timespec * timeout)
  682. {
  683. char buf[STREAM_BUF_SIZE];
  684. struct T_unitdata_ind * ind;
  685. struct strbuf dataptr;
  686. struct strbuf ctlptr;
  687. int ret, prio;
  688. ctlptr.len = 0;
  689. ctlptr.maxlen = STREAM_BUF_SIZE;
  690. ctlptr.buf = buf;
  691. dataptr.maxlen = len;
  692. dataptr.len = 0;
  693. dataptr.buf = msg;
  694. prio = 0;
  695. ret = getmsg_timedwait(fd, &ctlptr, &dataptr, &prio, timeout);
  696. if (ret >= OK)
  697. ret = dataptr.len;
  698. return(ret);
  699. }
  700. /* ==========================================================================
  701.  * recv()
  702.  */
  703. ssize_t recv(int fd, void * buf, size_t len, int flags,
  704.   struct sockaddr * from, int * from_len)
  705. {
  706. return(recv_timedwait(fd, buf, len, flags, NULL));
  707. }
  708. #endif
  709. #if (!defined (HAVE_SYSCALL_SETSOCKOPT)) && defined(HAVE_STREAMS)
  710. /* ==========================================================================
  711.  * setsockopt()
  712.  */
  713. int setsockopt(int s, int level, int optname, const void *optval, int optlen)
  714. {
  715. return(0);
  716. }
  717. #endif
  718. struct foo { /* Used by getsockname and getpeername */
  719. long a;
  720. int b;
  721. struct sockaddr *name;
  722. };
  723. #if (!defined (HAVE_SYSCALL_GETSOCKNAME)) && defined(HAVE_STREAMS)
  724. /* ==========================================================================
  725.  * getsockname()
  726.  */
  727. int getsockname(int s, struct sockaddr *name, int *namelen)
  728. {
  729. struct foo foo;
  730. int i;
  731. if (*namelen < sizeof(struct sockaddr)) {
  732. SET_ERRNO(ENOMEM);
  733. return(-1);
  734. }
  735. foo.a = 0x84;
  736. foo.b = 0;
  737. foo.name = name;
  738. i = ioctl(s, TI_GETMYNAME, &foo);
  739. *namelen = foo.b;
  740. return(i);
  741. }
  742. #endif
  743. #if (!defined (HAVE_SYSCALL_GETPEERNAME)) && defined(HAVE_STREAMS)
  744. /* ==========================================================================
  745.  * getpeername() ; Added by Monty
  746.  */
  747. int getpeername(int s, struct sockaddr *name, int *namelen)
  748. {
  749. struct foo foo;
  750. int i;
  751. if (*namelen < sizeof(struct sockaddr)) {
  752. SET_ERRNO(ENOMEM);
  753. return(-1);
  754. }
  755. foo.a = 0x84; /* Max length ? */
  756. foo.b = 0; /* Return length */
  757. foo.name = name; /* Return buffer */
  758. i = ioctl(s, TI_GETPEERNAME, &foo);
  759. *namelen = foo.b;
  760. return(i);
  761. }
  762. #endif
  763. #if (!defined (HAVE_SYSCALL_SHUTDOWN)) && defined(HAVE_STREAMS)
  764. /* ==========================================================================
  765.  * shutdown()
  766.  */
  767. int shutdown(int s, int how)
  768. {
  769. return(0);
  770. }
  771. #endif