On 13/06/20(Sat) 05:54, Todd C. Miller wrote:
> On Sat, 13 Jun 2020 10:05:19 +0200, Martin Pieuchot wrote:
>
> > Diff below extends the existing kqfilter handlers to be able to set
> > POLLHUP in the new poll(2) implementation.
> >
> > __EV_HUP is introduced and now set for this purpose. A new kqfilter
> > for deadfs is introduced to match the existing poll handler.
>
> OK. I wonder if POLLERR is actually more appropriate for this but
> I understand you are just matching existing behavior at this point.
>
> > __EV_HUP is not exactly like EV_EOF. Very few handlers set POLLHUP so
> > this approach is conservative.
>
> Right, there are some subtle differences.
>
> > __EV_HUP reuses the EV_FLAG1 flag which isn't used for `file_filtops'.
> > We could decided to set it only if __EV_POLL is set which should ensure
> > it is not exported to userland. Is it desirable?
>
> I think that would be safest.
Here's an updated diff that does that and move the defines under _KERNEL
as suggested by visa@. I left the dead-filter for another diff to match
another suggestion.
ok?
Index: kern/sys_pipe.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_pipe.c,v
retrieving revision 1.119
diff -u -p -r1.119 sys_pipe.c
--- kern/sys_pipe.c 7 Apr 2020 13:27:51 -0000 1.119
+++ kern/sys_pipe.c 15 Jun 2020 06:15:50 -0000
@@ -967,6 +967,8 @@ filt_piperead(struct knote *kn, long hin
if ((hint & NOTE_SUBMIT) == 0)
rw_exit_read(lock);
kn->kn_flags |= EV_EOF;
+ if (kn->kn_flags & __EV_POLL)
+ kn->kn_flags |= __EV_HUP;
return (1);
}
@@ -991,6 +993,8 @@ filt_pipewrite(struct knote *kn, long hi
rw_exit_read(lock);
kn->kn_data = 0;
kn->kn_flags |= EV_EOF;
+ if (kn->kn_flags & __EV_POLL)
+ kn->kn_flags |= __EV_HUP;
return (1);
}
kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
Index: kern/tty.c
===================================================================
RCS file: /cvs/src/sys/kern/tty.c,v
retrieving revision 1.156
diff -u -p -r1.156 tty.c
--- kern/tty.c 29 May 2020 04:42:25 -0000 1.156
+++ kern/tty.c 15 Jun 2020 06:15:50 -0000
@@ -1155,6 +1155,8 @@ filt_ttyread(struct knote *kn, long hint
splx(s);
if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
kn->kn_flags |= EV_EOF;
+ if (kn->kn_flags & __EV_POLL)
+ kn->kn_flags |= __EV_HUP;
return (1);
}
return (kn->kn_data > 0);
Index: kern/tty_pty.c
===================================================================
RCS file: /cvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.99
diff -u -p -r1.99 tty_pty.c
--- kern/tty_pty.c 21 May 2020 09:34:06 -0000 1.99
+++ kern/tty_pty.c 15 Jun 2020 06:15:50 -0000
@@ -678,6 +678,8 @@ filt_ptcread(struct knote *kn, long hint
if (!ISSET(tp->t_state, TS_CARR_ON)) {
kn->kn_flags |= EV_EOF;
+ if (kn->kn_flags & __EV_POLL)
+ kn->kn_flags |= __EV_HUP;
return (1);
}
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.244
diff -u -p -r1.244 uipc_socket.c
--- kern/uipc_socket.c 12 Apr 2020 16:15:18 -0000 1.244
+++ kern/uipc_socket.c 15 Jun 2020 06:15:50 -0000
@@ -2064,6 +2064,10 @@ filt_soread(struct knote *kn, long hint)
#endif /* SOCKET_SPLICE */
if (so->so_state & SS_CANTRCVMORE) {
kn->kn_flags |= EV_EOF;
+ if (kn->kn_flags & __EV_POLL) {
+ if (so->so_state & SS_ISDISCONNECTED)
+ kn->kn_flags |= __EV_HUP;
+ }
kn->kn_fflags = so->so_error;
rv = 1;
} else if (so->so_error) { /* temporary udp error */
@@ -2102,6 +2106,10 @@ filt_sowrite(struct knote *kn, long hint
kn->kn_data = sbspace(so, &so->so_snd);
if (so->so_state & SS_CANTSENDMORE) {
kn->kn_flags |= EV_EOF;
+ if (kn->kn_flags & __EV_POLL) {
+ if (so->so_state & SS_ISDISCONNECTED)
+ kn->kn_flags |= __EV_HUP;
+ }
kn->kn_fflags = so->so_error;
rv = 1;
} else if (so->so_error) { /* temporary udp error */
Index: miscfs/fifofs/fifo_vnops.c
===================================================================
RCS file: /cvs/src/sys/miscfs/fifofs/fifo_vnops.c,v
retrieving revision 1.76
diff -u -p -r1.76 fifo_vnops.c
--- miscfs/fifofs/fifo_vnops.c 8 Apr 2020 08:07:52 -0000 1.76
+++ miscfs/fifofs/fifo_vnops.c 15 Jun 2020 06:15:50 -0000
@@ -559,6 +559,8 @@ filt_fiforead(struct knote *kn, long hin
kn->kn_data = so->so_rcv.sb_cc;
if (so->so_state & SS_CANTRCVMORE) {
kn->kn_flags |= EV_EOF;
+ if (so->so_state & SS_ISDISCONNECTED)
+ kn->kn_flags |= __EV_HUP;
rv = 1;
} else {
kn->kn_flags &= ~EV_EOF;
Index: sys/event.h
===================================================================
RCS file: /cvs/src/sys/sys/event.h,v
retrieving revision 1.41
diff -u -p -r1.41 event.h
--- sys/event.h 12 Jun 2020 09:34:17 -0000 1.41
+++ sys/event.h 15 Jun 2020 06:15:50 -0000
@@ -74,7 +74,6 @@ struct kevent {
#define EV_DISPATCH 0x0080 /* disable event after reporting */
#define EV_SYSFLAGS 0xF000 /* reserved by system */
-#define __EV_POLL 0x1000 /* match behavior of poll & select */
#define EV_FLAG1 0x2000 /* filter-specific flag */
/* returned values */
@@ -129,6 +128,10 @@ struct klist {
};
#ifdef _KERNEL
+
+/* kernel-only flags */
+#define __EV_POLL 0x1000 /* match behavior of poll & select */
+#define __EV_HUP EV_FLAG1 /* device or socket disconnected */
#define EVFILT_MARKER 0xf /* placemarker for tailq */