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().
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to