Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v retrieving revision 1.6 retrieving revision 1.6.2.2 diff -u -p -r1.6 -r1.6.2.2 --- src/sys/kern/uipc_socket.c 1993/09/08 21:12:49 1.6 +++ src/sys/kern/uipc_socket.c 1993/11/06 00:07:55 1.6.2.2 @@ -31,22 +31,24 @@ * SUCH DAMAGE. * * from: @(#)uipc_socket.c 7.28 (Berkeley) 5/4/91 - * $Id: uipc_socket.c,v 1.6 1993/09/08 21:12:49 mycroft Exp $ + * $Id: uipc_socket.c,v 1.6.2.2 1993/11/06 00:07:55 mycroft Exp $ */ -#include "param.h" -#include "systm.h" -#include "proc.h" -#include "file.h" -#include "malloc.h" -#include "mbuf.h" -#include "domain.h" -#include "kernel.h" -#include "select.h" -#include "protosw.h" -#include "socket.h" -#include "socketvar.h" -#include "resourcevar.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* * Socket operation routines. @@ -332,6 +334,15 @@ sosend(so, addr, uio, top, control, flag resid = uio->uio_resid; else 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 = (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 && (so->so_proto->pr_flags & PR_ATOMIC); @@ -400,21 +411,10 @@ restart: if ((m->m_flags & M_EXT) == 0) goto nopages; mlen = MCLBYTES; -#ifdef MAPPED_MBUFS - 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; + len = min(min(mlen, resid), space); } else { nopages: len = min(min(mlen, resid), space); - space -= len; /* * For datagram protocols, leave room * for protocol headers in first mbuf. @@ -422,6 +422,7 @@ nopages: if (atomic && top == 0 && len < mlen) MH_ALIGN(m, len); } + space -= len; error = uiomove(mtod(m, caddr_t), (int)len, uio); resid = uio->uio_resid; m->m_len = len; @@ -719,8 +720,11 @@ dontblock: so->so_state |= SS_RCVATMARK; break; } - } else + } else { offset += len; + if (offset == so->so_oobmark) + break; + } } if (flags & MSG_EOR) break;