Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/uipc_socket.c
Show First 20 Lines • Show All 1,948 Lines • ▼ Show 20 Lines | restart: | ||||
*/ | */ | ||||
if (m == NULL || (((flags & MSG_DONTWAIT) == 0 && | if (m == NULL || (((flags & MSG_DONTWAIT) == 0 && | ||||
sbavail(&so->so_rcv) < uio->uio_resid) && | sbavail(&so->so_rcv) < uio->uio_resid) && | ||||
sbavail(&so->so_rcv) < so->so_rcv.sb_lowat && | sbavail(&so->so_rcv) < so->so_rcv.sb_lowat && | ||||
m->m_nextpkt == NULL && (pr->pr_flags & PR_ATOMIC) == 0)) { | m->m_nextpkt == NULL && (pr->pr_flags & PR_ATOMIC) == 0)) { | ||||
KASSERT(m != NULL || !sbavail(&so->so_rcv), | KASSERT(m != NULL || !sbavail(&so->so_rcv), | ||||
("receive: m == %p sbavail == %u", | ("receive: m == %p sbavail == %u", | ||||
m, sbavail(&so->so_rcv))); | m, sbavail(&so->so_rcv))); | ||||
if (so->so_error) { | if (so->so_error || so->so_rerror) { | ||||
if (m != NULL) | if (m != NULL) | ||||
goto dontblock; | goto dontblock; | ||||
if (so->so_error) | |||||
error = so->so_error; | error = so->so_error; | ||||
if ((flags & MSG_PEEK) == 0) | else | ||||
error = so->so_rerror; | |||||
if ((flags & MSG_PEEK) == 0) { | |||||
if (so->so_error) | |||||
so->so_error = 0; | so->so_error = 0; | ||||
else | |||||
so->so_rerror = 0; | |||||
} | |||||
SOCKBUF_UNLOCK(&so->so_rcv); | SOCKBUF_UNLOCK(&so->so_rcv); | ||||
goto release; | goto release; | ||||
} | } | ||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv); | SOCKBUF_LOCK_ASSERT(&so->so_rcv); | ||||
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { | if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { | ||||
if (m != NULL) | if (m != NULL) | ||||
goto dontblock; | goto dontblock; | ||||
#ifdef KERN_TLS | #ifdef KERN_TLS | ||||
▲ Show 20 Lines • Show All 327 Lines • ▼ Show 20 Lines | while (m != NULL && !(m->m_flags & M_NOTAVAIL) && uio->uio_resid > 0 | ||||
* must not quit until "uio->uio_resid == 0" or an error | * must not quit until "uio->uio_resid == 0" or an error | ||||
* termination. If a signal/timeout occurs, return with a | * termination. If a signal/timeout occurs, return with a | ||||
* short count but without error. Keep sockbuf locked | * short count but without error. Keep sockbuf locked | ||||
* against other readers. | * against other readers. | ||||
*/ | */ | ||||
while (flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 && | while (flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 && | ||||
!sosendallatonce(so) && nextrecord == NULL) { | !sosendallatonce(so) && nextrecord == NULL) { | ||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv); | SOCKBUF_LOCK_ASSERT(&so->so_rcv); | ||||
if (so->so_error || | if (so->so_error || so->so_rerror || | ||||
so->so_rcv.sb_state & SBS_CANTRCVMORE) | so->so_rcv.sb_state & SBS_CANTRCVMORE) | ||||
break; | break; | ||||
/* | /* | ||||
* Notify the protocol that some data has been | * Notify the protocol that some data has been | ||||
* drained before blocking. | * drained before blocking. | ||||
*/ | */ | ||||
if (pr->pr_flags & PR_WANTRCVD) { | if (pr->pr_flags & PR_WANTRCVD) { | ||||
SOCKBUF_UNLOCK(&so->so_rcv); | SOCKBUF_UNLOCK(&so->so_rcv); | ||||
▲ Show 20 Lines • Show All 724 Lines • ▼ Show 20 Lines | if (sopt->sopt_level != SOL_SOCKET) { | ||||
case SO_REUSEPORT: | case SO_REUSEPORT: | ||||
case SO_REUSEPORT_LB: | case SO_REUSEPORT_LB: | ||||
case SO_OOBINLINE: | case SO_OOBINLINE: | ||||
case SO_TIMESTAMP: | case SO_TIMESTAMP: | ||||
case SO_BINTIME: | case SO_BINTIME: | ||||
case SO_NOSIGPIPE: | case SO_NOSIGPIPE: | ||||
case SO_NO_DDP: | case SO_NO_DDP: | ||||
case SO_NO_OFFLOAD: | case SO_NO_OFFLOAD: | ||||
case SO_RERROR: | |||||
error = sooptcopyin(sopt, &optval, sizeof optval, | error = sooptcopyin(sopt, &optval, sizeof optval, | ||||
sizeof optval); | sizeof optval); | ||||
if (error) | if (error) | ||||
goto bad; | goto bad; | ||||
SOCK_LOCK(so); | SOCK_LOCK(so); | ||||
if (optval) | if (optval) | ||||
so->so_options |= sopt->sopt_name; | so->so_options |= sopt->sopt_name; | ||||
else | else | ||||
▲ Show 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | if (sopt->sopt_level != SOL_SOCKET) { | ||||
case SO_BROADCAST: | case SO_BROADCAST: | ||||
case SO_OOBINLINE: | case SO_OOBINLINE: | ||||
case SO_ACCEPTCONN: | case SO_ACCEPTCONN: | ||||
case SO_TIMESTAMP: | case SO_TIMESTAMP: | ||||
case SO_BINTIME: | case SO_BINTIME: | ||||
case SO_NOSIGPIPE: | case SO_NOSIGPIPE: | ||||
case SO_NO_DDP: | case SO_NO_DDP: | ||||
case SO_NO_OFFLOAD: | case SO_NO_OFFLOAD: | ||||
case SO_RERROR: | |||||
optval = so->so_options & sopt->sopt_name; | optval = so->so_options & sopt->sopt_name; | ||||
integer: | integer: | ||||
error = sooptcopyout(sopt, &optval, sizeof optval); | error = sooptcopyout(sopt, &optval, sizeof optval); | ||||
break; | break; | ||||
case SO_DOMAIN: | case SO_DOMAIN: | ||||
optval = so->so_proto->pr_domain->dom_family; | optval = so->so_proto->pr_domain->dom_family; | ||||
goto integer; | goto integer; | ||||
case SO_TYPE: | case SO_TYPE: | ||||
optval = so->so_type; | optval = so->so_type; | ||||
goto integer; | goto integer; | ||||
case SO_PROTOCOL: | case SO_PROTOCOL: | ||||
optval = so->so_proto->pr_protocol; | optval = so->so_proto->pr_protocol; | ||||
goto integer; | goto integer; | ||||
case SO_ERROR: | case SO_ERROR: | ||||
SOCK_LOCK(so); | SOCK_LOCK(so); | ||||
if (so->so_error) { | |||||
optval = so->so_error; | optval = so->so_error; | ||||
so->so_error = 0; | so->so_error = 0; | ||||
} else { | |||||
optval = so->so_rerror; | |||||
so->so_rerror = 0; | |||||
} | |||||
SOCK_UNLOCK(so); | SOCK_UNLOCK(so); | ||||
goto integer; | goto integer; | ||||
case SO_SNDBUF: | case SO_SNDBUF: | ||||
optval = SOLISTENING(so) ? so->sol_sbsnd_hiwat : | optval = SOLISTENING(so) ? so->sol_sbsnd_hiwat : | ||||
so->so_snd.sb_hiwat; | so->so_snd.sb_hiwat; | ||||
goto integer; | goto integer; | ||||
▲ Show 20 Lines • Show All 532 Lines • ▼ Show 20 Lines | filt_soread(struct knote *kn, long hint) | ||||
SOCKBUF_LOCK_ASSERT(&so->so_rcv); | SOCKBUF_LOCK_ASSERT(&so->so_rcv); | ||||
kn->kn_data = sbavail(&so->so_rcv) - so->so_rcv.sb_ctl; | kn->kn_data = sbavail(&so->so_rcv) - so->so_rcv.sb_ctl; | ||||
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { | if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { | ||||
kn->kn_flags |= EV_EOF; | kn->kn_flags |= EV_EOF; | ||||
kn->kn_fflags = so->so_error; | kn->kn_fflags = so->so_error; | ||||
return (1); | return (1); | ||||
} else if (so->so_error) /* temporary udp error */ | } else if (so->so_error || so->so_rerror) | ||||
return (1); | return (1); | ||||
if (kn->kn_sfflags & NOTE_LOWAT) { | if (kn->kn_sfflags & NOTE_LOWAT) { | ||||
if (kn->kn_data >= kn->kn_sdata) | if (kn->kn_data >= kn->kn_sdata) | ||||
return (1); | return (1); | ||||
} else if (sbavail(&so->so_rcv) >= so->so_rcv.sb_lowat) | } else if (sbavail(&so->so_rcv) >= so->so_rcv.sb_lowat) | ||||
return (1); | return (1); | ||||
▲ Show 20 Lines • Show All 579 Lines • Show Last 20 Lines |