home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / comm / amitcp-3.0ß2.lha / AmiTCP / src / amitcp / api / amiga_sendrecv.c < prev    next >
C/C++ Source or Header  |  1994-01-06  |  8KB  |  368 lines

  1. RCS_ID_C="$Id: amiga_sendrecv.c,v 3.1 1994/01/06 13:37:15 too Exp $";
  2. /*
  3.  * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
  4.  *                    Helsinki University of Technology, Finland.
  5.  *                    All rights reserved.
  6.  *
  7.  * Created: Wed Jan  5 18:35:27 1994 too
  8.  * Last modified: Thu Jan  6 15:20:11 1994 too
  9.  *
  10.  * HISTORY
  11.  * $Log: amiga_sendrecv.c,v $
  12.  * Revision 3.1  1994/01/06  13:37:15  too
  13.  * Moved send and recv functions from amiga_syscalls.c for
  14.  * easier update
  15.  *
  16.  */
  17.  
  18. #include <conf.h>
  19.  
  20. #include <sys/param.h>
  21. #include <sys/systm.h>
  22. #include <sys/malloc.h>
  23. #include <sys/mbuf.h>
  24. #include <sys/protosw.h>
  25. #include <sys/socket.h>
  26. #include <sys/socketvar.h>
  27. #include <sys/synch.h>
  28. #include <sys/errno.h>
  29.  
  30. #include <exec/types.h>
  31. #include <exec/libraries.h>
  32. #include <exec/semaphores.h>
  33.  
  34. #include <api/amiga_api.h>
  35. #include <api/amiga_libcallentry.h>
  36. #include <api/sockargs.h>
  37.  
  38. #include <kern/uipc_socket_protos.h>
  39. #include <kern/uipc_socket2_protos.h>
  40.   
  41. static LONG sendit(struct SocketBase * p,
  42.            LONG    s,
  43.            struct msghdr * mp,
  44.            LONG flags,
  45.            LONG * retsize);
  46.  
  47. static LONG recvit(struct SocketBase * p,
  48.            LONG s,
  49.            struct msghdr * mp,
  50.            LONG flags,
  51.            LONG * namelenp,
  52.            LONG * retsize);
  53.  
  54.  
  55. LONG SAVEDS RAF5(_send,
  56.          struct SocketBase *,    libPtr,    a6,
  57.          LONG,            s,    d0,
  58.          caddr_t,        buf,    a0,
  59.          LONG,            len,    d1,
  60.          LONG,            flags,    d2)
  61. #if 0     
  62. {
  63. #endif
  64.  
  65.   struct msghdr msg;
  66.   struct iovec aiov;
  67.   LONG error, retval;
  68.   
  69.   CHECK_TASK();
  70.  
  71.   msg.msg_name = 0;
  72.   msg.msg_namelen = 0;
  73.   msg.msg_iov = &aiov;
  74.   msg.msg_iovlen = 1;
  75.   msg.msg_control = 0;
  76.   aiov.iov_base = buf;
  77.   aiov.iov_len = len;
  78.   
  79.   ObtainSyscallSemaphore(libPtr);
  80.   error = sendit(libPtr, s, &msg, flags, &retval);
  81.   ReleaseSyscallSemaphore(libPtr);
  82.   
  83.   API_STD_RETURN(error, retval);
  84. }
  85.  
  86. LONG SAVEDS RAF7(_sendto,
  87.          struct SocketBase *,    libPtr,    a6,
  88.          LONG,            s,    d0,
  89.          caddr_t,        buf,    a0,
  90.          LONG,            len,    d1,
  91.          LONG,            flags,    d2,
  92.          caddr_t,        to,    a1,
  93.          LONG,            tolen,    d3)
  94. #if 0
  95. {
  96. #endif
  97.  
  98.   struct msghdr msg;
  99.   struct iovec aiov;
  100.   LONG error, retval;
  101.   
  102.   CHECK_TASK();
  103.  
  104.   msg.msg_name = to;
  105.   msg.msg_namelen = tolen;
  106.   msg.msg_iov = &aiov;
  107.   msg.msg_iovlen = 1;
  108.   msg.msg_control = 0;
  109.   aiov.iov_base = buf;
  110.   aiov.iov_len = len;
  111.   
  112.   ObtainSyscallSemaphore(libPtr);
  113.   error = sendit(libPtr, s, &msg, flags, &retval);
  114.   ReleaseSyscallSemaphore(libPtr);
  115.   
  116.   API_STD_RETURN(error, retval);
  117. }
  118.  
  119. LONG SAVEDS RAF4(_sendmsg,
  120.          struct SocketBase *,    libPtr,    a6,
  121.          LONG,            s,    d0,
  122.          struct msghdr *,    msg_p,    a0,
  123.          LONG,            flags,    d1)
  124. #if 0     
  125. {
  126. #endif
  127.   LONG error, retval;
  128.  
  129.   CHECK_TASK();
  130.  
  131.   ObtainSyscallSemaphore(libPtr);
  132.   error = sendit(libPtr, s, msg_p, flags, &retval);
  133.   ReleaseSyscallSemaphore(libPtr);
  134.  
  135.   API_STD_RETURN(error, retval);
  136. }
  137.  
  138. static LONG sendit(struct SocketBase * p,
  139.            LONG    s,
  140.            struct msghdr * mp,
  141.            LONG flags,
  142.            LONG * retsize)
  143. {
  144.   struct socket *so;
  145.   struct uio auio;
  146.   register int i;
  147.   register struct iovec *iov;
  148.   struct mbuf *to, *control;
  149.   LONG len, error;
  150.  
  151.   if (error = getSock(p, s, &so))
  152.     return (error);
  153.  
  154.   auio.uio_iov = mp->msg_iov;
  155.   auio.uio_iovcnt = mp->msg_iovlen;
  156.   auio.uio_procp = p;
  157.   auio.uio_resid = 0;
  158.   iov = mp->msg_iov;
  159.  
  160.   for(i = 0; i < mp->msg_iovlen; i++, iov++) {
  161.     if (iov->iov_len < 0)
  162.       return (EINVAL);
  163.     if ((auio.uio_resid += iov->iov_len) < 0)
  164.       return (EINVAL);
  165.   }
  166.   
  167.   if (mp->msg_name) {
  168.     if (error = sockArgs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME))
  169.       return (error);
  170.   }
  171.   else
  172.     to = 0;
  173.   
  174.   if (mp->msg_control) {
  175.     if (mp->msg_controllen < sizeof (struct cmsghdr)) {
  176.       error = EINVAL;
  177.       goto bad;
  178.     }
  179.     if (error = sockArgs(&control, mp->msg_control,
  180.              mp->msg_controllen, MT_CONTROL))
  181.       goto bad;
  182.   }
  183.   else
  184.     control = 0;
  185.  
  186.   len = auio.uio_resid;
  187.   if (error = sosend(so, to, &auio, (struct mbuf *)0, control, flags)) {
  188.     if (auio.uio_resid != len && (error == ERESTART || error == EINTR ||
  189.                   error == EWOULDBLOCK))
  190.       error = 0;
  191.   }
  192.   if (error == 0)
  193.     *retsize = len - auio.uio_resid;
  194.  
  195.   /* sosend() frees control if allocated */
  196.  bad:
  197.   if (to)
  198.     m_freem(to);
  199.  
  200.   return (error);
  201. }
  202.  
  203. LONG SAVEDS RAF5(_recv,
  204.          struct SocketBase *,    libPtr,    a6,
  205.          LONG,            s,    d0,
  206.          caddr_t,        buf,    a0,
  207.          LONG,            len,    d1,
  208.          LONG,            flags,    d2)
  209. #if 0     
  210. {
  211. #endif
  212.  
  213.   struct msghdr msg;
  214.   struct iovec aiov;
  215.   LONG error, retval;
  216.  
  217.   CHECK_TASK();
  218.  
  219.   msg.msg_name = 0;
  220.   msg.msg_namelen = 0;
  221.   msg.msg_iov = &aiov;
  222.   msg.msg_iovlen = 1;
  223.   msg.msg_control = 0;
  224.   aiov.iov_base = buf;
  225.   aiov.iov_len = len;
  226.  
  227.   ObtainSyscallSemaphore(libPtr);
  228.   error = recvit(libPtr, s, &msg, flags, NULL, &retval);
  229.   ReleaseSyscallSemaphore(libPtr);
  230.  
  231.   API_STD_RETURN(error, retval);
  232. }
  233.  
  234. LONG SAVEDS RAF7(_recvfrom,
  235.          struct SocketBase *,    libPtr,        a6,
  236.          LONG,            s,        d0,
  237.          caddr_t,        buf,        a0,
  238.          LONG,            len,        d1,
  239.          LONG,            flags,        d2,
  240.          caddr_t,        from,        a1,
  241.          LONG *,        fromlenaddr,    a2)
  242. #if 0
  243. {
  244. #endif
  245.  
  246.   struct msghdr    msg;
  247.   struct iovec aiov;
  248.   LONG error, retval;
  249.  
  250.   CHECK_TASK();
  251.  
  252.   if (fromlenaddr)
  253.     msg.msg_namelen = *fromlenaddr;
  254.   else
  255.     msg.msg_namelen = 0;
  256.  
  257.   msg.msg_name = from;
  258.   msg.msg_iov = &aiov;
  259.   msg.msg_iovlen = 1;
  260.   msg.msg_control = 0;
  261.   aiov.iov_base = buf;
  262.   aiov.iov_len = len;
  263.  
  264.   ObtainSyscallSemaphore(libPtr);
  265.   error = recvit(libPtr, s, &msg, flags, fromlenaddr, &retval);
  266.   ReleaseSyscallSemaphore(libPtr);
  267.  
  268.   API_STD_RETURN(error, retval);
  269. }
  270.  
  271. LONG SAVEDS RAF4(_recvmsg,
  272.          struct SocketBase *,    libPtr,    a6,
  273.          LONG,            s,    d0,
  274.          struct msghdr *,    msg_p,    a0,
  275.          LONG,            flags,    d1)
  276. #if 0     
  277. {
  278. #endif
  279.   LONG error, retval;
  280.   
  281.   CHECK_TASK();
  282.  
  283.   ObtainSyscallSemaphore(libPtr);
  284.   error = recvit(libPtr, s, msg_p, flags, NULL, &retval);
  285.   ReleaseSyscallSemaphore(libPtr);
  286.  
  287.   API_STD_RETURN(error, retval);
  288. }
  289.  
  290. static LONG recvit(struct SocketBase * p,
  291.            LONG s,
  292.            struct msghdr * mp,
  293.            LONG flags,
  294.            LONG * namelenp,
  295.            LONG * retsize)
  296. {
  297.   struct socket * so;
  298.   struct uio auio;
  299.   struct iovec *iov;
  300.   register int i;
  301.   ULONG len;
  302.   LONG error;
  303.   struct mbuf *from = 0, *control = 0;
  304.  
  305.   if (error = getSock(p, s, &so))
  306.     return (error);
  307.  
  308.   auio.uio_iov = mp->msg_iov;
  309.   auio.uio_iovcnt = mp->msg_iovlen;
  310.   auio.uio_procp = p;
  311.   auio.uio_resid = 0;
  312.  
  313.   iov = mp->msg_iov;
  314.   for(i = 0; i < mp->msg_iovlen; i++, iov++) {
  315.     if (iov->iov_len < 0)
  316.       return (EINVAL);
  317.     if ((auio.uio_resid += iov->iov_len) < 0)
  318.       return (EINVAL);
  319.   }
  320.   len = auio.uio_resid;
  321.   if (error = soreceive(so, &from, &auio,
  322.             (struct mbuf **)0, &control, (int *)&flags))
  323.     if (auio.uio_resid != len && (error == ERESTART || error == EINTR ||
  324.                   error == EWOULDBLOCK))
  325.       error = 0;
  326.   
  327.   if (error)
  328.     goto out;
  329.   
  330.   *retsize = len - auio.uio_resid;
  331.   
  332.   if (mp->msg_name) {
  333.     len = mp->msg_namelen;
  334.     if (len <= 0 || from == 0)
  335.       len = 0;
  336.     else {
  337.       if (len > from->m_len)
  338.     len = from->m_len;
  339.       aligned_bcopy(mtod(from, caddr_t), (caddr_t)mp->msg_name, (unsigned)len);
  340.     }
  341.     mp->msg_namelen = len;
  342.     if (namelenp)
  343.       *namelenp = len;
  344.   }
  345.   if (mp->msg_control) {
  346.     len = mp->msg_controllen;
  347.     if (len <= 0 || control == 0)
  348.       len = 0;
  349.     else {
  350.       if (len >= control->m_len)
  351.     len = control->m_len;
  352. /*      else
  353.     flags |= MSG_CTRUNC;  no syscall ever does something w/ mp->flags */
  354.       
  355.       aligned_bcopy(mtod(control, caddr_t),
  356.             (caddr_t)mp->msg_control, (unsigned)len);
  357.     }
  358.     mp->msg_controllen = len;
  359.   }
  360.  out:
  361.   if (from)
  362.     m_freem(from);
  363.   if (control)
  364.     m_freem(control);
  365.   
  366.   return (error);
  367. }
  368.