git: 2a5e58c59694 - main - procdesc: add NOTE_PDSIGCHLD

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 13 Jul 2026 03:12:52 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=2a5e58c59694bc719d7ab82abb1c65ee2045329d

commit 2a5e58c59694bc719d7ab82abb1c65ee2045329d
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-07-09 11:08:45 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-07-13 03:12:39 +0000

    procdesc: add NOTE_PDSIGCHLD
    
    The note type wakes up when there is something for pdwait(2) to report
    on the process descriptor.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D58123
---
 sys/kern/kern_sig.c     |  2 ++
 sys/kern/sys_procdesc.c | 25 +++++++++++++++++++++----
 sys/sys/event.h         |  9 ++++++---
 sys/sys/procdesc.h      |  1 +
 4 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 4c66ed24baf1..30f6b69da9ef 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2315,6 +2315,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
 
 	ps = p->p_sigacts;
 	KNOTE_LOCKED(p->p_klist, NOTE_SIGNAL | sig);
+	procdesc_jobstate(p);
 	prop = sigprop(sig);
 
 	if (td == NULL) {
@@ -3682,6 +3683,7 @@ childproc_jobstate(struct proc *p, int reason, int sig)
 	 */
 	p->p_pptr->p_flag |= P_STATCHILD;
 	wakeup(p->p_pptr);
+	procdesc_jobstate(p);
 
 	ps = p->p_pptr->p_sigacts;
 	mtx_lock(&ps->ps_mtx);
diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c
index 7351df11c631..0d26c2031b28 100644
--- a/sys/kern/sys_procdesc.c
+++ b/sys/kern/sys_procdesc.c
@@ -64,6 +64,7 @@
 
 #include <sys/param.h>
 #include <sys/capsicum.h>
+#include <sys/event.h>
 #include <sys/fcntl.h>
 #include <sys/file.h>
 #include <sys/filedesc.h>
@@ -347,7 +348,7 @@ procdesc_exit(struct proc *p)
 		return (1);
 	}
 	selwakeup(&pd->pd_selinfo);
-	KNOTE_LOCKED(&pd->pd_selinfo.si_note, NOTE_EXIT);
+	KNOTE_LOCKED(&pd->pd_selinfo.si_note, NOTE_EXIT | NOTE_PDSIGCHLD);
 	PROCDESC_UNLOCK(pd);
 
 	/* Wakeup all waiters for this procdesc' process exit. */
@@ -355,6 +356,21 @@ procdesc_exit(struct proc *p)
 	return (0);
 }
 
+void
+procdesc_jobstate(struct proc *p)
+{
+	struct procdesc *pd;
+
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+	pd = p->p_procdesc;
+	if (pd == NULL)
+		return;
+
+	PROCDESC_LOCK(pd);
+	KNOTE_LOCKED(&pd->pd_selinfo.si_note, NOTE_PDSIGCHLD);
+	PROCDESC_UNLOCK(pd);
+}
+
 /*
  * When a process descriptor is reaped, perhaps as a result of close(), release
  * the process's reference on the process descriptor.
@@ -502,10 +518,11 @@ procdesc_kqops_event(struct knote *kn, long hint)
 	pd = kn->kn_fp->f_data;
 	if (hint == 0) {
 		/*
-		 * Initial test after registration. Generate a NOTE_EXIT in
+		 * Initial test after registration.  Generate notes in
 		 * case the process already terminated before registration.
 		 */
-		event = pd->pd_flags & PDF_EXITED ? NOTE_EXIT : 0;
+		event = (pd->pd_flags & PDF_EXITED) != 0 ? (NOTE_EXIT |
+		    NOTE_PDSIGCHLD) : 0;
 	} else {
 		/* Mask off extra data. */
 		event = (u_int)hint & NOTE_PCTRLMASK;
@@ -516,7 +533,7 @@ procdesc_kqops_event(struct knote *kn, long hint)
 		kn->kn_fflags |= event;
 
 	/* Process is gone, so flag the event as finished. */
-	if (event == NOTE_EXIT) {
+	if ((event & NOTE_EXIT) != 0) {
 		kn->kn_flags |= EV_EOF | EV_ONESHOT;
 		if (kn->kn_fflags & NOTE_EXIT)
 			kn->kn_data = pd->pd_xstat;
diff --git a/sys/sys/event.h b/sys/sys/event.h
index de24c9226e4a..ed215453a325 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -202,9 +202,12 @@ struct freebsd11_kevent32 {
 /*
  * data/hint flags for EVFILT_PROC and EVFILT_PROCDESC, shared with userspace
  */
-#define	NOTE_EXIT	0x80000000		/* process exited */
-#define	NOTE_FORK	0x40000000		/* process forked */
-#define	NOTE_EXEC	0x20000000		/* process exec'd */
+#define	NOTE_EXIT	0x80000000		/* proc/procdesc: process
+						   exited */
+#define	NOTE_FORK	0x40000000		/* proc: process forked */
+#define	NOTE_EXEC	0x20000000		/* proc: process exec'd */
+#define	NOTE_PDSIGCHLD	0x10000000		/* procdesc: pdwait() info
+						   available */
 #define	NOTE_PCTRLMASK	0xf0000000		/* mask for hint bits */
 #define	NOTE_PDATAMASK	0x000fffff		/* mask for pid */
 
diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h
index b332f73744de..dafa3326384d 100644
--- a/sys/sys/procdesc.h
+++ b/sys/sys/procdesc.h
@@ -104,6 +104,7 @@ struct procdesc {
 int	 procdesc_exit(struct proc *);
 int	 procdesc_find(struct thread *, int fd, const cap_rights_t *,
 	    struct proc **);
+void	 procdesc_jobstate(struct proc *p);
 int	 kern_pdgetpid(struct thread *, int fd, const cap_rights_t *,
 	    pid_t *pidp);
 void	 procdesc_new(struct proc *, int);