Page MenuHomeFreeBSD

D58407.id182881.diff
No OneTemporary

D58407.id182881.diff

diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1117,7 +1117,7 @@
atomic_add_int(&nprocs, -1);
}
-static void
+void
wait_fill_siginfo(struct proc *p, siginfo_t *siginfo)
{
PROC_LOCK_ASSERT(p, MA_OWNED);
@@ -1160,7 +1160,7 @@
*/
}
-static void
+void
wait_fill_wrusage(struct proc *p, struct __wrusage *wrusage)
{
struct rusage *rup;
@@ -1578,12 +1578,30 @@
("closed proc %p procdesc %p pd flags %#x",
pd->pd_proc, pd, pd->pd_flags));
+ if ((pd->pd_flags & PDF_EXITED) != 0) {
+ if ((options & WEXITED) == 0) {
+ error = ESRCH;
+ goto exit_tree_locked;
+ }
+ procdesc_fill_winfo(pd, false);
+ *status = KW_EXITCODE(pd->pd_xexit, pd->pd_xsig);
+ if (wrusage != NULL) {
+ memcpy(wrusage, &pd->pd_wrusage,
+ sizeof(*wrusage));
+ }
+ if (siginfo != NULL) {
+ memcpy(siginfo, &pd->pd_siginfo,
+ sizeof(*siginfo));
+ }
+ goto exit_tree_locked;
+ }
p = pd->pd_proc;
if (p == NULL) {
error = ESRCH;
goto exit_tree_locked;
}
PROC_LOCK(p);
+ MPASS(p->p_state != PRS_ZOMBIE);
error = p_canwait(td, p);
if (error != 0)
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
@@ -295,7 +295,8 @@
KASSERT(pd->pd_fpcount > 0, ("%s: closed procdesc %p", __func__, pd));
pd->pd_flags |= PDF_EXITED;
- pd->pd_xstat = KW_EXITCODE(p->p_xexit, p->p_xsig);
+ pd->pd_xexit = p->p_xexit;
+ pd->pd_xsig = p->p_xsig;
selwakeup(&pd->pd_selinfo);
KNOTE_LOCKED(&pd->pd_selinfo.si_note, NOTE_EXIT | NOTE_PDSIGCHLD);
@@ -337,6 +338,25 @@
PROC_UNLOCK(p);
}
+void
+procdesc_fill_winfo(struct procdesc *pd, bool proc_locked)
+{
+ struct proc *p;
+
+ sx_assert(&proctree_lock, SA_XLOCKED);
+
+ if ((pd->pd_flags & (PDF_EXITED | PDF_EXIT_INFO)) == PDF_EXITED) {
+ pd->pd_flags |= PDF_EXIT_INFO;
+ p = pd->pd_proc;
+ if (!proc_locked)
+ PROC_LOCK(p);
+ wait_fill_siginfo(p, &pd->pd_siginfo);
+ wait_fill_wrusage(p, &pd->pd_wrusage);
+ if (!proc_locked)
+ PROC_UNLOCK(p);
+ }
+}
+
/*
* When a process descriptor is reaped, perhaps as a result of close(), release
* the process's reference on the process descriptor.
@@ -350,6 +370,7 @@
KASSERT(p->p_procdesc != NULL, ("procdesc_reap: p_procdesc == NULL"));
pd = p->p_procdesc;
+ procdesc_fill_winfo(pd, false);
pd->pd_proc = NULL;
p->p_procdesc = NULL;
procdesc_free(pd);
@@ -413,6 +434,7 @@
* First, detach the process from its descriptor so that
* its exit status will be reported normally.
*/
+ procdesc_fill_winfo(pd, true);
pd->pd_proc = NULL;
p->p_procdesc = NULL;
pd->pd_pid = -1;
@@ -458,7 +480,7 @@
revents = 0;
pd = fp->f_data;
PROCDESC_LOCK(pd);
- if (pd->pd_flags & PDF_EXITED)
+ if ((atomic_load_int(&pd->pd_flags) & PDF_EXITED) != 0)
revents |= POLLHUP;
else
selrecord(td, &pd->pd_selinfo);
@@ -491,7 +513,7 @@
* pending.
*/
p = pd->pd_proc;
- if ((pd->pd_flags & PDF_EXITED) != 0)
+ if ((atomic_load_int(&pd->pd_flags) & PDF_EXITED) != 0)
event = NOTE_EXIT | NOTE_PDSIGCHLD;
else if ((atomic_load_int(&p->p_flag) & (P_STOPPED_SIG |
P_STOPPED_TRACE)) != 0)
@@ -509,7 +531,7 @@
/* Report exit status */
if ((kn->kn_fflags & NOTE_EXIT) != 0)
- kn->kn_data = pd->pd_xstat;
+ kn->kn_data = KW_EXITCODE(pd->pd_xexit, pd->pd_xsig);
/* Process is gone, so flag the event as finished. */
if ((event & NOTE_REAP) != 0 ||
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1237,6 +1237,8 @@
void cpu_update_pcb(struct thread *);
bool curproc_sigkilled(void);
void userret(struct thread *, struct trapframe *);
+void wait_fill_siginfo(struct proc *p, struct __siginfo *siginfo);
+void wait_fill_wrusage(struct proc *p, struct __wrusage *wrusage);
void cpu_exit(struct thread *);
void exit1(struct thread *, int, int) __dead2;
diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h
--- a/sys/sys/procdesc.h
+++ b/sys/sys/procdesc.h
@@ -71,10 +71,15 @@
/*
* In-flight data and notification of events.
*/
- int pd_flags; /* (p) PD_ flags. */
- u_short pd_xstat; /* (p) Exit status. */
+ int pd_flags; /* (t) PD_ flags. */
struct selinfo pd_selinfo; /* (p) Event notification. */
struct mtx pd_lock; /* Protect data + events. */
+
+ /* Exit status. */
+ u_int pd_xexit;
+ u_int pd_xsig;
+ struct __wrusage pd_wrusage;
+ siginfo_t pd_siginfo;
};
/*
@@ -89,6 +94,7 @@
/*
* Flags for the pd_flags field.
*/
+#define PDF_EXIT_INFO 0x00000001 /* Exit info calculated. */
#define PDF_EXITED 0x00000004 /* Process exited. */
/*
@@ -111,6 +117,7 @@
void procdesc_finit(struct procdesc *, struct file *);
pid_t procdesc_pid(struct file *);
void procdesc_reap(struct proc *);
+void procdesc_fill_winfo(struct procdesc *pd, bool proc_locked);
int procdesc_falloc(struct thread *, struct file **, int *, int,
struct filecaps *);

File Metadata

Mime Type
text/plain
Expires
Fri, Jul 31, 3:43 AM (9 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35765122
Default Alt Text
D58407.id182881.diff (4 KB)

Event Timeline