| version 1.20, 1995/08/12 23:59:11 |
version 1.21, 1996/02/04 02:17:52 |
|
|
| #include <sys/protosw.h> |
#include <sys/protosw.h> |
| #include <sys/socket.h> |
#include <sys/socket.h> |
| #include <sys/socketvar.h> |
#include <sys/socketvar.h> |
| |
#include <sys/signalvar.h> |
| #include <sys/resourcevar.h> |
#include <sys/resourcevar.h> |
| |
|
| /* |
/* |
| Line 83 socreate(dom, aso, type, proto) |
|
| Line 84 socreate(dom, aso, type, proto) |
|
| so->so_state = SS_PRIV; |
so->so_state = SS_PRIV; |
| so->so_proto = prp; |
so->so_proto = prp; |
| error = |
error = |
| (*prp->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0, |
(*prp->pr_usrreq)(so, PRU_ATTACH, NULL, (struct mbuf *)(long)proto, |
| (struct mbuf *)(long)proto, (struct mbuf *)0); |
NULL); |
| if (error) { |
if (error) { |
| so->so_state |= SS_NOFDREF; |
so->so_state |= SS_NOFDREF; |
| sofree(so); |
sofree(so); |
|
|
| int s = splsoftnet(); |
int s = splsoftnet(); |
| int error; |
int error; |
| |
|
| error = |
error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, NULL, nam, NULL); |
| (*so->so_proto->pr_usrreq)(so, PRU_BIND, |
|
| (struct mbuf *)0, nam, (struct mbuf *)0); |
|
| splx(s); |
splx(s); |
| return (error); |
return (error); |
| } |
} |
| Line 123 solisten(so, backlog) |
|
| Line 122 solisten(so, backlog) |
|
| { |
{ |
| int s = splsoftnet(), error; |
int s = splsoftnet(), error; |
| |
|
| error = |
error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL, NULL, NULL); |
| (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, |
|
| (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0); |
|
| if (error) { |
if (error) { |
| splx(s); |
splx(s); |
| return (error); |
return (error); |
| Line 139 solisten(so, backlog) |
|
| Line 136 solisten(so, backlog) |
|
| return (0); |
return (0); |
| } |
} |
| |
|
| int |
void |
| sofree(so) |
sofree(so) |
| register struct socket *so; |
register struct socket *so; |
| { |
{ |
|
|
| if ((so->so_state & SS_ISDISCONNECTING) && |
if ((so->so_state & SS_ISDISCONNECTING) && |
| (so->so_state & SS_NBIO)) |
(so->so_state & SS_NBIO)) |
| goto drop; |
goto drop; |
| while (so->so_state & SS_ISCONNECTED) |
while (so->so_state & SS_ISCONNECTED) { |
| if (error = tsleep((caddr_t)&so->so_timeo, |
error = tsleep((caddr_t)&so->so_timeo, |
| PSOCK | PCATCH, netcls, so->so_linger)) |
PSOCK | PCATCH, netcls, |
| |
so->so_linger); |
| |
if (error) |
| break; |
break; |
| |
} |
| } |
} |
| } |
} |
| drop: |
drop: |
| if (so->so_pcb) { |
if (so->so_pcb) { |
| int error2 = |
int error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH, NULL, |
| (*so->so_proto->pr_usrreq)(so, PRU_DETACH, |
NULL, NULL); |
| (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0); |
|
| if (error == 0) |
if (error == 0) |
| error = error2; |
error = error2; |
| } |
} |
|
|
| struct socket *so; |
struct socket *so; |
| { |
{ |
| |
|
| return ( |
return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, NULL, NULL, NULL); |
| (*so->so_proto->pr_usrreq)(so, PRU_ABORT, |
|
| (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)); |
|
| } |
} |
| |
|
| int |
int |
| Line 233 soaccept(so, nam) |
|
| Line 230 soaccept(so, nam) |
|
| if ((so->so_state & SS_NOFDREF) == 0) |
if ((so->so_state & SS_NOFDREF) == 0) |
| panic("soaccept: !NOFDREF"); |
panic("soaccept: !NOFDREF"); |
| so->so_state &= ~SS_NOFDREF; |
so->so_state &= ~SS_NOFDREF; |
| error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, |
error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, NULL, nam, NULL); |
| (struct mbuf *)0, nam, (struct mbuf *)0); |
|
| splx(s); |
splx(s); |
| return (error); |
return (error); |
| } |
} |
| Line 262 soconnect(so, nam) |
|
| Line 258 soconnect(so, nam) |
|
| error = EISCONN; |
error = EISCONN; |
| else |
else |
| error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT, |
error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT, |
| (struct mbuf *)0, nam, (struct mbuf *)0); |
NULL, nam, NULL); |
| splx(s); |
splx(s); |
| return (error); |
return (error); |
| } |
} |
| Line 275 soconnect2(so1, so2) |
|
| Line 271 soconnect2(so1, so2) |
|
| int s = splsoftnet(); |
int s = splsoftnet(); |
| int error; |
int error; |
| |
|
| error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, |
error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, NULL, |
| (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0); |
(struct mbuf *)so2, NULL); |
| splx(s); |
splx(s); |
| return (error); |
return (error); |
| } |
} |
| Line 296 sodisconnect(so) |
|
| Line 292 sodisconnect(so) |
|
| error = EALREADY; |
error = EALREADY; |
| goto bad; |
goto bad; |
| } |
} |
| error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, |
error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, NULL, NULL, |
| (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0); |
NULL); |
| bad: |
bad: |
| splx(s); |
splx(s); |
| return (error); |
return (error); |
| Line 359 sosend(so, addr, uio, top, control, flag |
|
| Line 355 sosend(so, addr, uio, top, control, flag |
|
| #define snderr(errno) { error = errno; splx(s); goto release; } |
#define snderr(errno) { error = errno; splx(s); goto release; } |
| |
|
| restart: |
restart: |
| if (error = sblock(&so->so_snd, SBLOCKWAIT(flags))) |
if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0) |
| goto out; |
goto out; |
| do { |
do { |
| s = splsoftnet(); |
s = splsoftnet(); |
|
|
| space = sbspace(&so->so_snd); |
space = sbspace(&so->so_snd); |
| if (flags & MSG_OOB) |
if (flags & MSG_OOB) |
| space += 1024; |
space += 1024; |
| if (atomic && resid > so->so_snd.sb_hiwat || |
if ((atomic && resid > so->so_snd.sb_hiwat) || |
| clen > so->so_snd.sb_hiwat) |
clen > so->so_snd.sb_hiwat) |
| snderr(EMSGSIZE); |
snderr(EMSGSIZE); |
| if (space < resid + clen && uio && |
if (space < resid + clen && uio && |
|
|
| if (dontroute) |
if (dontroute) |
| so->so_options |= SO_DONTROUTE; |
so->so_options |= SO_DONTROUTE; |
| s = splsoftnet(); /* XXX */ |
s = splsoftnet(); /* XXX */ |
| error = (*so->so_proto->pr_usrreq)(so, |
error = (*so->so_proto->pr_usrreq)(so, (flags & MSG_OOB) ? |
| (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND, |
PRU_SENDOOB : PRU_SEND, |
| top, addr, control); |
top, addr, control); |
| splx(s); |
splx(s); |
| if (dontroute) |
if (dontroute) |
| so->so_options &= ~SO_DONTROUTE; |
so->so_options &= ~SO_DONTROUTE; |
| Line 510 soreceive(so, paddr, uio, mp0, controlp, |
|
| Line 506 soreceive(so, paddr, uio, mp0, controlp, |
|
| register int flags, len, error, s, offset; |
register int flags, len, error, s, offset; |
| struct protosw *pr = so->so_proto; |
struct protosw *pr = so->so_proto; |
| struct mbuf *nextrecord; |
struct mbuf *nextrecord; |
| int moff, type; |
int moff, type = 0; |
| int orig_resid = uio->uio_resid; |
int orig_resid = uio->uio_resid; |
| |
|
| mp = mp0; |
mp = mp0; |
| Line 525 soreceive(so, paddr, uio, mp0, controlp, |
|
| Line 521 soreceive(so, paddr, uio, mp0, controlp, |
|
| if (flags & MSG_OOB) { |
if (flags & MSG_OOB) { |
| m = m_get(M_WAIT, MT_DATA); |
m = m_get(M_WAIT, MT_DATA); |
| error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m, |
error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m, |
| (struct mbuf *)(long)(flags & MSG_PEEK), (struct mbuf *)0); |
(struct mbuf *)(long)(flags & MSG_PEEK), |
| |
NULL); |
| if (error) |
if (error) |
| goto bad; |
goto bad; |
| do { |
do { |
|
|
| if (mp) |
if (mp) |
| *mp = (struct mbuf *)0; |
*mp = (struct mbuf *)0; |
| if (so->so_state & SS_ISCONFIRMING && uio->uio_resid) |
if (so->so_state & SS_ISCONFIRMING && uio->uio_resid) |
| (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0, |
(*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL); |
| (struct mbuf *)0, (struct mbuf *)0); |
|
| |
|
| restart: |
restart: |
| if (error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) |
if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0) |
| return (error); |
return (error); |
| s = splsoftnet(); |
s = splsoftnet(); |
| |
|
|
|
| * we have to do the receive in sections, and thus risk returning |
* we have to do the receive in sections, and thus risk returning |
| * a short count if a timeout or signal occurs after we start. |
* a short count if a timeout or signal occurs after we start. |
| */ |
*/ |
| if (m == 0 || ((flags & MSG_DONTWAIT) == 0 && |
if (m == 0 || (((flags & MSG_DONTWAIT) == 0 && |
| so->so_rcv.sb_cc < uio->uio_resid) && |
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 && (pr->pr_flags & PR_ATOMIC) == 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"); |
|
|
| splx(s); |
splx(s); |
| return (0); |
return (0); |
| } |
} |
| if (m = so->so_rcv.sb_mb) |
if ((m = so->so_rcv.sb_mb) != NULL) |
| nextrecord = m->m_nextpkt; |
nextrecord = m->m_nextpkt; |
| } |
} |
| } |
} |
|
|
| if (m == 0) |
if (m == 0) |
| so->so_rcv.sb_mb = nextrecord; |
so->so_rcv.sb_mb = nextrecord; |
| 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, NULL, |
| (struct mbuf *)(long)flags, (struct mbuf *)0, |
(struct mbuf *)(long)flags, NULL); |
| (struct mbuf *)0); |
|
| } |
} |
| if (orig_resid == uio->uio_resid && orig_resid && |
if (orig_resid == uio->uio_resid && orig_resid && |
| (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) { |
(flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) { |
| Line 809 soshutdown(so, how) |
|
| Line 804 soshutdown(so, how) |
|
| if (how & FREAD) |
if (how & FREAD) |
| sorflush(so); |
sorflush(so); |
| if (how & FWRITE) |
if (how & FWRITE) |
| return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN, |
return (*pr->pr_usrreq)(so, PRU_SHUTDOWN, NULL, NULL, NULL); |
| (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)); |
|
| return (0); |
return (0); |
| } |
} |
| |
|