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 rcsdiff: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.4 retrieving revision 1.12 diff -u -p -r1.4 -r1.12 --- src/sys/kern/uipc_socket.c 1993/08/03 01:36:10 1.4 +++ src/sys/kern/uipc_socket.c 1994/04/25 08:41:03 1.12 @@ -31,22 +31,21 @@ * SUCH DAMAGE. * * from: @(#)uipc_socket.c 7.28 (Berkeley) 5/4/91 - * $Id: uipc_socket.c,v 1.4 1993/08/03 01:36:10 cgd Exp $ + * $Id: uipc_socket.c,v 1.12 1994/04/25 08:41:03 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 /* * Socket operation routines. @@ -58,6 +57,7 @@ /*ARGSUSED*/ int socreate(dom, aso, type, proto) + int dom; struct socket **aso; register int type; int proto; @@ -71,7 +71,7 @@ socreate(dom, aso, type, proto) prp = pffindproto(dom, proto, type); else prp = pffindtype(dom, type); - if (prp == 0 || || !prp->pr_usrreq) + if (!prp || !prp->pr_usrreq) return (EPROTONOSUPPORT); if (prp->pr_type != type) return (EPROTOTYPE); @@ -89,6 +89,10 @@ socreate(dom, aso, type, proto) sofree(so); return (error); } +#ifdef COMPAT_SUNOS + if (p->p_emul == EMUL_SUNOS && type == SOCK_DGRAM) + so->so_options |= SO_BROADCAST; +#endif *aso = so; return (0); } @@ -321,7 +325,7 @@ sosend(so, addr, uio, top, control, flag struct mbuf *control; int flags; { - struct proc *p = curproc; /* XXX */ + struct proc *p = curproc; /* XXX */ struct mbuf **mp; register struct mbuf *m; register long space, len, resid; @@ -332,6 +336,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); @@ -360,11 +373,11 @@ restart: space = sbspace(&so->so_snd); if (flags & MSG_OOB) space += 1024; - if (space < resid + clen && + if (atomic && resid > so->so_snd.sb_hiwat || + clen > so->so_snd.sb_hiwat) + snderr(EMSGSIZE); + if (space < resid + clen && uio && (atomic || space < so->so_snd.sb_lowat || space < clen)) { - if (atomic && resid > so->so_snd.sb_hiwat || - clen > so->so_snd.sb_hiwat) - snderr(EMSGSIZE); if (so->so_state & SS_NBIO) snderr(EWOULDBLOCK); sbunlock(&so->so_snd); @@ -395,25 +408,15 @@ restart: MGET(m, M_WAIT, MT_DATA); mlen = MLEN; } - if (resid >= MINCLSIZE && space >= MCLBYTES) { + if (resid >= MINCLSIZE) { MCLGET(m, M_WAIT); 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 - space -= MCLBYTES; + 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. @@ -421,6 +424,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; @@ -488,7 +492,6 @@ soreceive(so, paddr, uio, mp0, controlp, struct mbuf **controlp; int *flagsp; { - struct proc *p = curproc; /* XXX */ register struct mbuf *m, **mp; register int flags, len, error, s, offset; struct protosw *pr = so->so_proto; @@ -589,7 +592,8 @@ restart: goto restart; } dontblock: - p->p_stats->p_ru.ru_msgrcv++; + if (uio->uio_procp) + uio->uio_procp->p_stats->p_ru.ru_msgrcv++; nextrecord = m->m_nextpkt; if (pr->pr_flags & PR_ADDR) { #ifdef DIAGNOSTIC @@ -718,8 +722,11 @@ dontblock: so->so_state |= SS_RCVATMARK; break; } - } else + } else { offset += len; + if (offset == so->so_oobmark) + break; + } } if (flags & MSG_EOR) break;