-/* $OpenBSD: uipc_socket.c,v 1.262 2021/05/25 22:45:09 bluhm Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.263 2021/05/28 16:24:53 visa Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
void filt_sordetach(struct knote *kn);
int filt_soread(struct knote *kn, long hint);
+int filt_soreadmodify(struct kevent *kev, struct knote *kn);
+int filt_soreadprocess(struct knote *kn, struct kevent *kev);
+int filt_soread_common(struct knote *kn, struct socket *so);
void filt_sowdetach(struct knote *kn);
int filt_sowrite(struct knote *kn, long hint);
+int filt_sowritemodify(struct kevent *kev, struct knote *kn);
+int filt_sowriteprocess(struct knote *kn, struct kevent *kev);
+int filt_sowrite_common(struct knote *kn, struct socket *so);
int filt_solisten(struct knote *kn, long hint);
+int filt_solistenmodify(struct kevent *kev, struct knote *kn);
+int filt_solistenprocess(struct knote *kn, struct kevent *kev);
+int filt_solisten_common(struct knote *kn, struct socket *so);
const struct filterops solisten_filtops = {
.f_flags = FILTEROP_ISFD,
.f_attach = NULL,
.f_detach = filt_sordetach,
.f_event = filt_solisten,
+ .f_modify = filt_solistenmodify,
+ .f_process = filt_solistenprocess,
};
const struct filterops soread_filtops = {
.f_attach = NULL,
.f_detach = filt_sordetach,
.f_event = filt_soread,
+ .f_modify = filt_soreadmodify,
+ .f_process = filt_soreadprocess,
};
const struct filterops sowrite_filtops = {
.f_attach = NULL,
.f_detach = filt_sowdetach,
.f_event = filt_sowrite,
+ .f_modify = filt_sowritemodify,
+ .f_process = filt_sowriteprocess,
};
const struct filterops soexcept_filtops = {
.f_attach = NULL,
.f_detach = filt_sordetach,
.f_event = filt_soread,
+ .f_modify = filt_soreadmodify,
+ .f_process = filt_soreadprocess,
};
#ifndef SOMINCONN
}
int
-filt_soread(struct knote *kn, long hint)
+filt_soread_common(struct knote *kn, struct socket *so)
{
- struct socket *so = kn->kn_fp->f_data;
- int s, rv = 0;
+ int rv = 0;
+
+ soassertlocked(so);
- if ((hint & NOTE_SUBMIT) == 0)
- s = solock(so);
kn->kn_data = so->so_rcv.sb_cc;
#ifdef SOCKET_SPLICE
if (isspliced(so)) {
} else {
rv = (kn->kn_data >= so->so_rcv.sb_lowat);
}
- if ((hint & NOTE_SUBMIT) == 0)
- sounlock(so, s);
return rv;
}
+int
+filt_soread(struct knote *kn, long hint)
+{
+ struct socket *so = kn->kn_fp->f_data;
+
+ return (filt_soread_common(kn, so));
+}
+
+int
+filt_soreadmodify(struct kevent *kev, struct knote *kn)
+{
+ struct socket *so = kn->kn_fp->f_data;
+ int rv, s;
+
+ s = solock(so);
+ knote_modify(kev, kn);
+ rv = filt_soread_common(kn, so);
+ sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_soreadprocess(struct knote *kn, struct kevent *kev)
+{
+ struct socket *so = kn->kn_fp->f_data;
+ int rv, s;
+
+ s = solock(so);
+ if (kev != NULL && (kn->kn_flags & EV_ONESHOT))
+ rv = 1;
+ else
+ rv = filt_soread_common(kn, so);
+ if (rv != 0)
+ knote_submit(kn, kev);
+ sounlock(so, s);
+
+ return (rv);
+}
+
void
filt_sowdetach(struct knote *kn)
{
}
int
-filt_sowrite(struct knote *kn, long hint)
+filt_sowrite_common(struct knote *kn, struct socket *so)
{
- struct socket *so = kn->kn_fp->f_data;
- int s, rv;
+ int rv;
+
+ soassertlocked(so);
- if ((hint & NOTE_SUBMIT) == 0)
- s = solock(so);
kn->kn_data = sbspace(so, &so->so_snd);
if (so->so_state & SS_CANTSENDMORE) {
kn->kn_flags |= EV_EOF;
} else {
rv = (kn->kn_data >= so->so_snd.sb_lowat);
}
- if ((hint & NOTE_SUBMIT) == 0)
- sounlock(so, s);
return (rv);
}
int
-filt_solisten(struct knote *kn, long hint)
+filt_sowrite(struct knote *kn, long hint)
{
struct socket *so = kn->kn_fp->f_data;
- int s;
- if ((hint & NOTE_SUBMIT) == 0)
- s = solock(so);
+ return (filt_sowrite_common(kn, so));
+}
+
+int
+filt_sowritemodify(struct kevent *kev, struct knote *kn)
+{
+ struct socket *so = kn->kn_fp->f_data;
+ int rv, s;
+
+ s = solock(so);
+ knote_modify(kev, kn);
+ rv = filt_sowrite_common(kn, so);
+ sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_sowriteprocess(struct knote *kn, struct kevent *kev)
+{
+ struct socket *so = kn->kn_fp->f_data;
+ int rv, s;
+
+ s = solock(so);
+ if (kev != NULL && (kn->kn_flags & EV_ONESHOT))
+ rv = 1;
+ else
+ rv = filt_sowrite_common(kn, so);
+ if (rv != 0)
+ knote_submit(kn, kev);
+ sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_solisten_common(struct knote *kn, struct socket *so)
+{
+ soassertlocked(so);
+
kn->kn_data = so->so_qlen;
- if ((hint & NOTE_SUBMIT) == 0)
- sounlock(so, s);
return (kn->kn_data != 0);
}
+int
+filt_solisten(struct knote *kn, long hint)
+{
+ struct socket *so = kn->kn_fp->f_data;
+
+ return (filt_solisten_common(kn, so));
+}
+
+int
+filt_solistenmodify(struct kevent *kev, struct knote *kn)
+{
+ struct socket *so = kn->kn_fp->f_data;
+ int rv, s;
+
+ s = solock(so);
+ knote_modify(kev, kn);
+ rv = filt_solisten_common(kn, so);
+ sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_solistenprocess(struct knote *kn, struct kevent *kev)
+{
+ struct socket *so = kn->kn_fp->f_data;
+ int rv, s;
+
+ s = solock(so);
+ if (kev != NULL && (kn->kn_flags & EV_ONESHOT))
+ rv = 1;
+ else
+ rv = filt_solisten_common(kn, so);
+ if (rv != 0)
+ knote_submit(kn, kev);
+ sounlock(so, s);
+
+ return (rv);
+}
+
#ifdef DDB
void
sobuf_print(struct sockbuf *,