| version 1.6, 1993/09/08 21:12:49 |
version 1.6.2.2, 1993/11/06 00:07:55 |
|
|
| * $Id$ |
* $Id$ |
| */ |
*/ |
| |
|
| #include "param.h" |
#include <sys/param.h> |
| #include "systm.h" |
#include <sys/systm.h> |
| #include "proc.h" |
#include <sys/proc.h> |
| #include "file.h" |
#include <sys/file.h> |
| #include "malloc.h" |
#include <sys/malloc.h> |
| #include "mbuf.h" |
#include <sys/mbuf.h> |
| #include "domain.h" |
#include <sys/domain.h> |
| #include "kernel.h" |
#include <sys/kernel.h> |
| #include "select.h" |
#include <sys/select.h> |
| #include "protosw.h" |
#include <sys/protosw.h> |
| #include "socket.h" |
#include <sys/socket.h> |
| #include "socketvar.h" |
#include <sys/socketvar.h> |
| #include "resourcevar.h" |
#include <sys/resourcevar.h> |
| |
|
| |
#include <machine/cpu.h> |
| |
|
| /* |
/* |
| * Socket operation routines. |
* Socket operation routines. |
| Line 332 sosend(so, addr, uio, top, control, flag |
|
| Line 334 sosend(so, addr, uio, top, control, flag |
|
| resid = uio->uio_resid; |
resid = uio->uio_resid; |
| else |
else |
| resid = top->m_pkthdr.len; |
resid = top->m_pkthdr.len; |
| |
/* |
| |
* In theory resid should be unsigned. |
| |
* However, space must be signed, as it might be less than 0 |
| |
* if we over-committed, and we must use a signed comparison |
| |
* of space and resid. On the other hand, a negative resid |
| |
* causes us to loop sending 0-length segments to the protocol. |
| |
*/ |
| |
if (resid < 0) |
| |
return (EINVAL); |
| dontroute = |
dontroute = |
| (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 && |
(flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 && |
| (so->so_proto->pr_flags & PR_ATOMIC); |
(so->so_proto->pr_flags & PR_ATOMIC); |
|
|
| if ((m->m_flags & M_EXT) == 0) |
if ((m->m_flags & M_EXT) == 0) |
| goto nopages; |
goto nopages; |
| mlen = MCLBYTES; |
mlen = MCLBYTES; |
| #ifdef MAPPED_MBUFS |
len = min(min(mlen, resid), space); |
| len = min(MCLBYTES, resid); |
|
| #else |
|
| if (top == 0) { |
|
| len = min(MCLBYTES - max_hdr, resid); |
|
| m->m_data += max_hdr; |
|
| } else |
|
| len = min(MCLBYTES, resid); |
|
| #endif |
|
| len = min(len, space); |
|
| space -= len; |
|
| } else { |
} else { |
| nopages: |
nopages: |
| len = min(min(mlen, resid), space); |
len = min(min(mlen, resid), space); |
| space -= len; |
|
| /* |
/* |
| * For datagram protocols, leave room |
* For datagram protocols, leave room |
| * for protocol headers in first mbuf. |
* for protocol headers in first mbuf. |
|
|
| if (atomic && top == 0 && len < mlen) |
if (atomic && top == 0 && len < mlen) |
| MH_ALIGN(m, len); |
MH_ALIGN(m, len); |
| } |
} |
| |
space -= len; |
| error = uiomove(mtod(m, caddr_t), (int)len, uio); |
error = uiomove(mtod(m, caddr_t), (int)len, uio); |
| resid = uio->uio_resid; |
resid = uio->uio_resid; |
| m->m_len = len; |
m->m_len = len; |
|
|
| so->so_state |= SS_RCVATMARK; |
so->so_state |= SS_RCVATMARK; |
| break; |
break; |
| } |
} |
| } else |
} else { |
| offset += len; |
offset += len; |
| |
if (offset == so->so_oobmark) |
| |
break; |
| |
} |
| } |
} |
| if (flags & MSG_EOR) |
if (flags & MSG_EOR) |
| break; |
break; |