diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2315,6 +2315,7 @@ 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 @@ */ 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 --- a/sys/kern/sys_procdesc.c +++ b/sys/kern/sys_procdesc.c @@ -64,6 +64,7 @@ #include #include +#include #include #include #include @@ -347,7 +348,7 @@ 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 @@ 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 @@ 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 @@ 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 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -202,9 +202,12 @@ /* * 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 --- a/sys/sys/procdesc.h +++ b/sys/sys/procdesc.h @@ -104,6 +104,7 @@ 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);