diff --git a/dependencies/tlibc b/dependencies/tlibc index 649c2c0..9db2d00 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit 649c2c09680dbd7de3e245e2b5fcd710201ba6ab +Subproject commit 9db2d003f505013b620bbfc8bd4559f3e381e247 diff --git a/mono-apphost.toml b/mono-apphost.toml index f19d690..f039e43 100644 --- a/mono-apphost.toml +++ b/mono-apphost.toml @@ -1,5 +1,6 @@ main_assembly_path="Program.dll" mono_libs_dir="mono-libs" +working_dir="" # error, critical, warning, message, info, debug (default=error) trace_level="" diff --git a/src/main.c b/src/main.c index f0fbcc0..c3c9e34 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,7 @@ static const cstr DOMAIN_NAME = "mono-apphost"; typedef struct ApphostConfig { char* main_assembly_path; char* mono_libs_dir; + NULLABLE(char*) working_dir; // error, critical, warning, message, info, debug (default=error) NULLABLE(char*) trace_level; @@ -30,6 +31,7 @@ void ApphostConfig_free(ApphostConfig* conf){ return; free(conf->main_assembly_path); free(conf->mono_libs_dir); + free(conf->working_dir); free(conf->trace_level); free(conf->trace_mask); free(conf); @@ -95,9 +97,33 @@ Result(ApphostConfig*) ApphostConfig_load_filename(cstr _conf_path_raw){ conf->mono_libs_dir = str_copy(*mono_libs_dir).data; + // working_dir + NULLABLE(TomlValue*) working_dir = TomlTable_tryGet(config_top, STR("working_dir")); + if(working_dir){ + if(working_dir->type != TLIBTOML_STRING){ + Return RESULT_ERROR_LITERAL("working_dir: value must be a string"); + } + + if(working_dir->s->len != 0){ + path_fix_separators(working_dir->s); + if(!dir_exists(working_dir->s->data)){ + char* err = sprintf_malloc( + "working_dir: directory '%s' doesn't exist", + working_dir->s->data); + Return RESULT_ERROR_HEAP(err); + } + + conf->working_dir = str_copy(*working_dir->s).data; + } + } + + // trace_level NULLABLE(TomlValue*) trace_level = TomlTable_tryGet(config_top, STR("trace_level")); if(trace_level){ + if(trace_level->type != TLIBTOML_STRING){ + Return RESULT_ERROR_LITERAL("trace_level: value must be a string"); + } if(trace_level->s->len != 0) conf->trace_level = str_copy(*trace_level->s).data; } @@ -105,6 +131,9 @@ Result(ApphostConfig*) ApphostConfig_load_filename(cstr _conf_path_raw){ // trace_mask NULLABLE(TomlValue*) trace_mask = TomlTable_tryGet(config_top, STR("trace_mask")); if(trace_mask){ + if(trace_mask->type != TLIBTOML_STRING){ + Return RESULT_ERROR_LITERAL("trace_mask: value must be a string"); + } if(trace_mask->s->len != 0) conf->trace_mask = str_copy(*trace_mask->s).data; } @@ -115,15 +144,13 @@ Result(ApphostConfig*) ApphostConfig_load_filename(cstr _conf_path_raw){ void trace_print_handler(const char *message, mono_bool is_stdout){ - FILE* stream = is_stdout ? stdout : stderr; - fprintf(stream, "[MonoPrint]: %s\n", message); + printfe("[MonoPrint]: %s\n", message); } void trace_log_handler(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) { - FILE* stream = stderr; - fprintf(stream, "[%s/%s]: %s\n", log_domain, log_level, message); + printfe("[%s/%s]: %s\n", log_domain, log_level, message); } @@ -177,6 +204,10 @@ Result(i32) try_main(i32 argc, cstr* argv){ try(MonoAssembly* assembly, p, load_assembly(domain, conf->main_assembly_path)) + if(conf->working_dir){ + try_void(dir_setCurrent(conf->working_dir)); + } + i32 ret = mono_jit_exec(domain, assembly, argc, (char**)(argv)); Return RESULT_VALUE(i, ret); }