summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Koenig <jk@jk.fr.eu.org>2010-08-22 21:23:36 +0000
committerJeremie Koenig <jk@jk.fr.eu.org>2010-08-30 14:29:51 +0200
commit4665f087fde174a9de3e1c3f3de090dd4bfa85e0 (patch)
tree111edd6241a6fc5b493939e9379f19396a097992
parent5714e1cef2584410a7823c7ead9d2435141fb0c4 (diff)
Add a fake-self option to control the self symlink
* main.c (argp_parse, main): Add the --fake-self option. * main.h: Publish it. * rootdir.c (rootdir_gc_fakeself, rootdir_entries, rootdir_create_node): Use it.
-rw-r--r--main.c17
-rw-r--r--main.h1
-rw-r--r--rootdir.c30
3 files changed, 35 insertions, 13 deletions
diff --git a/main.c b/main.c
index 09cffc7..26f5248 100644
--- a/main.c
+++ b/main.c
@@ -13,6 +13,7 @@
/* Command-line options */
int opt_clk_tck;
mode_t opt_stat_mode;
+pid_t opt_fake_self;
static error_t
argp_parser (int key, char *arg, struct argp_state *state)
@@ -32,6 +33,17 @@ argp_parser (int key, char *arg, struct argp_state *state)
if (*endp || ! *arg || opt_stat_mode & ~07777)
error (1, 0, "--stat-mode: MODE should be an octal mode");
break;
+
+ case 'S':
+ if (arg)
+ {
+ opt_fake_self = strtol (arg, &endp, 0);
+ if (*endp || ! *arg)
+ error (1, 0, "--fake-self: PID must be an integer");
+ }
+ else
+ opt_fake_self = 1;
+ break;
}
return 0;
@@ -48,6 +60,10 @@ struct argp argp = {
"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)" },
{}
},
.parser = argp_parser,
@@ -95,6 +111,7 @@ int main (int argc, char **argv)
opt_clk_tck = sysconf(_SC_CLK_TCK);
opt_stat_mode = 0400;
+ opt_fake_self = -1;
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 6669d32..361380b 100644
--- a/main.h
+++ b/main.h
@@ -1,3 +1,4 @@
/* Startup options */
extern int opt_clk_tck;
extern mode_t opt_stat_mode;
+extern pid_t opt_fake_self;
diff --git a/rootdir.c b/rootdir.c
index 1d9c083..833fc15 100644
--- a/rootdir.c
+++ b/rootdir.c
@@ -156,9 +156,8 @@ rootdir_gc_empty (void *hook, void **contents, size_t *contents_len)
static error_t
rootdir_gc_fakeself (void *hook, void **contents, size_t *contents_len)
{
- *contents = "1";
- *contents_len = strlen (*contents);
- return 0;
+ *contents_len = asprintf ((char **) contents, "%d", opt_fake_self);
+ return *contents_len >= 0 ? 0 : ENOMEM;
}
@@ -177,7 +176,15 @@ rootdir_symlink_make_node (void *dir_hook, void *entry_hook)
return np;
}
-static struct procfs_dir_entry rootdir_entries[] = {
+static const struct procfs_dir_entry rootdir_entries[] = {
+ {
+ .name = "self",
+ .make_node = rootdir_symlink_make_node,
+ .hook = & (struct procfs_node_ops) {
+ .get_contents = rootdir_gc_fakeself,
+ .cleanup_contents = procfs_cleanup_contents_with_free,
+ },
+ },
{
.name = "version",
.make_node = rootdir_file_make_node,
@@ -217,13 +224,6 @@ static struct procfs_dir_entry rootdir_entries[] = {
.get_contents = rootdir_gc_empty,
},
},
- {
- .name = "self",
- .make_node = rootdir_symlink_make_node,
- .hook = & (struct procfs_node_ops) {
- .get_contents = rootdir_gc_fakeself,
- },
- },
{}
};
@@ -231,14 +231,18 @@ error_t
rootdir_create_node (struct node **np)
{
struct ps_context *pc;
+ const struct procfs_dir_entry *entries;
error_t err;
err = ps_context_create (getproc (), &pc);
if (err)
return err;
- *np = procfs_dir_make_node (rootdir_entries, pc,
- (void (*)(void *)) ps_context_free);
+ entries = rootdir_entries;
+ if (opt_fake_self < 0)
+ entries++;
+
+ *np = procfs_dir_make_node (entries, pc, (void (*)(void *)) ps_context_free);
return 0;
}