This can be used to set/override system properties.
Signed-off-by: Tomek Grabiec <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel