summaryrefslogtreecommitdiff
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r--sys/kern/kern_sysctl.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index d1109e22d8b4..3bc26236edb5 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
- * $Id: kern_sysctl.c,v 1.25.4.4 1996/05/30 01:24:41 davidg Exp $
+ * $Id: kern_sysctl.c,v 1.25.4.5 1996/05/31 08:04:10 peter Exp $
*/
/*
@@ -648,17 +648,24 @@ sysctl_doproc(name, namelen, where, sizep)
size_t *sizep;
{
register struct proc *p;
- register struct kinfo_proc *dp = (struct kinfo_proc *)where;
- register int needed = 0;
- int buflen = where != NULL ? *sizep : 0;
+ register struct kinfo_proc *dp;
+ register int needed;
+ int buflen;
int doingzomb;
struct eproc eproc;
int error = 0;
if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
return (EINVAL);
- p = (struct proc *)allproc;
+restart:
doingzomb = 0;
+ p = (struct proc *)allproc;
+ if (where != NULL)
+ buflen = *sizep;
+ else
+ buflen = 0;
+ dp = (struct kinfo_proc *)where;
+ needed = 0;
again:
for (; p != NULL; p = p->p_next) {
/*
@@ -703,15 +710,37 @@ again:
break;
}
if (buflen >= sizeof(struct kinfo_proc)) {
+ pid_t pid = p->p_pid;
+
fill_eproc(p, &eproc);
error = copyout((caddr_t)p, &dp->kp_proc,
sizeof(struct proc));
if (error)
return (error);
+ /*
+ * Since copyout can block, our cached struct proc * may
+ * no longer be valid. For allproc, restart from the
+ * beginning if the process no longer exists. For
+ * zombproc, just stop if it's gone.
+ */
+ if (!doingzomb) {
+ if (pid && (pfind(pid) != p))
+ goto restart;
+ } else {
+ if (zpfind(pid) != p)
+ break;
+ }
error = copyout((caddr_t)&eproc, &dp->kp_eproc,
sizeof(eproc));
if (error)
return (error);
+ if (!doingzomb) {
+ if (pid && (pfind(pid) != p))
+ goto restart;
+ } else {
+ if (zpfind(pid) != p)
+ break;
+ }
dp++;
buflen -= sizeof(struct kinfo_proc);
}