From e3707dc9deb28d5144836032a54dbc028247835d Mon Sep 17 00:00:00 2001 From: Jeremie Koenig Date: Mon, 23 Aug 2010 05:19:19 +0000 Subject: Add a global cmdline file * main.c (argp_parser, main): Add the --kernel-pid option. * main.h: Publish it. * rootdir.c (rootdir_gc_cmdline): New function. --- main.c | 11 +++++++++++ main.h | 1 + rootdir.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/main.c b/main.c index 26f5248f..fee4867c 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,7 @@ int opt_clk_tck; mode_t opt_stat_mode; pid_t opt_fake_self; +pid_t opt_kernel_pid; static error_t argp_parser (int key, char *arg, struct argp_state *state) @@ -44,6 +45,12 @@ argp_parser (int key, char *arg, struct argp_state *state) else opt_fake_self = 1; break; + + case 'k': + opt_kernel_pid = strtol (arg, &endp, 0); + if (*endp || ! *arg || (signed) opt_kernel_pid < 0) + error (1, 0, "--kernel-process: PID must be a positive integer"); + break; } return 0; @@ -64,6 +71,9 @@ struct argp argp = { "Provide a fake \"self\" symlink to the given PID, for compatibility " "purposes. If PID is omitted, \"self\" will point to init. " "(default: no self link)" }, + { "kernel-process", 'k', "PID", 0, + "Process identifier for the kernel, used to retreive its command line " + "(default: 2)" }, {} }, .parser = argp_parser, @@ -112,6 +122,7 @@ int main (int argc, char **argv) opt_clk_tck = sysconf(_SC_CLK_TCK); opt_stat_mode = 0400; opt_fake_self = -1; + opt_kernel_pid = 2; argp_parse (&argp, argc, argv, 0, 0, 0); task_get_bootstrap_port (mach_task_self (), &bootstrap); diff --git a/main.h b/main.h index 361380b3..6ada229a 100644 --- a/main.h +++ b/main.h @@ -2,3 +2,4 @@ extern int opt_clk_tck; extern mode_t opt_stat_mode; extern pid_t opt_fake_self; +extern pid_t opt_kernel_pid; diff --git a/rootdir.c b/rootdir.c index f5b43ff0..865342ce 100644 --- a/rootdir.c +++ b/rootdir.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "procfs.h" #include "procfs_dir.h" @@ -230,6 +231,41 @@ rootdir_gc_vmstat (void *hook, void **contents, size_t *contents_len) return *contents_len >= 0 ? 0 : ENOMEM; } +static error_t +rootdir_gc_cmdline (void *hook, void **contents, size_t *contents_len) +{ + struct ps_context *pc = hook; + struct proc_stat *ps; + error_t err; + + err = _proc_stat_create (opt_kernel_pid, pc, &ps); + if (err) + return EIO; + + err = proc_stat_set_flags (ps, PSTAT_ARGS); + if (err || ! (proc_stat_flags (ps) & PSTAT_ARGS)) + { + err = EIO; + goto out; + } + + *contents_len = proc_stat_args_len (ps); + *contents = malloc (*contents_len); + if (! *contents) + { + err = ENOMEM; + goto out; + } + + memcpy (*contents, proc_stat_args (ps), *contents_len); + argz_stringify (*contents, *contents_len, ' '); + ((char *) *contents)[*contents_len - 1] = '\n'; + +out: + _proc_stat_free (ps); + return err; +} + static error_t rootdir_gc_fakeself (void *hook, void **contents, size_t *contents_len) { @@ -310,6 +346,14 @@ static const struct procfs_dir_entry rootdir_entries[] = { .cleanup_contents = procfs_cleanup_contents_with_free, }, }, + { + .name = "cmdline", + .make_node = rootdir_file_make_node, + .hook = & (struct procfs_node_ops) { + .get_contents = rootdir_gc_cmdline, + .cleanup_contents = procfs_cleanup_contents_with_free, + }, + }, {} }; -- cgit v1.2.3