by getting EPIPE from usrreq if disconnected; M_WAIT is here
SCCS-vsn: sys/kern/uipc_socket.c 6.11
-/* uipc_socket.c 6.10 85/04/02 */
+/* uipc_socket.c 6.11 85/05/27 */
#include "param.h"
#include "systm.h"
#include "param.h"
#include "systm.h"
if (prp->pr_type != type)
return (EPROTOTYPE);
m = m_getclr(M_WAIT, MT_SOCKET);
if (prp->pr_type != type)
return (EPROTOTYPE);
m = m_getclr(M_WAIT, MT_SOCKET);
- if (m == 0)
- return (ENOBUFS);
so = mtod(m, struct socket *);
so->so_options = 0;
so->so_state = 0;
so = mtod(m, struct socket *);
so->so_options = 0;
so->so_state = 0;
sblock(&so->so_snd);
do {
s = splnet();
sblock(&so->so_snd);
do {
s = splnet();
- if (so->so_state & SS_CANTSENDMORE) {
- psignal(u.u_procp, SIGPIPE);
+ if (so->so_state & SS_CANTSENDMORE)
if (so->so_error) {
error = so->so_error;
so->so_error = 0; /* ??? */
if (so->so_error) {
error = so->so_error;
so->so_error = 0; /* ??? */
- while (uio->uio_resid > 0 && space > 0) {
register struct iovec *iov = uio->uio_iov;
register struct iovec *iov = uio->uio_iov;
- if (iov->iov_len == 0) {
- uio->uio_iov++;
- uio->uio_iovcnt--;
- if (uio->uio_iovcnt < 0)
- panic("sosend");
- continue;
- }
MGET(m, M_WAIT, MT_DATA);
MGET(m, M_WAIT, MT_DATA);
-if (m == NULL) {
- error = ENOBUFS; /* SIGPIPE? */
- goto release;
-}
if (iov->iov_len >= CLBYTES && space >= CLBYTES) {
register struct mbuf *p;
MCLGET(p, 1);
if (iov->iov_len >= CLBYTES && space >= CLBYTES) {
register struct mbuf *p;
MCLGET(p, 1);
goto release;
mp = &m->m_next;
space -= len;
goto release;
mp = &m->m_next;
space -= len;
+ if (uio->uio_resid <= 0)
+ break;
+ while (uio->uio_iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt <= 0)
+ panic("sosend");
+ }
- if (top) {
- if (dontroute)
- so->so_options |= SO_DONTROUTE;
- s = splnet();
- error = (*so->so_proto->pr_usrreq)(so,
- (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
- top, (caddr_t)nam, rights);
- splx(s);
- if (dontroute)
- so->so_options &= ~SO_DONTROUTE;
- }
+ if (dontroute)
+ so->so_options |= SO_DONTROUTE;
+ s = splnet(); /* XXX */
+ error = (*so->so_proto->pr_usrreq)(so,
+ (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
+ top, (caddr_t)nam, rights);
+ splx(s);
+ if (dontroute)
+ so->so_options &= ~SO_DONTROUTE;
top = 0;
first = 0;
if (error)
top = 0;
first = 0;
if (error)
sbunlock(&so->so_snd);
if (top)
m_freem(top);
sbunlock(&so->so_snd);
if (top)
m_freem(top);
+ if (error == EPIPE)
+ psignal(u.u_procp, SIGPIPE);
*aname = 0;
if (flags & MSG_OOB) {
m = m_get(M_WAIT, MT_DATA);
*aname = 0;
if (flags & MSG_OOB) {
m = m_get(M_WAIT, MT_DATA);
- if (m == 0)
- return (ENOBUFS);
error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
m, (struct mbuf *)0, (struct mbuf *)0);
if (error)
error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
m, (struct mbuf *)0, (struct mbuf *)0);
if (error)
return (ENOPROTOOPT);
} else {
m = m_get(M_WAIT, MT_SOOPTS);
return (ENOPROTOOPT);
} else {
m = m_get(M_WAIT, MT_SOOPTS);
- if (m == NULL)
- return (ENOBUFS);
switch (optname) {
case SO_LINGER:
switch (optname) {
case SO_LINGER: