From owner-svn-src-head@FreeBSD.ORG Sun Nov 17 22:31:24 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 886763DA; Sun, 17 Nov 2013 22:31:24 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 68AF62990; Sun, 17 Nov 2013 22:31:24 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rAHMVOev095236; Sun, 17 Nov 2013 22:31:24 GMT (envelope-from jilles@svn.freebsd.org) Received: (from jilles@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rAHMVOlW095234; Sun, 17 Nov 2013 22:31:24 GMT (envelope-from jilles@svn.freebsd.org) Message-Id: <201311172231.rAHMVOlW095234@svn.freebsd.org> From: Jilles Tjoelker Date: Sun, 17 Nov 2013 22:31:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r258281 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Nov 2013 22:31:24 -0000 Author: jilles Date: Sun Nov 17 22:31:23 2013 New Revision: 258281 URL: http://svnweb.freebsd.org/changeset/base/258281 Log: 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 Reported by: Dmitrijs Ledkovs Tested by: Dmitrijs Ledkovs Modified: head/sys/kern/kern_exit.c head/sys/kern/kern_sig.c Modified: head/sys/kern/kern_exit.c ============================================================================== --- head/sys/kern/kern_exit.c Sun Nov 17 22:24:34 2013 (r258280) +++ head/sys/kern/kern_exit.c Sun Nov 17 22:31:23 2013 (r258281) @@ -974,16 +974,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: head/sys/kern/kern_sig.c ============================================================================== --- head/sys/kern/kern_sig.c Sun Nov 17 22:24:34 2013 (r258280) +++ head/sys/kern/kern_sig.c Sun Nov 17 22:31:23 2013 (r258281) @@ -2959,7 +2959,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; @@ -2979,7 +2979,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); } @@ -2987,6 +2987,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); } @@ -3000,13 +3001,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().