commit-hurd
[Top][All Lists]
Advanced

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

[hurd] 16/16: Implement /proc/<pid>/exe


From: Samuel Thibault
Subject: [hurd] 16/16: Implement /proc/<pid>/exe
Date: Tue, 09 Jan 2018 01:35:30 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch upstream
in repository hurd.

commit 104f3121f8005b426d4df77b2420cfe5837033d1
Author: Samuel Thibault <address@hidden>
Date:   Mon Jan 8 23:00:37 2018 +0100

    Implement /proc/<pid>/exe
    
    by adding proc_set/get_exe to the proc server, making
    exec call proc_set_exe, and libps call proc_get_exe. procfs can then just
    retrieve the information to make the "exe" symlink.
    
    * hurd/process.defs (proc_set_exe, proc_get_exe): New RPCs.
    * hurd/process_request.defs: Likewise.
    * hurd/process_reply.defs: Add skips for proc_set_exe and proc_get_exe RPCs.
    * proc/proc.h (struct proc): Add `exe' field.
    * proc/info.c (S_proc_set_exe, S_proc_get_exe): New functions.
    * proc/mgt.c (process_has_exited): Free p->exe.
    (S_proc_child): Duplicate parent `exe' into child's `exe'.
    * exec/exec.c (do_exec): Call proc_set_exe when a filename is available.
    * libps/ps.h (struct proc_stat): Add `exe_vm_alloced', `exe', and `exe_len'
    field.
    (PSTAT_EXE): New macro.
    (PSTAT_USER_BASE): Change value to make room.
    (proc_stat_exe, proc_stat_exe_len): New macros.
    * libps/procstat.c (proc_stat_set_flags): Handle PSTAT_EXE case by calling
    proc_get_exe.
    * libps/spec.c (ps_get_exe): New function.
    (ps_exe_getter): New structure.
    (ps_fmt_spec): Add "Exe" specification.
    * procfs/process.c (process_file_symlink_make_node, process_file_gc_exe): 
New
    functions.
    (procfs_dir_entry): Add "exe" entry.
    * startup/startup.c (launch_core_servers): Set exe paths for startup, auth,
    proc, and fs servers.
    (frob_kernel_process): Set exe path for kernel task.
    (S_startup_essential_task): Set exe path for exec server.
---
 exec/exec.c       |  3 +++
 hurd/process.defs | 12 ++++++++++--
 libps/procstat.c  | 17 +++++++++++++++++
 libps/ps.h        | 11 ++++++++++-
 libps/spec.c      | 10 ++++++++++
 proc/info.c       | 41 +++++++++++++++++++++++++++++++++++++++++
 proc/mgt.c        |  4 ++++
 proc/proc.h       |  1 +
 procfs/process.c  | 32 ++++++++++++++++++++++++++++++++
 startup/startup.c |  7 +++++++
 10 files changed, 135 insertions(+), 3 deletions(-)

diff --git a/exec/exec.c b/exec/exec.c
index 94f0a73..e959091 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1314,6 +1314,9 @@ do_exec (file_t file,
       if (e.error)
        goto out;
 
+      if (abspath)
+       proc_set_exe (boot->portarray[INIT_PORT_PROC], abspath);
+
       set_name (newtask, argv, pid);
 
       e.error = proc_set_entry (boot->portarray[INIT_PORT_PROC],
diff --git a/hurd/process.defs b/hurd/process.defs
index 725326a..d515a46 100644
--- a/hurd/process.defs
+++ b/hurd/process.defs
@@ -414,8 +414,16 @@ routine proc_make_task_namespace (
        process: process_t;
        notify: mach_port_send_t);
 
-skip; /* proc_set_exe */
-skip; /* proc_get_exe */
+/* Set the process binary executable path.  */
+routine proc_set_exe (
+       process: process_t;
+       path: string_t);
+
+/* Get the process binary executable path.  */
+routine proc_get_exe (
+       process: process_t;
+       which: pid_t;
+       out path: string_t);
 
 /* Set the locations of the executable entry.  */
 routine proc_set_entry (
diff --git a/libps/procstat.c b/libps/procstat.c
index f6420ee..d042341 100644
--- a/libps/procstat.c
+++ b/libps/procstat.c
@@ -956,6 +956,23 @@ proc_stat_set_flags (struct proc_stat *ps, ps_flags_t 
flags)
        }
     }
 
+  /* The process's path to binary executable */
+  if (NEED (PSTAT_EXE, PSTAT_PID))
+    {
+      ps->exe = malloc (sizeof(string_t));
+      if (ps->exe)
+       {
+         if (proc_get_exe (server, ps->pid, ps->exe))
+           free (ps->exe);
+         else
+           {
+             ps->exe_len = strlen(ps->exe);
+             have |= PSTAT_EXE;
+             ps->exe_vm_alloced = 0;
+           }
+       }
+    }
+
   /* The ctty id port; note that this is just a magic cookie;
      we use it to fetch a port to the actual terminal -- it's not useful for
      much else.  */
diff --git a/libps/ps.h b/libps/ps.h
index 3ee142d..2725b1f 100644
--- a/libps/ps.h
+++ b/libps/ps.h
@@ -272,6 +272,7 @@ struct proc_stat
   unsigned thread_waits_vm_alloced : 1;
   unsigned args_vm_alloced : 1;
   unsigned env_vm_alloced : 1;
+  unsigned exe_vm_alloced : 1;
 
   /* Various libc ports:  */
 
@@ -305,6 +306,11 @@ struct proc_stat
   size_t env_len;
 
   unsigned num_ports;
+
+  /* The path to process's binary executable.  */
+  char *exe;
+  /* The length of EXE.  */
+  size_t exe_len;
 };
 
 /* Proc_stat flag bits; each bit is set in the FLAGS field if that
@@ -344,12 +350,13 @@ struct proc_stat
 #define PSTAT_HOOK           0x800000 /* Has a non-zero hook */
 #define PSTAT_NUM_PORTS      0x4000000 /* Number of Mach ports in the task */
 #define PSTAT_TIMES          0x8000000 /* Task/thread user and system times */
+#define PSTAT_EXE           0x10000000 /* Path to binary executable */
 
 /* Flag bits that don't correspond precisely to any field.  */
 #define PSTAT_NO_MSGPORT     0x1000000 /* Don't use the msgport at all */
 
 /* Bits from PSTAT_USER_BASE on up are available for user-use.  */
-#define PSTAT_USER_BASE      0x10000000
+#define PSTAT_USER_BASE      0x20000000
 #define PSTAT_USER_MASK      ~(PSTAT_USER_BASE - 1)
 
 /* If the PSTAT_STATE flag is set, then the proc_stats state field holds a
@@ -448,6 +455,8 @@ extern char *proc_stat_state_tags;
 #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_exe(ps) ((ps)->exe)
+#define proc_stat_exe_len(ps) ((ps)->exe_len)
 #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 5e540f8..4760c43 100644
--- a/libps/spec.c
+++ b/libps/spec.c
@@ -358,6 +358,14 @@ ps_get_num_ports (struct proc_stat *ps)
 const struct ps_getter ps_num_ports_getter =
 {"num_ports", PSTAT_NUM_PORTS, (vf) ps_get_num_ports};
 
+static void
+ps_get_exe (struct proc_stat *ps, char **exe_p, int *exe_len_p)
+{
+  *exe_p = proc_stat_exe (ps);
+  *exe_len_p = proc_stat_exe_len (ps);
+}
+const struct ps_getter ps_exe_getter =
+{"exe", PSTAT_EXE, ps_get_exe};
 /* ---------------------------------------------------------------- */
 /* some printing functions */
 
@@ -1166,6 +1174,8 @@ static const struct ps_fmt_spec specs[] =
    &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},
+  {"Exe",      0,       0, -1, 0,
+   &ps_exe_getter,        ps_emit_string,  ps_cmp_strings,ps_nominal_string},
   {0}
 };
 
diff --git a/proc/info.c b/proc/info.c
index 3c1bf6d..6ab9f3f 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -24,6 +24,7 @@
 #include <sys/mman.h>
 #include <hurd/hurd_types.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/resource.h>
@@ -1017,3 +1018,43 @@ S_proc_getnports (struct proc *callerp,
 
   return err;
 }
+
+/* Implement proc_set_path as described in <hurd/process.defs>. */
+kern_return_t
+S_proc_set_exe (struct proc *p,
+               char *path)
+{
+  char *copy;
+
+  if (!p)
+    return EOPNOTSUPP;
+
+  copy = strdup(path);
+  if (! copy)
+    return ENOMEM;
+
+  free(p->exe);
+  p->exe = copy;
+  return 0;
+}
+
+/* Implement proc_get_path as described in <hurd/process.defs>. */
+kern_return_t
+S_proc_get_exe (struct proc *callerp,
+               pid_t pid,
+               char *path)
+{
+  struct proc *p = pid_find (pid);
+
+  /* No need to check CALLERP here; we don't use it. */
+
+  if (!p)
+    return ESRCH;
+
+  if (p->exe)
+    snprintf (path, 1024 /* XXX */, "%s", p->exe);
+  else
+    path[0] = 0;
+  return 0;
+}
+
diff --git a/proc/mgt.c b/proc/mgt.c
index 354f378..d92bf52 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -223,6 +223,8 @@ S_proc_child (struct proc *parentp,
       childp->start_code = parentp->start_code;
       childp->end_code = parentp->end_code;
     }
+  if (! childp->exe && parentp->exe)
+    childp->exe = strdup (parentp->exe);
 
   if (MACH_PORT_VALID (parentp->p_task_namespace))
     {
@@ -860,6 +862,8 @@ process_has_exited (struct proc *p)
 
   if (!--p->p_login->l_refcnt)
     free (p->p_login);
+  free (p->exe);
+  p->exe = NULL;
 
   ids_rele (p->p_id);
 
diff --git a/proc/proc.h b/proc/proc.h
index b33845d..a974f62 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -68,6 +68,7 @@ struct proc
   pthread_cond_t p_wakeup;
 
   /* Miscellaneous information */
+  char *exe;                   /* path to binary executable */
   vm_address_t p_argv, p_envp;
   vm_address_t start_code;     /* all executable segments are in this range */
   vm_address_t end_code;
diff --git a/procfs/process.c b/procfs/process.c
index ece37b7..59653b2 100644
--- a/procfs/process.c
+++ b/procfs/process.c
@@ -95,6 +95,19 @@ static int args_filename_length (const char *name)
 /* Actual content generators */
 
 static ssize_t
+process_file_gc_exe (struct proc_stat *ps, char **contents)
+{
+  if (proc_stat_exe_len (ps) == 0)
+    {
+      *contents = "-";
+      return 1;
+    }
+
+  *contents = proc_stat_exe(ps);
+  return proc_stat_exe_len(ps);
+}
+
+static ssize_t
 process_file_gc_cmdline (struct proc_stat *ps, char **contents)
 {
   *contents = proc_stat_args(ps);
@@ -410,6 +423,14 @@ process_file_make_node (void *dir_hook, const void 
*entry_hook)
   return np;
 }
 
+static struct node *
+process_file_symlink_make_node (void *dir_hook, const void *entry_hook)
+{
+  struct node *np = process_file_make_node (dir_hook, entry_hook);
+  if (np) procfs_node_chtype (np, S_IFLNK);
+  return np;
+}
+
 /* Stat needs its own constructor in order to set its mode according to
    the --stat-mode command-line option.  */
 static struct node *
@@ -425,6 +446,17 @@ process_stat_make_node (void *dir_hook, const void 
*entry_hook)
 
 static struct procfs_dir_entry entries[] = {
   {
+    .name = "exe",
+    .hook = & (struct process_file_desc) {
+      .get_contents = process_file_gc_exe,
+      .needs = PSTAT_EXE,
+      .no_cleanup = 1,
+    },
+    .ops = {
+      .make_node = process_file_symlink_make_node,
+    },
+  },
+  {
     .name = "cmdline",
     .hook = & (struct process_file_desc) {
       .get_contents = process_file_gc_cmdline,
diff --git a/startup/startup.c b/startup/startup.c
index 81a6771..9a06f7c 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -832,6 +832,7 @@ launch_core_servers (void)
   assert_perror_backtrace (err);
   err = proc_mark_exec (procserver);
   assert_perror_backtrace (err);
+  proc_set_exe (procserver, "/hurd/startup");
 
   /* Declare that the filesystem and auth are our children. */
   err = proc_child (procserver, fstask);
@@ -845,6 +846,7 @@ launch_core_servers (void)
   assert_perror_backtrace (err);
   err = proc_mark_exec (authproc);
   assert_perror_backtrace (err);
+  proc_set_exe (authproc, "/hurd/auth");
 
   err = install_as_translator ();
   if (err)
@@ -883,6 +885,7 @@ launch_core_servers (void)
     {
       proc_mark_important (procproc);
       proc_mark_exec (procproc);
+      proc_set_exe (procproc, "/hurd/proc");
       mach_port_deallocate (mach_task_self (), procproc);
     }
 
@@ -898,6 +901,7 @@ launch_core_servers (void)
   assert_perror_backtrace (err);
   err = proc_mark_exec (fsproc);
   assert_perror_backtrace (err);
+  proc_set_exe (fsproc, "fs");
 
   fprintf (stderr, ".\n");
 
@@ -1045,6 +1049,8 @@ frob_kernel_process (void)
   err = record_essential_task ("kernel", task);
   assert_perror_backtrace (err);
 
+  proc_set_exe (proc, "kernel");
+
   err = task_get_bootstrap_port (task, &kbs);
   assert_perror_backtrace (err);
   if (kbs == MACH_PORT_NULL)
@@ -1455,6 +1461,7 @@ S_startup_essential_task (mach_port_t server,
           mach_port_t execproc;
           proc_task2proc (procserver, task, &execproc);
           proc_mark_important (execproc);
+          proc_set_exe (execproc, "/hurd/exec");
         }
       else if (!strcmp (name, "proc"))
        procinit = 1;

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

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