summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_socket.c
diff options
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r--sys/kern/uipc_socket.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 3d6e12e88bc..8f3ac59436c 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.246 2020/06/18 14:05:21 mvs Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.247 2020/06/22 13:14:32 mpi Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -93,6 +93,12 @@ const struct filterops sowrite_filtops = {
.f_event = filt_sowrite,
};
+const struct filterops soexcept_filtops = {
+ .f_flags = FILTEROP_ISFD,
+ .f_attach = NULL,
+ .f_detach = filt_sordetach,
+ .f_event = filt_soread,
+};
#ifndef SOMINCONN
#define SOMINCONN 80
@@ -2026,6 +2032,10 @@ soo_kqfilter(struct file *fp, struct knote *kn)
kn->kn_fop = &sowrite_filtops;
sb = &so->so_snd;
break;
+ case EVFILT_EXCEPT:
+ kn->kn_fop = &soexcept_filtops;
+ sb = &so->so_rcv;
+ break;
default:
return (EINVAL);
}
@@ -2052,7 +2062,7 @@ int
filt_soread(struct knote *kn, long hint)
{
struct socket *so = kn->kn_fp->f_data;
- int s, rv;
+ int s, rv = 0;
if ((hint & NOTE_SUBMIT) == 0)
s = solock(so);
@@ -2062,7 +2072,13 @@ filt_soread(struct knote *kn, long hint)
rv = 0;
} else
#endif /* SOCKET_SPLICE */
- if (so->so_state & SS_CANTRCVMORE) {
+ if (kn->kn_sfflags & NOTE_OOB) {
+ if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
+ kn->kn_fflags |= NOTE_OOB;
+ kn->kn_data -= so->so_oobmark;
+ rv = 1;
+ }
+ } else if (so->so_state & SS_CANTRCVMORE) {
kn->kn_flags |= EV_EOF;
if (kn->kn_flags & __EV_POLL) {
if (so->so_state & SS_ISDISCONNECTED)