summaryrefslogtreecommitdiff
path: root/proc/info.c
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1994-05-13 21:17:57 +0000
committerMichael I. Bushnell <mib@gnu.org>1994-05-13 21:17:57 +0000
commit15fb94304f3d9b9dc3c46a78c5cf10e71bcf5778 (patch)
tree6df54eaf1e24b2eeea20699d62e31428a414e290 /proc/info.c
parent8f9bc8670a72780b53f1b2827f6610af595f3346 (diff)
Formerly info.c.~6~
Diffstat (limited to 'proc/info.c')
-rw-r--r--proc/info.c70
1 files changed, 57 insertions, 13 deletions
diff --git a/proc/info.c b/proc/info.c
index 7f6a5cdf..e33e76d0 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -129,6 +129,8 @@ get_string (task_t t,
err = vm_read (t, readaddr, vm_page_size * 2, &data, &readlen);
if (err == KERN_INVALID_ADDRESS)
err = vm_read (t, readaddr, vm_page_size, &data, &readlen);
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
if (err)
return err;
@@ -170,6 +172,8 @@ get_vector (task_t task,
err = vm_read (task, readaddr, vm_page_size * 2, &data, &readlen);
if (err == KERN_INVALID_ADDRESS)
err = vm_read (task, readaddr, vm_page_size, &data, &readlen);
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
if (err)
return err;
@@ -311,7 +315,7 @@ S_proc_getprocinfo (struct proc *callerp,
thread_t *thds;
error_t err;
size_t structsize;
- int i;
+ int i, j;
int didalloc = 0;
u_int tkcount, thcount;
@@ -319,6 +323,8 @@ S_proc_getprocinfo (struct proc *callerp,
return ESRCH;
err = task_threads (p->p_task, &thds, &nthreads);
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
if (err)
return err;
@@ -352,19 +358,57 @@ S_proc_getprocinfo (struct proc *callerp,
err = task_info (p->p_task, TASK_BASIC_INFO, (int *)&pi->taskinfo,
&tkcount);
- for (i = 0; i < nthreads; i++)
- {
- thcount = THREAD_BASIC_INFO_COUNT;
- if (!err)
- err = thread_info (thds[i], THREAD_BASIC_INFO,
- (int *)&pi->threadinfos[i].pis_bi,
- &thcount);
- thcount = THREAD_SCHED_INFO_COUNT;
- if (!err)
- err = thread_info (thds[i], THREAD_SCHED_INFO,
- (int *)&pi->threadinfos[i].pis_si,
- &thcount);
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
+ if (err)
+ for (i = 0; i < nthreads; i++)
mach_port_deallocate (mach_task_self (), thds[i]);
+ else
+ {
+ j = 0;
+ for (i = 0; i < nthreads; i++)
+ {
+ thcount = THREAD_BASIC_INFO_COUNT;
+ err = thread_info (thds[i], THREAD_BASIC_INFO,
+ (int *)&pi->threadinfos[j].pis_bi,
+ &thcount);
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
+ if (err && err != ESRCH)
+ break;
+
+ thcount = THREAD_SCHED_INFO_COUNT;
+ if (!err)
+ err = thread_info (thds[i], THREAD_SCHED_INFO,
+ (int *)&pi->threadinfos[j].pis_si,
+ &thcount);
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
+ if (err && err != ESRCH)
+ break;
+
+ if (!err)
+ j++;
+ else
+ {
+ /* Don't count this one */
+ /* XXX This is buggy if *piarraylen drops enough to
+ reduce the number of pages in structsize, because
+ the message send won't deallocate all that we allocated. */
+ *piarraylen -= sizeof pi->threadinfos[j] / sizeof (int);
+ pi->nthreads--;
+ }
+
+ /* XXX If a thread has died, then its stats are now in
+ the TASK_BASIC_INFO struct, but our copy might have been fetched
+ from before the thread's death. */
+
+ mach_port_deallocate (mach_task_self (), thds[i]);
+ }
+ /* If we got an error (other than ESRCH); clean the rest
+ of the thds */
+ for (; i < nthreads; i++)
+ mach_port_deallocate (mach_task_self (), thds[i]);
}
vm_deallocate (mach_task_self (), (u_int )thds,