/*
* Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * All rights reserved.
*
- * @(#)uipc_socket.c 7.3 (Berkeley) %G%
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ *
+ * @(#)uipc_socket.c 7.7 (Berkeley) %G%
*/
#include "param.h"
-#include "systm.h"
#include "dir.h"
#include "user.h"
#include "proc.h"
#include "file.h"
-#include "inode.h"
-#include "buf.h"
#include "mbuf.h"
-#include "un.h"
#include "domain.h"
#include "protosw.h"
#include "socket.h"
#include "socketvar.h"
-#include "stat.h"
-#include "ioctl.h"
-#include "uio.h"
-#include "../net/route.h"
-#include "../netinet/in.h"
-#include "../net/if.h"
/*
* Socket operation routines.
struct mbuf **rightsp;
{
register struct mbuf *m;
- register int len, error = 0, s, tomark;
+ register int len, error = 0, s, offset;
struct protosw *pr = so->so_proto;
struct mbuf *nextrecord;
int moff;
sblock(&so->so_rcv);
s = splnet();
-#define rcverr(errno) { error = errno; splx(s); goto release; }
if (so->so_rcv.sb_cc == 0) {
if (so->so_error) {
error = so->so_error;
so->so_error = 0;
- splx(s);
goto release;
}
- if (so->so_state & SS_CANTRCVMORE) {
- splx(s);
+ if (so->so_state & SS_CANTRCVMORE)
goto release;
- }
if ((so->so_state & SS_ISCONNECTED) == 0 &&
- (so->so_proto->pr_flags & PR_CONNREQUIRED))
- rcverr(ENOTCONN);
+ (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
+ error = ENOTCONN;
+ goto release;
+ }
if (uio->uio_resid == 0)
goto release;
- if (so->so_state & SS_NBIO)
- rcverr(EWOULDBLOCK);
+ if (so->so_state & SS_NBIO) {
+ error = EWOULDBLOCK;
+ goto release;
+ }
sbunlock(&so->so_rcv);
sbwait(&so->so_rcv);
splx(s);
}
}
moff = 0;
- tomark = so->so_oobmark;
+ offset = 0;
while (m && uio->uio_resid > 0 && error == 0) {
if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
panic("receive 3");
len = uio->uio_resid;
so->so_state &= ~SS_RCVATMARK;
- if (tomark && len > tomark)
- len = tomark;
+ if (so->so_oobmark && len > so->so_oobmark - offset)
+ len = so->so_oobmark - offset;
if (len > m->m_len - moff)
len = m->m_len - moff;
splx(s);
so->so_rcv.sb_cc -= len;
}
}
- if ((flags & MSG_PEEK) == 0 && so->so_oobmark) {
- so->so_oobmark -= len;
- if (so->so_oobmark == 0) {
- so->so_state |= SS_RCVATMARK;
- break;
- }
- }
- if (tomark) {
- tomark -= len;
- if (tomark == 0)
- break;
+ if (so->so_oobmark) {
+ if ((flags & MSG_PEEK) == 0) {
+ so->so_oobmark -= len;
+ if (so->so_oobmark == 0) {
+ so->so_state |= SS_RCVATMARK;
+ break;
+ }
+ } else
+ offset += len;
}
}
if ((flags & MSG_PEEK) == 0) {