bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Obtain number of ports in proc and libps


From: olafBuddenhagen
Subject: [PATCH] Obtain number of ports in proc and libps
Date: Tue, 7 Sep 2010 02:25:50 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

>From 60c06172f3ae0ce585a95c08062f39998f9edfe1 Mon Sep 17 00:00:00 2001
From: antrik <address@hidden>
Date: Sat, 20 Jun 2009 12:29:06 +0200
Subject: [PATCH] Obtain number of ports in proc and libps

Add (and implement) a proc RPC to obtain the number of Mach ports used
by the target task.

Add infrastructure in libps to read this information.
---

This is a patch (against the Hurd source tree) that I wrote last summer,
but didn't get around yet to submit...

It allows showing the number of open ports of any process in the output
of "ps", by including "%ports" in the output format (ps -F). This is
useful for finding port leaks etc.

I have been using this on my system all the time since I created it, and
often running "ps" with this field included. I didn't observe any
problems.

As this modifies RPC definitions, it requires the usual bootstrap
procedure: First build a glibc using the new process.defs; and then
build the modified Hurd against the new libc-dev.

 hurd/process.defs         |    8 +++++++-
 hurd/process_request.defs |    6 ++++++
 libps/procstat.c          |    4 ++++
 libps/ps.h                |    4 ++++
 libps/spec.c              |   10 ++++++++++
 proc/info.c               |   32 ++++++++++++++++++++++++++++++++
 6 files changed, 63 insertions(+), 1 deletions(-)

diff --git a/hurd/process.defs b/hurd/process.defs
index a87cc42..43cc9f2 100644
--- a/hurd/process.defs
+++ b/hurd/process.defs
@@ -356,7 +356,7 @@ routine proc_getpgrppids (
        out pidset: pidarray_t, dealloc);
 
 
-/*** Another miscelleneous info query ***/
+/*** Other miscelleneous info queries ***/
 
 /* Return the controlling TTY used by PID in TTY; opened without read or
    write access. */
@@ -364,3 +364,9 @@ routine proc_get_tty (
        calling_process: process_t;
        target_process: pid_t;
        out tty: mach_port_send_t);
+
+/* Return the number of Mach ports used by PID */
+routine proc_getnports (
+       process: process_t;
+       which: pid_t;
+       out nports: mach_msg_type_number_t);
diff --git a/hurd/process_request.defs b/hurd/process_request.defs
index 8669e44..80a2828 100644
--- a/hurd/process_request.defs
+++ b/hurd/process_request.defs
@@ -365,3 +365,9 @@ simpleroutine proc_get_tty_request (
        process: process_t;
        ureplyport reply: reply_port_t;
        pid: pid_t);
+
+/* Return the number of Mach ports used by PID */
+simpleroutine proc_getnports_request (
+       process: process_t;
+       ureplyport reply: reply_port_t;
+       which: pid_t);
diff --git a/libps/procstat.c b/libps/procstat.c
index e8eeb66..2efd11a 100644
--- a/libps/procstat.c
+++ b/libps/procstat.c
@@ -995,6 +995,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.  */
diff --git a/libps/ps.h b/libps/ps.h
index 27f2e78..f0600c6 100644
--- a/libps/ps.h
+++ b/libps/ps.h
@@ -301,6 +301,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 +340,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 +444,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.  */
diff --git a/libps/spec.c b/libps/spec.c
index da1e372..5499bc1 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}
 };
 
diff --git a/proc/info.c b/proc/info.c
index ec072fa..ca0dc4f 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -759,3 +759,35 @@ S_proc_get_tty (struct proc *p, pid_t pid,
 {
   return EOPNOTSUPP;           /* XXX */
 }
+
+/* Implement proc_getnports as described in <hurd/process.defs>. */
+kern_return_t
+S_proc_getnports (struct proc *callerp,
+                   pid_t pid,
+                   mach_msg_type_number_t *nports)
+{
+  struct proc *p = pid_find (pid);
+  mach_port_array_t names;
+  mach_msg_type_number_t ncount;
+  mach_port_type_array_t types;
+  mach_msg_type_number_t tcount;
+  error_t err = 0;
+
+  /* No need to check CALLERP here; we don't use it. */
+
+  if (!p)
+    return ESRCH;
+
+  err = mach_port_names (p->p_task, &names, &ncount, &types, &tcount);
+  if (err == KERN_INVALID_TASK)
+    err = ESRCH;
+
+  if (!err) {
+    *nports = ncount;
+
+    munmap (names, ncount * sizeof (mach_port_t));
+    munmap (types, tcount * sizeof (mach_port_type_t));
+  }
+
+  return err;
+}
-- 
1.6.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]