This can be used to set/override system properties. Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- vm/jato.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 122 insertions(+), 19 deletions(-)
diff --git a/vm/jato.c b/vm/jato.c index b7f7e3d..f75ca00 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -51,6 +51,8 @@ #include "jit/perf-map.h" #include "jit/text.h" +#include "lib/list.h" + #include "vm/class.h" #include "vm/classloader.h" #include "vm/fault-inject.h" @@ -112,32 +114,86 @@ static void vm_properties_set_property(struct vm_object *p, } struct system_properties_entry { - const char *key; - const char *value; + char *key; + char *value; + struct list_head list_node; }; -static const struct system_properties_entry system_properties[] = { - { "java.vm.name", "jato" }, - { "java.io.tmpdir", "/tmp" }, - { "file.separator", "/" }, - { "path.separator", ":" }, - { "line.separator", "\n" }, -}; +static struct list_head system_properties_list; -static void native_vmsystemproperties_preinit(struct vm_object *p) +static void add_system_property(char *key, char *value) +{ + struct system_properties_entry *this; + + assert(key && value); + + list_for_each_entry(this, &system_properties_list, list_node) { + if (strcmp(this->key, key) == 0) { + free(this->value); + free(key); + + this->value = value; + return; + } + } + + struct system_properties_entry *ent = malloc(sizeof *ent); + if (!ent) + error("out of memory"); + + ent->key = key; + ent->value = value; + list_add(&ent->list_node, &system_properties_list); +} + +static void add_system_property_const(const char *key, const char *value) { - char *s; + char *key_d; + char *value_d; + + key_d = strdup(key); + value_d = strdup(value); + + if (!key_d || !value_d) + error("out of memory"); + + add_system_property(key_d, value_d); +} - s = getenv("LD_LIBRARY_PATH"); +/* + * This sets default values of system properties. It should be called + * before command line arguments are parsed because these properties + * can be overriden by -Dkey=value option. + */ +static void init_system_properties(void) { + INIT_LIST_HEAD(&system_properties_list); + + add_system_property_const("java.vm.name", "jato"); + add_system_property_const("java.io.tmpdir", "/tmp"); + add_system_property_const("file.separator", "/"); + add_system_property_const("path.separator", ":"); + add_system_property_const("line.separator", "\n"); + + const char *s = getenv("LD_LIBRARY_PATH"); if (!s) s = "/usr/lib/classpath/"; - vm_properties_set_property(p, "java.library.path", s); + add_system_property_const("java.library.path", s); +} + +static void native_vmsystemproperties_preinit(struct vm_object *p) +{ + struct system_properties_entry *this, *t; - for (unsigned int i = 0; i < ARRAY_SIZE(system_properties); ++i) { - const struct system_properties_entry *e = &system_properties[i]; + list_for_each_entry(this, &system_properties_list, list_node) + vm_properties_set_property(p, this->key, this->value); - vm_properties_set_property(p, e->key, e->value); + /* dealloc system properties list */ + list_for_each_entry_safe(this, t, &system_properties_list, list_node) { + free(this->key); + free(this->value); + list_del(&this->list_node); + free(this); } } @@ -570,10 +626,39 @@ static void handle_trace_trampoline(void) opt_trace_magic_trampoline = true; } +static void handle_define(const char *arg) +{ + char *str, *ptr, *key, *value; + + str = strdup(arg); + if (!str) + error("out of memory"); + + key = strtok_r(str, "=", &ptr); + value = strtok_r(NULL, "=", &ptr); + + if (!key || !*key) + goto out; + + if (!value) + value = ""; + + key = strdup(key); + value = strdup(value); + + if (!key || !value) + error("out of memory"); + + add_system_property(key, value); + out: + free(str); +} + struct option { const char *name; bool arg; + bool arg_is_adjacent; union { void (*func)(void); @@ -585,12 +670,17 @@ struct option { { .name = _name, .arg = false, .handler.func = _handler } #define DEFINE_OPTION_ARG(_name, _handler) \ - { .name = _name, .arg = true, .handler.func_arg = _handler } + { .name = _name, .arg = true, .arg_is_adjacent = false, .handler.func_arg = _handler } + +#define DEFINE_OPTION_ADJACENT_ARG(_name, _handler) \ + { .name = _name, .arg = true, .arg_is_adjacent = true, .handler.func_arg = _handler } const struct option options[] = { DEFINE_OPTION("h", handle_help), DEFINE_OPTION("help", handle_help), + DEFINE_OPTION_ADJACENT_ARG("D", handle_define), + DEFINE_OPTION_ARG("classpath", handle_classpath), DEFINE_OPTION_ARG("cp", handle_classpath), DEFINE_OPTION_ARG("jar", handle_jar), @@ -612,8 +702,14 @@ const struct option options[] = { static const struct option *get_option(const char *name) { for (unsigned int i = 0; i < ARRAY_SIZE(options); ++i) { - if (!strcmp(name, options[i].name)) - return &options[i]; + const struct option *opt = &options[i]; + + if (opt->arg && opt->arg_is_adjacent && + !strncmp(name, opt->name, strlen(opt->name))) + return opt; + + if (!strcmp(name, opt->name)) + return opt; } return NULL; @@ -636,6 +732,12 @@ static void parse_options(int argc, char *argv[]) continue; } + if (opt->arg_is_adjacent) { + opt->handler.func_arg(argv[optind] + strlen(opt->name) + + 1); + continue; + } + /* We wanted an argument, but there was none */ if (optind + 1 >= argc) usage(stderr, EXIT_FAILURE); @@ -673,6 +775,7 @@ main(int argc, char *argv[]) setvbuf(stderr, NULL, _IONBF, 0); #endif + init_system_properties(); parse_options(argc, argv); init_vm_objects(); -- 1.6.0.6 ------------------------------------------------------------------------------ _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel