bug-hurd
[Top][All Lists]
Advanced

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

[PATCH] exec: add proper argument parsing, add --device-master-port


From: Justus Winter
Subject: [PATCH] exec: add proper argument parsing, add --device-master-port
Date: Tue, 23 Sep 2014 12:33:06 +0200

If the device master port is given, a boot-time exec server can print
diagnostic messages earlier.

* exec/main.c (opt_device_master): New variable.
(OPT_DEVICE_MASTER_PORT): New macro.
(options): New set of options.
(parse_opt): New function.
(trivfs_append_args): Likewise.
(argp): Pull the argp definition out of main.
(trivfs_runtime_argp): Set, so that we respond properly to fsysopts.
(open_console): Pull the code out of S_exec_init and generalize it.
(main): Call open_console if a device master port is given.
(S_exec_init): Call open_console.
---
 exec/main.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 93 insertions(+), 13 deletions(-)

diff --git a/exec/main.c b/exec/main.c
index 78faebd..784000b 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -45,6 +45,7 @@ int trivfs_cntl_nportclasses = 1;
 struct trivfs_control *fsys;
 
 char **save_argv;
+mach_port_t opt_device_master;
 
 
 #include "exec_S.h"
@@ -104,16 +105,104 @@ deadboot (void *p)
   ports_enable_class (trivfs_cntl_portclasses[0]);
 }
 
+#define OPT_DEVICE_MASTER_PORT (-1)
+
+static const struct argp_option options[] =
+{
+  {"device-master-port", OPT_DEVICE_MASTER_PORT, "PORT", 0,
+   "If specified, a boot-time exec server can print "
+   "diagnostic messages earlier.", 0},
+  {0}
+};
+
+static error_t
+parse_opt (int opt, char *arg, struct argp_state *state)
+{
+  switch (opt)
+    {
+    default:
+      return ARGP_ERR_UNKNOWN;
+    case ARGP_KEY_INIT:
+    case ARGP_KEY_SUCCESS:
+    case ARGP_KEY_ERROR:
+      break;
+
+    case OPT_DEVICE_MASTER_PORT:
+      opt_device_master = atoi (arg);
+      break;
+    }
+  return 0;
+}
+
+/* This will be called from libtrivfs to help construct the answer
+   to an fsys_get_options RPC.  */
+error_t
+trivfs_append_args (struct trivfs_control *fsys,
+                   char **argz, size_t *argz_len)
+{
+  error_t err = 0;
+  char *opt;
+
+  if (MACH_PORT_VALID (opt_device_master))
+    {
+      asprintf (&opt, "--device-master-port=%d", opt_device_master);
+
+      if (opt)
+       {
+         err = argz_add (argz, argz_len, opt);
+         free (opt);
+       }
+    }
+
+  return err;
+}
+
+static struct argp argp =
+{ options, parse_opt, 0, "Hurd standard exec server." };
+
+/* Setting this variable makes libtrivfs use our argp to
+   parse options passed in an fsys_set_options RPC.  */
+struct argp *trivfs_runtime_argp = &argp;
+
+/* Get our stderr set up to print on the console, in case we have to
+   panic or something.  */
+error_t
+open_console (mach_port_t device_master)
+{
+  static int got_console = 0;
+  mach_port_t cons;
+  error_t err;
+
+  if (got_console)
+    return 0;
+
+  err = device_open (device_master, D_READ|D_WRITE, "console", &cons);
+  if (err)
+    return err;
+
+  stdin = mach_open_devstream (cons, "r");
+  stdout = stderr = mach_open_devstream (cons, "w");
+
+  got_console = 1;
+  mach_port_deallocate (mach_task_self (), cons);
+  return 0;
+}
 
 int
 main (int argc, char **argv)
 {
   error_t err;
   mach_port_t bootstrap;
-  struct argp argp = { 0, 0, 0, "Hurd standard exec server." };
 
   argp_parse (&argp, argc, argv, 0, 0, 0);
 
+  if (MACH_PORT_VALID (opt_device_master))
+    {
+      err = open_console (opt_device_master);
+      assert_perror (err);
+      mach_port_deallocate (mach_task_self (), opt_device_master);
+    }
+
   save_argv = argv;
 
   task_get_bootstrap_port (mach_task_self (), &bootstrap);
@@ -236,18 +325,9 @@ S_exec_init (struct trivfs_protid *protid,
   err = get_privileged_ports (&host_priv, &device_master);
   assert_perror (err);
 
-  {
-    /* Get our stderr set up to print on the console, in case we have
-       to panic or something.  */
-    mach_port_t cons;
-    error_t err;
-    err = device_open (device_master, D_READ|D_WRITE, "console", &cons);
-    assert_perror (err);
-    mach_port_deallocate (mach_task_self (), device_master);
-    stdin = mach_open_devstream (cons, "r");
-    stdout = stderr = mach_open_devstream (cons, "w");
-    mach_port_deallocate (mach_task_self (), cons);
-  }
+  err = open_console (device_master);
+  assert_perror (err);
+  mach_port_deallocate (mach_task_self (), device_master);
 
   proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION);
 
-- 
2.1.0




reply via email to

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