summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-09-23 11:42:43 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-09-29 12:34:20 +0200
commitaf77f771b687d3653018bc18b1b07a4805beaa19 (patch)
tree3077e15108f2f0fe23a9ca092e26709cc1de81e6
parent1a22019e6a86d0636f9847f8891f280facd2fd22 (diff)
exec: add proper argument parsing, add --device-master-port
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.
-rw-r--r--exec/main.c106
1 files changed, 93 insertions, 13 deletions
diff --git a/exec/main.c b/exec/main.c
index 78faebd4..784000b8 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);