summaryrefslogtreecommitdiff
path: root/procfs/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'procfs/main.c')
-rw-r--r--procfs/main.c165
1 files changed, 127 insertions, 38 deletions
diff --git a/procfs/main.c b/procfs/main.c
index 90b3e92c..54e96823 100644
--- a/procfs/main.c
+++ b/procfs/main.c
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <error.h>
#include <argp.h>
+#include <argz.h>
#include <hurd/netfs.h>
#include <ps.h>
#include "procfs.h"
@@ -37,6 +38,13 @@ pid_t opt_fake_self;
pid_t opt_kernel_pid;
uid_t opt_anon_owner;
+/* Default values */
+#define OPT_CLK_TCK sysconf(_SC_CLK_TCK)
+#define OPT_STAT_MODE 0400
+#define OPT_FAKE_SELF -1
+#define OPT_KERNEL_PID 2
+#define OPT_ANON_OWNER 0
+
#define NODEV_KEY -1 /* <= 0, so no short option. */
#define NOEXEC_KEY -2 /* Likewise. */
#define NOSUID_KEY -3 /* Likewise. */
@@ -120,50 +128,90 @@ argp_parser (int key, char *arg, struct argp_state *state)
case NOSUID_KEY:
/* Ignored for compatibility with Linux' procfs. */
;;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
}
return 0;
}
+struct argp_option common_options[] = {
+ { "clk-tck", 'h', "HZ", 0,
+ "Unit used for the values expressed in system clock ticks "
+ "(default: sysconf(_SC_CLK_TCK))" },
+ { "stat-mode", 's', "MODE", 0,
+ "The [pid]/stat file publishes information which on Hurd is only "
+ "available to the process owner. "
+ "You can use this option to override its mode to be more permissive "
+ "for compatibility purposes. "
+ "(default: 0400)" },
+ { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL,
+ "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, as well as the global up and idle times. "
+ "(default: 2)" },
+ { "compatible", 'c', NULL, 0,
+ "Try to be compatible with the Linux procps utilities. "
+ "Currently equivalent to -h 100 -s 0444 -S 1." },
+ { "anonymous-owner", 'a', "USER", 0,
+ "Make USER the owner of files related to processes without one. "
+ "Be aware that USER will be granted access to the environment and "
+ "other sensitive information about the processes in question. "
+ "(default: use uid 0)" },
+ { "nodev", NODEV_KEY, NULL, 0,
+ "Ignored for compatibility with Linux' procfs." },
+ { "noexec", NOEXEC_KEY, NULL, 0,
+ "Ignored for compatibility with Linux' procfs." },
+ { "nosuid", NOSUID_KEY, NULL, 0,
+ "Ignored for compatibility with Linux' procfs." },
+ {}
+};
+
struct argp argp = {
- .options = (struct argp_option []) {
- { "clk-tck", 'h', "HZ", 0,
- "Unit used for the values expressed in system clock ticks "
- "(default: sysconf(_SC_CLK_TCK))" },
- { "stat-mode", 's', "MODE", 0,
- "The [pid]/stat file publishes information which on Hurd is only "
- "available to the process owner. "
- "You can use this option to override its mode to be more permissive "
- "for compatibility purposes. "
- "(default: 0400)" },
- { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL,
- "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, as well as the global up and idle times. "
- "(default: 2)" },
- { "compatible", 'c', NULL, 0,
- "Try to be compatible with the Linux procps utilities. "
- "Currently equivalent to -h 100 -s 0444 -S 1." },
- { "anonymous-owner", 'a', "USER", 0,
- "Make USER the owner of files related to processes without one. "
- "Be aware that USER will be granted access to the environment and "
- "other sensitive information about the processes in question. "
- "(default: use uid 0)" },
- { "nodev", NODEV_KEY, NULL, 0,
- "Ignored for compatibility with Linux' procfs." },
- { "noexec", NOEXEC_KEY, NULL, 0,
- "Ignored for compatibility with Linux' procfs." },
- { "nosuid", NOSUID_KEY, NULL, 0,
- "Ignored for compatibility with Linux' procfs." },
+ .options = common_options,
+ .parser = argp_parser,
+ .doc = "A virtual filesystem emulating the Linux procfs.",
+ .children = (struct argp_child []) {
+ { &netfs_std_startup_argp, },
{}
},
+};
+
+static error_t
+runtime_argp_parser (int key, char *arg, struct argp_state *state)
+{
+ switch (key)
+ {
+ case 'u':
+ /* do nothing */
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+
+ return 0;
+}
+
+struct argp runtime_argp = {
+ .options = (struct argp_option []) {
+ { "update", 'u', NULL, 0, "remount; for procfs this does nothing" },
+ {},
+ },
+ .parser = runtime_argp_parser,
+};
+
+struct argp netfs_runtime_argp_ = {
+ .options = common_options,
.parser = argp_parser,
.doc = "A virtual filesystem emulating the Linux procfs.",
.children = (struct argp_child []) {
- { &netfs_std_startup_argp, },
+ { &runtime_argp, },
+ { &netfs_std_runtime_argp, },
{}
},
};
@@ -171,6 +219,47 @@ struct argp argp = {
/* Used by netfs_set_options to handle runtime option parsing. */
struct argp *netfs_runtime_argp = &argp;
+/* Return an argz string describing the current options. Fill *ARGZ
+ with a pointer to newly malloced storage holding the list and *LEN
+ to the length of that storage. */
+error_t
+netfs_append_args (char **argz, size_t *argz_len)
+{
+ char buf[80];
+ error_t err = 0;
+
+#define FOPT(opt, default, fmt, args...) \
+ do { \
+ if (! err && opt != default) \
+ { \
+ snprintf (buf, sizeof buf, fmt, ## args); \
+ err = argz_add (argz, argz_len, buf); \
+ } \
+ } while (0)
+
+ FOPT (opt_clk_tck, OPT_CLK_TCK,
+ "--clk-tck=%d", opt_clk_tck);
+
+ FOPT (opt_stat_mode, OPT_STAT_MODE,
+ "--stat-mode=%o", opt_stat_mode);
+
+ FOPT (opt_fake_self, OPT_FAKE_SELF,
+ "--fake-self=%d", opt_fake_self);
+
+ FOPT (opt_anon_owner, OPT_ANON_OWNER,
+ "--anonymous-owner=%d", opt_anon_owner);
+
+ FOPT (opt_kernel_pid, OPT_KERNEL_PID,
+ "--kernel-process=%d", opt_kernel_pid);
+
+#undef FOPT
+
+ if (! err)
+ err = netfs_append_std_options (argz, argz_len);
+
+ return err;
+}
+
error_t
root_make_node (struct ps_context *pc, struct node **np)
{
@@ -196,11 +285,11 @@ int main (int argc, char **argv)
mach_port_t bootstrap;
error_t err;
- opt_clk_tck = sysconf(_SC_CLK_TCK);
- opt_stat_mode = 0400;
- opt_fake_self = -1;
- opt_kernel_pid = 2;
- opt_anon_owner = 0;
+ opt_clk_tck = OPT_CLK_TCK;
+ opt_stat_mode = OPT_STAT_MODE;
+ opt_fake_self = OPT_FAKE_SELF;
+ opt_kernel_pid = OPT_KERNEL_PID;
+ opt_anon_owner = OPT_ANON_OWNER;
err = argp_parse (&argp, argc, argv, 0, 0, 0);
if (err)
error (1, err, "Could not parse command line");