| version 1.2, 1993/05/18 18:19:36 |
version 1.3, 1993/06/27 06:08:15 |
|
|
| */ |
*/ |
| |
|
| #include "param.h" |
#include "param.h" |
| |
#include "systm.h" |
| #include "proc.h" |
#include "proc.h" |
| #include "file.h" |
#include "file.h" |
| #include "malloc.h" |
#include "malloc.h" |
|
|
| * switching out to the protocol specific routines. |
* switching out to the protocol specific routines. |
| */ |
*/ |
| /*ARGSUSED*/ |
/*ARGSUSED*/ |
| |
int |
| socreate(dom, aso, type, proto) |
socreate(dom, aso, type, proto) |
| struct socket **aso; |
struct socket **aso; |
| register int type; |
register int type; |
| Line 91 socreate(dom, aso, type, proto) |
|
| Line 93 socreate(dom, aso, type, proto) |
|
| return (0); |
return (0); |
| } |
} |
| |
|
| |
int |
| sobind(so, nam) |
sobind(so, nam) |
| struct socket *so; |
struct socket *so; |
| struct mbuf *nam; |
struct mbuf *nam; |
|
|
| return (error); |
return (error); |
| } |
} |
| |
|
| |
int |
| solisten(so, backlog) |
solisten(so, backlog) |
| register struct socket *so; |
register struct socket *so; |
| int backlog; |
int backlog; |
| Line 127 solisten(so, backlog) |
|
| Line 131 solisten(so, backlog) |
|
| return (0); |
return (0); |
| } |
} |
| |
|
| |
int |
| sofree(so) |
sofree(so) |
| register struct socket *so; |
register struct socket *so; |
| { |
{ |
|
|
| * Initiate disconnect if connected. |
* Initiate disconnect if connected. |
| * Free socket when disconnect complete. |
* Free socket when disconnect complete. |
| */ |
*/ |
| |
int |
| soclose(so) |
soclose(so) |
| register struct socket *so; |
register struct socket *so; |
| { |
{ |
|
|
| /* |
/* |
| * Must be called at splnet... |
* Must be called at splnet... |
| */ |
*/ |
| |
int |
| soabort(so) |
soabort(so) |
| struct socket *so; |
struct socket *so; |
| { |
{ |
|
|
| (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)); |
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)); |
| } |
} |
| |
|
| |
int |
| soaccept(so, nam) |
soaccept(so, nam) |
| register struct socket *so; |
register struct socket *so; |
| struct mbuf *nam; |
struct mbuf *nam; |
| Line 223 soaccept(so, nam) |
|
| Line 231 soaccept(so, nam) |
|
| return (error); |
return (error); |
| } |
} |
| |
|
| |
int |
| soconnect(so, nam) |
soconnect(so, nam) |
| register struct socket *so; |
register struct socket *so; |
| struct mbuf *nam; |
struct mbuf *nam; |
| Line 250 soconnect(so, nam) |
|
| Line 259 soconnect(so, nam) |
|
| return (error); |
return (error); |
| } |
} |
| |
|
| |
int |
| soconnect2(so1, so2) |
soconnect2(so1, so2) |
| register struct socket *so1; |
register struct socket *so1; |
| struct socket *so2; |
struct socket *so2; |
| Line 263 soconnect2(so1, so2) |
|
| Line 273 soconnect2(so1, so2) |
|
| return (error); |
return (error); |
| } |
} |
| |
|
| |
int |
| sodisconnect(so) |
sodisconnect(so) |
| register struct socket *so; |
register struct socket *so; |
| { |
{ |
|
|
| * must check for short counts if EINTR/ERESTART are returned. |
* must check for short counts if EINTR/ERESTART are returned. |
| * Data and control buffers are freed on return. |
* Data and control buffers are freed on return. |
| */ |
*/ |
| |
int |
| sosend(so, addr, uio, top, control, flags) |
sosend(so, addr, uio, top, control, flags) |
| register struct socket *so; |
register struct socket *so; |
| struct mbuf *addr; |
struct mbuf *addr; |
|
|
| * an mbuf **mp0 for use in returning the chain. The uio is then used |
* an mbuf **mp0 for use in returning the chain. The uio is then used |
| * only for the count in uio_resid. |
* only for the count in uio_resid. |
| */ |
*/ |
| |
int |
| soreceive(so, paddr, uio, mp0, controlp, flagsp) |
soreceive(so, paddr, uio, mp0, controlp, flagsp) |
| register struct socket *so; |
register struct socket *so; |
| struct mbuf **paddr; |
struct mbuf **paddr; |
| Line 481 soreceive(so, paddr, uio, mp0, controlp, |
|
| Line 494 soreceive(so, paddr, uio, mp0, controlp, |
|
| struct protosw *pr = so->so_proto; |
struct protosw *pr = so->so_proto; |
| struct mbuf *nextrecord; |
struct mbuf *nextrecord; |
| int moff, type; |
int moff, type; |
| |
int orig_resid = uio->uio_resid; |
| |
|
| mp = mp0; |
mp = mp0; |
| if (paddr) |
if (paddr) |
|
|
| while (m == 0 || so->so_rcv.sb_cc < uio->uio_resid && |
while (m == 0 || so->so_rcv.sb_cc < uio->uio_resid && |
| (so->so_rcv.sb_cc < so->so_rcv.sb_lowat || |
(so->so_rcv.sb_cc < so->so_rcv.sb_lowat || |
| ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) && |
((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) && |
| m->m_nextpkt == 0) { |
m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0) { |
| #ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
| if (m == 0 && so->so_rcv.sb_cc) |
if (m == 0 && so->so_rcv.sb_cc) |
| panic("receive 1"); |
panic("receive 1"); |
|
|
| if (m->m_type != MT_SONAME) |
if (m->m_type != MT_SONAME) |
| panic("receive 1a"); |
panic("receive 1a"); |
| #endif |
#endif |
| |
orig_resid = 0; |
| if (flags & MSG_PEEK) { |
if (flags & MSG_PEEK) { |
| if (paddr) |
if (paddr) |
| *paddr = m_copy(m, 0, m->m_len); |
*paddr = m_copy(m, 0, m->m_len); |
|
|
| m = so->so_rcv.sb_mb; |
m = so->so_rcv.sb_mb; |
| } |
} |
| } |
} |
| if (controlp) |
if (controlp) { |
| |
orig_resid = 0; |
| controlp = &(*controlp)->m_next; |
controlp = &(*controlp)->m_next; |
| |
} |
| } |
} |
| if (m) { |
if (m) { |
| if ((flags & MSG_PEEK) == 0) |
if ((flags & MSG_PEEK) == 0) |
|
|
| * Keep sockbuf locked against other readers. |
* Keep sockbuf locked against other readers. |
| */ |
*/ |
| while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 && |
while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 && |
| !sosendallatonce(so)) { |
!sosendallatonce(so) && !nextrecord) { |
| if (so->so_error || so->so_state & SS_CANTRCVMORE) |
if (so->so_error || so->so_state & SS_CANTRCVMORE) |
| break; |
break; |
| error = sbwait(&so->so_rcv); |
error = sbwait(&so->so_rcv); |
|
|
| nextrecord = m->m_nextpkt; |
nextrecord = m->m_nextpkt; |
| } |
} |
| } |
} |
| |
|
| |
if (m && pr->pr_flags & PR_ATOMIC) { |
| |
flags |= MSG_TRUNC; |
| |
if ((flags & MSG_PEEK) == 0) |
| |
(void) sbdroprecord(&so->so_rcv); |
| |
} |
| if ((flags & MSG_PEEK) == 0) { |
if ((flags & MSG_PEEK) == 0) { |
| if (m == 0) |
if (m == 0) |
| so->so_rcv.sb_mb = nextrecord; |
so->so_rcv.sb_mb = nextrecord; |
| else if (pr->pr_flags & PR_ATOMIC) { |
|
| flags |= MSG_TRUNC; |
|
| (void) sbdroprecord(&so->so_rcv); |
|
| } |
|
| if (pr->pr_flags & PR_WANTRCVD && so->so_pcb) |
if (pr->pr_flags & PR_WANTRCVD && so->so_pcb) |
| (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0, |
(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0, |
| (struct mbuf *)flags, (struct mbuf *)0, |
(struct mbuf *)flags, (struct mbuf *)0, |
| (struct mbuf *)0); |
(struct mbuf *)0); |
| } |
} |
| |
if (orig_resid == uio->uio_resid && orig_resid && |
| |
(flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) { |
| |
sbunlock(&so->so_rcv); |
| |
splx(s); |
| |
goto restart; |
| |
} |
| |
|
| if (flagsp) |
if (flagsp) |
| *flagsp |= flags; |
*flagsp |= flags; |
| release: |
release: |