kern/kern_exit.c: extract some helpers from proc_to_reap()

Reviewed by:	asomers, markj
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D54592
This commit is contained in:
Konstantin Belousov
2026-01-08 06:19:04 +02:00
parent 109b9f48ec
commit 2b67cfa39d
+66 -50
View File
@@ -1042,13 +1042,75 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
atomic_add_int(&nprocs, -1);
}
static void
wait_fill_siginfo(struct proc *p, siginfo_t *siginfo)
{
PROC_LOCK_ASSERT(p, MA_OWNED);
if (siginfo == NULL)
return;
bzero(siginfo, sizeof(*siginfo));
siginfo->si_errno = 0;
/*
* SUSv4 requires that the si_signo value is always
* SIGCHLD. Obey it despite the rfork(2) interface allows to
* request other signal for child exit notification.
*/
siginfo->si_signo = SIGCHLD;
/*
* This is still a rough estimate. We will fix the cases
* TRAPPED, STOPPED, and CONTINUED later.
*/
if (WCOREDUMP(p->p_xsig)) {
siginfo->si_code = CLD_DUMPED;
siginfo->si_status = WTERMSIG(p->p_xsig);
} else if (WIFSIGNALED(p->p_xsig)) {
siginfo->si_code = CLD_KILLED;
siginfo->si_status = WTERMSIG(p->p_xsig);
} else {
siginfo->si_code = CLD_EXITED;
siginfo->si_status = p->p_xexit;
}
siginfo->si_pid = p->p_pid;
siginfo->si_uid = p->p_ucred->cr_uid;
/*
* The si_addr field would be useful additional detail, but
* apparently the PC value may be lost when we reach this
* point. bzero() above sets siginfo->si_addr to NULL.
*/
}
static void
wait_fill_wrusage(struct proc *p, struct __wrusage *wrusage)
{
struct rusage *rup;
PROC_LOCK_ASSERT(p, MA_OWNED);
if (wrusage == NULL)
return;
rup = &wrusage->wru_self;
*rup = p->p_ru;
PROC_STATLOCK(p);
calcru(p, &rup->ru_utime, &rup->ru_stime);
PROC_STATUNLOCK(p);
rup = &wrusage->wru_children;
*rup = p->p_stats->p_cru;
calccru(p, &rup->ru_utime, &rup->ru_stime);
}
static int
proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id,
int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo,
int check_only)
{
struct rusage *rup;
sx_assert(&proctree_lock, SA_XLOCKED);
PROC_LOCK(p);
@@ -1133,60 +1195,14 @@ proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id,
return (0);
}
if (siginfo != NULL) {
bzero(siginfo, sizeof(*siginfo));
siginfo->si_errno = 0;
/*
* SUSv4 requires that the si_signo value is always
* SIGCHLD. Obey it despite the rfork(2) interface
* allows to request other signal for child exit
* notification.
*/
siginfo->si_signo = SIGCHLD;
/*
* This is still a rough estimate. We will fix the
* cases TRAPPED, STOPPED, and CONTINUED later.
*/
if (WCOREDUMP(p->p_xsig)) {
siginfo->si_code = CLD_DUMPED;
siginfo->si_status = WTERMSIG(p->p_xsig);
} else if (WIFSIGNALED(p->p_xsig)) {
siginfo->si_code = CLD_KILLED;
siginfo->si_status = WTERMSIG(p->p_xsig);
} else {
siginfo->si_code = CLD_EXITED;
siginfo->si_status = p->p_xexit;
}
siginfo->si_pid = p->p_pid;
siginfo->si_uid = p->p_ucred->cr_uid;
/*
* The si_addr field would be useful additional
* detail, but apparently the PC value may be lost
* when we reach this point. bzero() above sets
* siginfo->si_addr to NULL.
*/
}
wait_fill_siginfo(p, siginfo);
/*
* There should be no reason to limit resources usage info to
* exited processes only. A snapshot about any resources used
* by a stopped process may be exactly what is needed.
*/
if (wrusage != NULL) {
rup = &wrusage->wru_self;
*rup = p->p_ru;
PROC_STATLOCK(p);
calcru(p, &rup->ru_utime, &rup->ru_stime);
PROC_STATUNLOCK(p);
rup = &wrusage->wru_children;
*rup = p->p_stats->p_cru;
calccru(p, &rup->ru_utime, &rup->ru_stime);
}
wait_fill_wrusage(p, wrusage);
if (p->p_state == PRS_ZOMBIE && !check_only) {
proc_reap(td, p, status, options);