svn commit: r260227 - stable/9/sys/kern
Jilles Tjoelker
jilles at FreeBSD.org
Fri Jan 3 14:30:25 UTC 2014
Author: jilles
Date: Fri Jan 3 14:30:24 2014
New Revision: 260227
URL: http://svnweb.freebsd.org/changeset/base/260227
Log:
MFC r258281: Fix siginfo_t.si_status for wait6/waitid/SIGCHLD.
Per POSIX, si_status should contain the value passed to exit() for
si_code==CLD_EXITED and the signal number for other si_code. This was
incorrect for CLD_EXITED and CLD_DUMPED.
This is still not fully POSIX-compliant (Austin group issue #594 says that
the full value passed to exit() shall be returned via si_status, not just
the low 8 bits) but is sufficient for a si_status-related test in libnih
(upstart, Debian/kFreeBSD).
PR: kern/184002
Modified:
stable/9/sys/kern/kern_exit.c
stable/9/sys/kern/kern_sig.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/kern/kern_exit.c
==============================================================================
--- stable/9/sys/kern/kern_exit.c Fri Jan 3 12:28:33 2014 (r260226)
+++ stable/9/sys/kern/kern_exit.c Fri Jan 3 14:30:24 2014 (r260227)
@@ -978,16 +978,19 @@ proc_to_reap(struct thread *td, struct p
* This is still a rough estimate. We will fix the
* cases TRAPPED, STOPPED, and CONTINUED later.
*/
- if (WCOREDUMP(p->p_xstat))
+ if (WCOREDUMP(p->p_xstat)) {
siginfo->si_code = CLD_DUMPED;
- else if (WIFSIGNALED(p->p_xstat))
+ siginfo->si_status = WTERMSIG(p->p_xstat);
+ } else if (WIFSIGNALED(p->p_xstat)) {
siginfo->si_code = CLD_KILLED;
- else
+ siginfo->si_status = WTERMSIG(p->p_xstat);
+ } else {
siginfo->si_code = CLD_EXITED;
+ siginfo->si_status = WEXITSTATUS(p->p_xstat);
+ }
siginfo->si_pid = p->p_pid;
siginfo->si_uid = p->p_ucred->cr_uid;
- siginfo->si_status = p->p_xstat;
/*
* The si_addr field would be useful additional
Modified: stable/9/sys/kern/kern_sig.c
==============================================================================
--- stable/9/sys/kern/kern_sig.c Fri Jan 3 12:28:33 2014 (r260226)
+++ stable/9/sys/kern/kern_sig.c Fri Jan 3 14:30:24 2014 (r260227)
@@ -2951,7 +2951,7 @@ sigparent(struct proc *p, int reason, in
}
static void
-childproc_jobstate(struct proc *p, int reason, int status)
+childproc_jobstate(struct proc *p, int reason, int sig)
{
struct sigacts *ps;
@@ -2971,7 +2971,7 @@ childproc_jobstate(struct proc *p, int r
mtx_lock(&ps->ps_mtx);
if ((ps->ps_flag & PS_NOCLDSTOP) == 0) {
mtx_unlock(&ps->ps_mtx);
- sigparent(p, reason, status);
+ sigparent(p, reason, sig);
} else
mtx_unlock(&ps->ps_mtx);
}
@@ -2979,6 +2979,7 @@ childproc_jobstate(struct proc *p, int r
void
childproc_stopped(struct proc *p, int reason)
{
+ /* p_xstat is a plain signal number, not a full wait() status here. */
childproc_jobstate(p, reason, p->p_xstat);
}
@@ -2992,13 +2993,15 @@ void
childproc_exited(struct proc *p)
{
int reason;
- int status = p->p_xstat; /* convert to int */
+ int xstat = p->p_xstat; /* convert to int */
+ int status;
- reason = CLD_EXITED;
- if (WCOREDUMP(status))
- reason = CLD_DUMPED;
- else if (WIFSIGNALED(status))
- reason = CLD_KILLED;
+ if (WCOREDUMP(xstat))
+ reason = CLD_DUMPED, status = WTERMSIG(xstat);
+ else if (WIFSIGNALED(xstat))
+ reason = CLD_KILLED, status = WTERMSIG(xstat);
+ else
+ reason = CLD_EXITED, status = WEXITSTATUS(xstat);
/*
* XXX avoid calling wakeup(p->p_pptr), the work is
* done in exit1().
More information about the svn-src-stable-9
mailing list