diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-09-23 11:42:43 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-09-29 12:34:20 +0200 |
commit | af77f771b687d3653018bc18b1b07a4805beaa19 (patch) | |
tree | 3077e15108f2f0fe23a9ca092e26709cc1de81e6 /exec/main.c | |
parent | 1a22019e6a86d0636f9847f8891f280facd2fd22 (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.
Diffstat (limited to 'exec/main.c')
-rw-r--r-- | exec/main.c | 106 |
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); |