aboutsummaryrefslogtreecommitdiff
path: root/libps
diff options
context:
space:
mode:
Diffstat (limited to 'libps')
-rw-r--r--libps/fmt.c4
-rw-r--r--libps/procstat.c49
-rw-r--r--libps/ps.h10
-rw-r--r--libps/spec.c10
4 files changed, 47 insertions, 26 deletions
diff --git a/libps/fmt.c b/libps/fmt.c
index eae08ffe..3a47338a 100644
--- a/libps/fmt.c
+++ b/libps/fmt.c
@@ -194,7 +194,9 @@ _fmt_create (char *src, int posix, struct ps_fmt_specs *fmt_specs,
while (*src != '\0' && *src != stop)
src++;
}
- *src++ = '\0'; /* NUL terminhate NAME. */
+
+ if (*src)
+ *src++ = '\0'; /* NUL terminate NAME. */
}
else
/* A gnu-style field spec: `NAME' or `NAME:TITLE'. */
diff --git a/libps/procstat.c b/libps/procstat.c
index e8eeb668..eac4ae42 100644
--- a/libps/procstat.c
+++ b/libps/procstat.c
@@ -109,20 +109,22 @@ fetch_procinfo (process_t server, pid_t pid,
struct procinfo **pi, size_t *pi_size,
char **waits, size_t *waits_len)
{
+ static const struct { ps_flags_t ps_flag; int pi_flags; } map[] =
+ {
+ { PSTAT_TASK_BASIC, PI_FETCH_TASKINFO },
+ { PSTAT_TASK_EVENTS, PI_FETCH_TASKEVENTS },
+ { PSTAT_NUM_THREADS, PI_FETCH_THREADS },
+ { PSTAT_THREAD_BASIC, PI_FETCH_THREAD_BASIC | PI_FETCH_THREADS },
+ { PSTAT_THREAD_SCHED, PI_FETCH_THREAD_SCHED | PI_FETCH_THREADS },
+ { PSTAT_THREAD_WAITS, PI_FETCH_THREAD_WAITS | PI_FETCH_THREADS },
+ { 0, }
+ };
int pi_flags = 0;
+ int i;
- if ((need & PSTAT_TASK_BASIC) && !(*have & PSTAT_TASK_BASIC))
- pi_flags |= PI_FETCH_TASKINFO;
- if ((need & PSTAT_TASK_EVENTS) && !(*have & PSTAT_TASK_EVENTS))
- pi_flags |= PI_FETCH_TASKEVENTS;
- if ((need & PSTAT_NUM_THREADS) && !(*have & PSTAT_NUM_THREADS))
- pi_flags |= PI_FETCH_THREADS;
- if ((need & PSTAT_THREAD_BASIC) && !(*have & PSTAT_THREAD_BASIC))
- pi_flags |= PI_FETCH_THREAD_BASIC | PI_FETCH_THREADS;
- if ((need & PSTAT_THREAD_SCHED) && !(*have & PSTAT_THREAD_SCHED))
- pi_flags |= PI_FETCH_THREAD_SCHED | PI_FETCH_THREADS;
- if ((need & PSTAT_THREAD_WAITS) && !(*have & PSTAT_THREAD_WAITS))
- pi_flags |= PI_FETCH_THREAD_WAITS | PI_FETCH_THREADS;
+ for (i = 0; map[i].ps_flag; i++)
+ if ((need & map[i].ps_flag) && !(*have & map[i].ps_flag))
+ pi_flags |= map[i].pi_flags;
if (pi_flags || ((need & PSTAT_PROC_INFO) && !(*have & PSTAT_PROC_INFO)))
{
@@ -137,16 +139,9 @@ fetch_procinfo (process_t server, pid_t pid,
/* Update *HAVE to reflect what we've successfully fetched. */
{
*have |= PSTAT_PROC_INFO;
- if (pi_flags & PI_FETCH_TASKINFO)
- *have |= PSTAT_TASK_BASIC;
- if (pi_flags & PI_FETCH_THREADS)
- *have |= PSTAT_NUM_THREADS;
- if (pi_flags & PI_FETCH_THREAD_BASIC)
- *have |= PSTAT_THREAD_BASIC;
- if (pi_flags & PI_FETCH_THREAD_SCHED)
- *have |= PSTAT_THREAD_SCHED;
- if (pi_flags & PI_FETCH_THREAD_WAITS)
- *have |= PSTAT_THREAD_WAITS;
+ for (i = 0; map[i].ps_flag; i++)
+ if ((pi_flags & map[i].pi_flags) == map[i].pi_flags)
+ *have |= map[i].ps_flag;
}
return err;
}
@@ -966,7 +961,7 @@ proc_stat_set_flags (struct proc_stat *ps, ps_flags_t flags)
when creating a file. */
MP_MGET (PSTAT_UMASK, PSTAT_TASK,
ps_msg_get_init_int (ps->msgport, ps->task, INIT_UMASK,
- &ps->umask));
+ (int *) &ps->umask));
if (NEED (PSTAT_OWNER_UID, PSTAT_PROC_INFO))
{
@@ -995,6 +990,10 @@ proc_stat_set_flags (struct proc_stat *ps, ps_flags_t flags)
if (ps_context_find_tty_by_cttyid (ps->context, ps->cttyid, &ps->tty) == 0)
have |= PSTAT_TTY;
+ /* The number of Mach ports in the task. */
+ MGET (PSTAT_NUM_PORTS, PSTAT_PID,
+ proc_getnports (server, ps->pid, &ps->num_ports));
+
/* Update PS's flag state. We haven't tried user flags yet, so don't mark
them as having failed. We do this before checking user bits so that the
user fetch hook sees PS in a consistent state. */
@@ -1050,7 +1049,7 @@ _proc_stat_free (ps)
MFREEPORT (PSTAT_AUTH, auth);
/* free any allocated memory pointed to by PS */
- MFREEMEM (PSTAT_PROCINFO, proc_info, ps->proc_info_size,
+ MFREEMEM (PSTAT_PROC_INFO, proc_info, ps->proc_info_size,
ps->proc_info_vm_alloced, 0, char);
MFREEMEM (PSTAT_THREAD_BASIC, thread_basic_info, 0, 0, 0, 0);
MFREEMEM (PSTAT_THREAD_SCHED, thread_sched_info, 0, 0, 0, 0);
@@ -1058,6 +1057,8 @@ _proc_stat_free (ps)
MFREEMEM (PSTAT_ENV, env, ps->env_len, ps->env_vm_alloced, 0, char);
MFREEMEM (PSTAT_TASK_EVENTS, task_events_info, ps->task_events_info_size,
0, &ps->task_events_info_buf, char);
+ MFREEMEM (PSTAT_THREAD_WAITS, thread_waits, ps->thread_waits_len,
+ ps->thread_waits_vm_alloced, 0, char);
FREE (ps);
}
diff --git a/libps/ps.h b/libps/ps.h
index 27f2e787..b85ede46 100644
--- a/libps/ps.h
+++ b/libps/ps.h
@@ -261,6 +261,8 @@ struct proc_stat
/* Virtual memory statistics for the process, as returned by task_info;
see <mach/task_info.h> for a description of task_events_info_t. */
+ /* FIXME: we are actually currently storing it into proc_info, see
+ fetch_procinfo. */
task_events_info_t task_events_info;
task_events_info_data_t task_events_info_buf;
size_t task_events_info_size;
@@ -301,6 +303,8 @@ struct proc_stat
char *env;
/* The length of ENV. */
size_t env_len;
+
+ unsigned num_ports;
};
/* Proc_stat flag bits; each bit is set in the FLAGS field if that
@@ -338,6 +342,7 @@ struct proc_stat
#define PSTAT_OWNER_UID 0x200000 /* The uid of the the proc's owner */
#define PSTAT_UMASK 0x400000 /* The proc's current umask */
#define PSTAT_HOOK 0x800000 /* Has a non-zero hook */
+#define PSTAT_NUM_PORTS 0x4000000 /* Number of Mach ports in the task */
/* Flag bits that don't correspond precisely to any field. */
#define PSTAT_NO_MSGPORT 0x1000000 /* Don't use the msgport at all */
@@ -441,6 +446,7 @@ extern char *proc_stat_state_tags;
#define proc_stat_umask(ps) ((ps)->umask)
#define proc_stat_tty(ps) ((ps)->tty)
#define proc_stat_task_events_info(ps) ((ps)->task_events_info)
+#define proc_stat_num_ports(ps) ((ps)->num_ports)
#define proc_stat_has(ps, needs) (((ps)->flags & needs) == needs)
/* True if PS refers to a thread and not a process. */
@@ -454,7 +460,9 @@ error_t _proc_stat_create (pid_t pid, struct ps_context *context,
/* Frees PS and any memory/ports it references. Users shouldn't use this
routine; proc_stats are normally freed only when their ps_context goes
- away. */
+ away. Insubordinate users will make sure they free the thread proc_stats
+ before they free the corresponding process proc_stat since the thread_wait
+ fields of the former may reference the latter. */
void _proc_stat_free (struct proc_stat *ps);
/* Adds FLAGS to PS's flags, fetching information as necessary to validate
diff --git a/libps/spec.c b/libps/spec.c
index da1e372a..5499bc15 100644
--- a/libps/spec.c
+++ b/libps/spec.c
@@ -349,6 +349,14 @@ ps_get_zero_fills (struct proc_stat *ps)
const struct ps_getter ps_zero_fills_getter =
{"zero_fills", PSTAT_TASK_EVENTS, (vf) ps_get_zero_fills};
+static int
+ps_get_num_ports (struct proc_stat *ps)
+{
+ return proc_stat_num_ports (ps);
+}
+const struct ps_getter ps_num_ports_getter =
+{"num_ports", PSTAT_NUM_PORTS, (vf) ps_get_num_ports};
+
/* ---------------------------------------------------------------- */
/* some printing functions */
@@ -1155,6 +1163,8 @@ static const struct ps_fmt_spec specs[] =
&ps_msgs_sent_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint},
{"ZFills", 0, -5, -1, 0,
&ps_zero_fills_getter, ps_emit_int, ps_cmp_ints, ps_nominal_zint},
+ {"Ports", 0, -5, -1, 0,
+ &ps_num_ports_getter, ps_emit_int, ps_cmp_ints, 0},
{0}
};