diff options
Diffstat (limited to 'erts/etc')
27 files changed, 1878 insertions, 1656 deletions
diff --git a/erts/etc/common/ct_run.c b/erts/etc/common/ct_run.c index 853785dcd1..bb59b93998 100644 --- a/erts/etc/common/ct_run.c +++ b/erts/etc/common/ct_run.c @@ -117,9 +117,14 @@ char *strerror(int errnum) } #endif /* !HAVE_STRERROR */ -int -main(int argc, char** argv) +#ifdef __WIN32__ +int wmain(int argc, wchar_t **wcargv) +{ + char** argv; +#else +int main(int argc, char** argv) { +#endif int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; @@ -129,7 +134,21 @@ main(int argc, char** argv) int dist_mode; int cnt; int erl_args; - char** argv0 = argv; + char** argv0; + +#ifdef __WIN32__ + int i; + int len; + /* Convert argv to utf8 */ + argv = malloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = malloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL); + } + argv[argc] = NULL; +#endif + argv0 = argv; emulator = get_default_emulator(argv[0]); @@ -295,48 +314,50 @@ push_words(char* src) PUSH(strsave(sbuf)); } #ifdef __WIN32__ -char *make_commandline(char **argv) +wchar_t *make_commandline(char **argv) { - static char *buff = NULL; + static wchar_t *buff = NULL; static int siz = 0; - int num = 0; - char **arg, *p; + int num = 0, len; + char **arg; + wchar_t *p; - if (*argv == NULL) { - return ""; + if (*argv == NULL) { + return L""; } for (arg = argv; *arg != NULL; ++arg) { num += strlen(*arg)+1; } if (!siz) { siz = num; - buff = malloc(siz*sizeof(char)); + buff = (wchar_t *) emalloc(siz*sizeof(wchar_t)); } else if (siz < num) { siz = num; - buff = realloc(buff,siz*sizeof(char)); + buff = (wchar_t *) realloc(buff,siz*sizeof(wchar_t)); } p = buff; + num=0; for (arg = argv; *arg != NULL; ++arg) { - strcpy(p,*arg); - p+=strlen(*arg); - *p++=' '; + len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, p, siz); + p+=(len-1); + *p++=L' '; } - *(--p) = '\0'; + *(--p) = L'\0'; if (debug) { - printf("Processed commandline:%s\n",buff); + printf("Processed command line:%S\n",buff); } return buff; } int my_spawnvp(char **argv) { - STARTUPINFO siStartInfo; + STARTUPINFOW siStartInfo; PROCESS_INFORMATION piProcInfo; DWORD ec; - memset(&siStartInfo,0,sizeof(STARTUPINFO)); - siStartInfo.cb = sizeof(STARTUPINFO); + memset(&siStartInfo,0,sizeof(STARTUPINFOW)); + siStartInfo.cb = sizeof(STARTUPINFOW); siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); @@ -345,7 +366,7 @@ int my_spawnvp(char **argv) siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - if (!CreateProcess(NULL, + if (!CreateProcessW(NULL, make_commandline(argv), NULL, NULL, @@ -432,6 +453,18 @@ strsave(char* string) return p; } +static int +file_exists(char *progname) +{ +#ifdef __WIN32__ + wchar_t wcsbuf[MAXPATHLEN]; + MultiByteToWideChar(CP_UTF8, 0, progname, -1, wcsbuf, MAXPATHLEN); + return (_waccess(wcsbuf, 0) != -1); +#else + return (access(progname, 1) != -1); +#endif +} + static char* get_default_emulator(char* progname) { @@ -445,15 +478,8 @@ get_default_emulator(char* progname) for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { strcpy(s+1, ERL_NAME); -#ifdef __WIN32__ - if (_access(sbuf, 0) != -1) { + if(file_exists(sbuf)) return strsave(sbuf); - } -#else - if (access(sbuf, 1) != -1) { - return strsave(sbuf); - } -#endif break; } } diff --git a/erts/etc/common/dialyzer.c b/erts/etc/common/dialyzer.c index b8a7a2bf03..09afb25182 100644 --- a/erts/etc/common/dialyzer.c +++ b/erts/etc/common/dialyzer.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2006-2012. All Rights Reserved. + * Copyright Ericsson AB 2006-2013. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -104,20 +104,31 @@ get_env(char *key) { #ifdef __WIN32__ DWORD size = 32; - char *value = NULL; + char *value=NULL; + wchar_t *wcvalue = NULL; + wchar_t wckey[256]; + int len; + + MultiByteToWideChar(CP_UTF8, 0, key, -1, wckey, 256); + while (1) { DWORD nsz; - if (value) - free(value); - value = emalloc(size); + if (wcvalue) + free(wcvalue); + wcvalue = (wchar_t*) emalloc(size*sizeof(wchar_t)); SetLastError(0); - nsz = GetEnvironmentVariable((LPCTSTR) key, (LPTSTR) value, size); + nsz = GetEnvironmentVariableW(wckey, wcvalue, size); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { - free(value); + free(wcvalue); return NULL; } - if (nsz <= size) + if (nsz <= size) { + len = WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, NULL, 0, NULL, NULL); + value = emalloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, value, len, NULL, NULL); + free(wcvalue); return value; + } size = nsz; } #else @@ -134,9 +145,14 @@ free_env_val(char *value) #endif } -int -main(int argc, char** argv) +#ifdef __WIN32__ +int wmain(int argc, wchar_t **wcargv) +{ + char** argv; +#else +int main(int argc, char** argv) { +#endif int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; @@ -144,6 +160,18 @@ main(int argc, char** argv) int i; int need_shell = 0; +#ifdef __WIN32__ + int len; + /* Convert argv to utf8 */ + argv = malloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = malloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL); + } + argv[argc] = NULL; +#endif + env = get_env("DIALYZER_EMULATOR"); emulator = env ? env : get_default_emulator(argv[0]); @@ -260,49 +288,52 @@ push_words(char* src) if (sbuf[0]) PUSH(strsave(sbuf)); } + #ifdef __WIN32__ -char *make_commandline(char **argv) +wchar_t *make_commandline(char **argv) { - static char *buff = NULL; + static wchar_t *buff = NULL; static int siz = 0; - int num = 0; - char **arg, *p; + int num = 0, len; + char **arg; + wchar_t *p; if (*argv == NULL) { - return ""; + return L""; } for (arg = argv; *arg != NULL; ++arg) { num += strlen(*arg)+1; } if (!siz) { siz = num; - buff = malloc(siz*sizeof(char)); + buff = (wchar_t *) emalloc(siz*sizeof(wchar_t)); } else if (siz < num) { siz = num; - buff = realloc(buff,siz*sizeof(char)); + buff = (wchar_t *) realloc(buff,siz*sizeof(wchar_t)); } p = buff; + num=0; for (arg = argv; *arg != NULL; ++arg) { - strcpy(p,*arg); - p+=strlen(*arg); - *p++=' '; + len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, p, siz); + p+=(len-1); + *p++=L' '; } - *(--p) = '\0'; + *(--p) = L'\0'; if (debug) { - printf("Processed commandline:%s\n",buff); + printf("Processed command line:%S\n",buff); } return buff; } int my_spawnvp(char **argv) { - STARTUPINFO siStartInfo; + STARTUPINFOW siStartInfo; PROCESS_INFORMATION piProcInfo; DWORD ec; - memset(&siStartInfo,0,sizeof(STARTUPINFO)); - siStartInfo.cb = sizeof(STARTUPINFO); + memset(&siStartInfo,0,sizeof(STARTUPINFOW)); + siStartInfo.cb = sizeof(STARTUPINFOW); siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); @@ -311,7 +342,7 @@ int my_spawnvp(char **argv) siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - if (!CreateProcess(NULL, + if (!CreateProcessW(NULL, make_commandline(argv), NULL, NULL, @@ -398,6 +429,18 @@ strsave(char* string) return p; } +static int +file_exists(char *progname) +{ +#ifdef __WIN32__ + wchar_t wcsbuf[MAXPATHLEN]; + MultiByteToWideChar(CP_UTF8, 0, progname, -1, wcsbuf, MAXPATHLEN); + return (_waccess(wcsbuf, 0) != -1); +#else + return (access(progname, 1) != -1); +#endif +} + static char* get_default_emulator(char* progname) { @@ -411,15 +454,8 @@ get_default_emulator(char* progname) for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { strcpy(s+1, ERL_NAME); -#ifdef __WIN32__ - if (_access(sbuf, 0) != -1) { + if(file_exists(sbuf)) return strsave(sbuf); - } -#else - if (access(sbuf, 1) != -1) { - return strsave(sbuf); - } -#endif break; } } diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c index c2d7c7c76d..055064abc4 100644 --- a/erts/etc/common/erlc.c +++ b/erts/etc/common/erlc.c @@ -60,7 +60,6 @@ static int eargc; /* Number of arguments in eargv. */ #define PUSH2(s, t) PUSH(s); PUSH(t) #define PUSH3(s, t, u) PUSH2(s, t); PUSH(u) -static char* output_type = NULL; /* Type of output file. */ #ifdef __WIN32__ static int pause_after_execution = 0; #endif @@ -71,7 +70,6 @@ static int pause_after_execution = 0; static char* process_opt(int* pArgc, char*** pArgv, int offset); static void error(char* format, ...); -static void usage(void); static char* emalloc(size_t size); static char* strsave(char* string); static void push_words(char* src); @@ -114,20 +112,31 @@ get_env(char *key) { #ifdef __WIN32__ DWORD size = 32; - char *value = NULL; + char *value=NULL; + wchar_t *wcvalue = NULL; + wchar_t wckey[256]; + int len; + + MultiByteToWideChar(CP_UTF8, 0, key, -1, wckey, 256); + while (1) { DWORD nsz; - if (value) - free(value); - value = emalloc(size); + if (wcvalue) + free(wcvalue); + wcvalue = (wchar_t *) emalloc(size*sizeof(wchar_t)); SetLastError(0); - nsz = GetEnvironmentVariable((LPCTSTR) key, (LPTSTR) value, size); + nsz = GetEnvironmentVariableW(wckey, wcvalue, size); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { - free(value); + free(wcvalue); return NULL; } - if (nsz <= size) + if (nsz <= size) { + len = WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, NULL, 0, NULL, NULL); + value = emalloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, value, len, NULL, NULL); + free(wcvalue); return value; + } size = nsz; } #else @@ -144,16 +153,32 @@ free_env_val(char *value) #endif } - -int -main(int argc, char** argv) +#ifdef __WIN32__ +int wmain(int argc, wchar_t **wcargv) { - char cwd[MAXPATHLEN]; /* Current working directory. */ + char** argv; +#else +int main(int argc, char** argv) +{ +#endif int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; char *env; +#ifdef __WIN32__ + int i; + int len; + /* Convert argv to utf8 */ + argv = malloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = malloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL); + } + argv[argc] = NULL; +#endif + env = get_env("ERLC_EMULATOR"); emulator = env ? env : get_default_emulator(argv[0]); @@ -191,176 +216,41 @@ main(int argc, char** argv) PUSH2("-mode", "minimal"); PUSH2("-boot", "start_clean"); PUSH3("-s", "erl_compile", "compile_cmdline"); + PUSH("-extra"); /* * Push standard arguments to Erlang. - * - * The @cwd argument was once needed, but from on R13B02 is optional. - * For maximum compatibility between erlc and erl of different versions, - * still provide the @cwd argument, unless it is too long to be - * represented as an atom. */ - if (getcwd(cwd, sizeof(cwd)) == NULL) - error("Failed to get current working directory: %s", strerror(errno)); -#ifdef __WIN32__ - (void) GetShortPathName(cwd, cwd, sizeof(cwd)); -#endif - if (strlen(cwd) < 256) { - PUSH2("@cwd", cwd); - } /* * Parse all command line switches. */ - while (argc > 1 && (argv[1][0] == '-' || argv[1][0] == '+')) { + while (argc > 1) { /* * Options starting with '+' are passed on to Erlang. */ - if (argv[1][0] == '+') { - PUSH2("@option", argv[1]+1); - } else { - /* - * Interpret options starting with '-'. - */ - + switch (argv[1][0]) { + case '+': + PUSH(argv[1]); + break; + case '-': switch (argv[1][1]) { - case 'b': - output_type = process_opt(&argc, &argv, 0); - PUSH2("@output_type", output_type); - break; - case 'c': /* Allowed for compatibility with 'erl'. */ - if (strcmp(argv[1], "-compile") != 0) - goto error; - break; case 'd': - debug = 1; - break; - case 'D': - { - char* def = process_opt(&argc, &argv, 0); - char* equals; - - def = strsave(def); /* Do not clobber original. */ - if ((equals = strchr(def, '=')) == NULL) { - PUSH2("@d", def); - } else { - *equals = '\0'; - equals++; - PUSH3("@dv", def, equals); - } - } - break; - case 'I': - PUSH2("@i", process_opt(&argc, &argv, 0)); - break; - case 'M': - { - char *buf, *key, *val; - size_t buf_len; - - if (argv[1][2] == '\0') { /* -M */ - /* Push the following options: - * o 'makedep' - * o {makedep_output, standard_io} - */ - buf = strsave("makedep"); - PUSH2("@option", buf); - - key = "makedep_output"; - val = "standard_io"; - buf_len = 1 + strlen(key) + 1 + strlen(val) + 1 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,%s}", key, val); - PUSH2("@option", buf); - } else if (argv[1][3] == '\0') { - switch(argv[1][2]) { - case 'D': /* -MD */ - /* Push the following options: - * o 'makedep' - */ - buf = strsave("makedep"); - PUSH2("@option", buf); - break; - case 'F': /* -MF <file> */ - /* Push the following options: - * o 'makedep' - * o {makedep_output, <file>} - */ - buf = strsave("makedep"); - PUSH2("@option", buf); - - key = "makedep_output"; - val = process_opt(&argc, &argv, 1); - buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,\"%s\"}", key, val); - PUSH2("@option", buf); - break; - case 'T': /* -MT <target> */ - /* Push the following options: - * o {makedep_target, <target>} - */ - key = "makedep_target"; - val = process_opt(&argc, &argv, 1); - buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,\"%s\"}", key, val); - PUSH2("@option", buf); - break; - case 'Q': /* -MQ <target> */ - /* Push the following options: - * o {makedep_target, <target>} - * o makedep_quote_target - */ - key = "makedep_target"; - val = process_opt(&argc, &argv, 1); - buf_len = 1 + strlen(key) + 2 + strlen(val) + 2 + 1; - buf = emalloc(buf_len); - snprintf(buf, buf_len, "{%s,\"%s\"}", key, val); - PUSH2("@option", buf); - - buf = strsave("makedep_quote_target"); - PUSH2("@option", buf); - break; - case 'G': /* -MG */ - /* Push the following options: - * o makedep_add_missing - */ - buf = strsave("makedep_add_missing"); - PUSH2("@option", buf); - break; - case 'P': /* -MP */ - /* Push the following options: - * o makedep_phony - */ - buf = strsave("makedep_phony"); - PUSH2("@option", buf); - break; - default: - goto error; - } - } + if (argv[1][2] == '\0') { + debug = 1; + } else { + PUSH(argv[1]); } break; - case 'o': - PUSH2("@outdir", process_opt(&argc, &argv, 0)); - break; - case 'O': - PUSH("@optimize"); - if (argv[1][2] == '\0') - PUSH("1"); - else - PUSH(argv[1]+2); - break; case 'p': { int c = argv[1][2]; if (c != 'a' && c != 'z') { - goto error; + PUSH(argv[1]); #ifdef __WIN32__ } else if (strcmp(argv[1], "-pause") == 0) { pause_after_execution = 1; @@ -381,81 +271,21 @@ main(int argc, char** argv) if (strcmp(argv[1], "-smp") == 0) { UNSHIFT(argv[1]); } else { - goto error; - } - break; - case 'v': /* Verbose. */ - PUSH2("@verbose", "true"); - break; - case 'V': - /** XXX Version perhaps, but of what? **/ - break; - case 'W': /* Enable warnings. */ - if (strcmp(argv[1]+2, "all") == 0) { - PUSH2("@warn", "999"); - } else if (strcmp(argv[1]+2, "error") == 0) { - PUSH2("@option", "warnings_as_errors"); - } else if (isdigit((int)argv[1][2])) { - PUSH2("@warn", argv[1]+2); - } else { - PUSH2("@warn", "1"); - } - break; - case 'E': - case 'S': - case 'P': - { - char* buf; - - /* - * From the given upper-case letter, construct - * a quoted atom. This is a convenience for the - * Erlang compiler, to avoid fighting with the shell's - * quoting. - */ - - buf = emalloc(4); - buf[0] = '\''; - buf[1] = argv[1][1]; - buf[2] = '\''; - buf[3] = '\0'; - - PUSH2("@option", buf); + PUSH(argv[1]); } break; - - case '-': - goto no_more_options; - default: - error: - usage(); + PUSH(argv[1]); break; } + break; + default: + PUSH(argv[1]); + break; } argc--, argv++; } - no_more_options: - - if (argc <= 1) { - /* - * To avoid starting an Erlang system unless absolutely needed - * exit if no files were specified on the command line. - */ - exit(0); - } - - /* - * The rest of the command line must be filenames. Simply push them. - */ - - PUSH("@files"); - while (argc > 1) { - PUSH(argv[1]); - argc--, argv++; - } - /* * Move up the commands for invoking the emulator and adjust eargv * accordingly. @@ -520,48 +350,50 @@ push_words(char* src) PUSH(strsave(sbuf)); } #ifdef __WIN32__ -char *make_commandline(char **argv) +wchar_t *make_commandline(char **argv) { - static char *buff = NULL; + static wchar_t *buff = NULL; static int siz = 0; - int num = 0; - char **arg, *p; + int num = 0, len; + char **arg; + wchar_t *p; if (*argv == NULL) { - return ""; + return L""; } for (arg = argv; *arg != NULL; ++arg) { num += strlen(*arg)+1; } if (!siz) { siz = num; - buff = malloc(siz*sizeof(char)); + buff = (wchar_t *) emalloc(siz*sizeof(wchar_t)); } else if (siz < num) { siz = num; - buff = realloc(buff,siz*sizeof(char)); + buff = (wchar_t *) realloc(buff,siz*sizeof(wchar_t)); } p = buff; + num=0; for (arg = argv; *arg != NULL; ++arg) { - strcpy(p,*arg); - p+=strlen(*arg); - *p++=' '; + len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, p, siz); + p+=(len-1); + *p++=L' '; } - *(--p) = '\0'; + *(--p) = L'\0'; if (debug) { - printf("Processed commandline:%s\n",buff); + printf("Processed command line:%S\n",buff); } return buff; } int my_spawnvp(char **argv) { - STARTUPINFO siStartInfo; + STARTUPINFOW siStartInfo; PROCESS_INFORMATION piProcInfo; DWORD ec; - memset(&siStartInfo,0,sizeof(STARTUPINFO)); - siStartInfo.cb = sizeof(STARTUPINFO); + memset(&siStartInfo,0,sizeof(STARTUPINFOW)); + siStartInfo.cb = sizeof(STARTUPINFOW); siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); @@ -570,7 +402,7 @@ int my_spawnvp(char **argv) siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - if (!CreateProcess(NULL, + if (!CreateProcessW(NULL, make_commandline(argv), NULL, NULL, @@ -633,53 +465,6 @@ run_erlang(char* progname, char** argv) } static void -usage(void) -{ - static struct { - char* name; - char* desc; - } options[] = { - {"-b type", "type of output file (e.g. jam or beam)"}, - {"-d", "turn on debugging of erlc itself"}, - {"-Dname", "define name"}, - {"-Dname=value", "define name to have value"}, - {"-help", "shows this help text"}, - {"-I path", "where to search for include files"}, - {"-M", "generate a rule for make(1) describing the dependencies"}, - {"-MF file", "write the dependencies to 'file'"}, - {"-MT target", "change the target of the rule emitted by dependency " - "generation"}, - {"-MQ target", "same as -MT but quote characters special to make(1)"}, - {"-MG", "consider missing headers as generated files and add them to " - "the dependencies"}, - {"-MP", "add a phony target for each dependency"}, - {"-MD", "same as -M -MT file (with default 'file')"}, - {"-o name", "name output directory or file"}, - {"-pa path", "add path to the front of Erlang's code path"}, - {"-pz path", "add path to the end of Erlang's code path"}, - {"-smp", "compile using SMP emulator"}, - {"-v", "verbose compiler output"}, - {"-Werror", "make all warnings into errors"}, - {"-W0", "disable warnings"}, - {"-Wnumber", "set warning level to number"}, - {"-Wall", "enable all warnings"}, - {"-W", "enable warnings (default; same as -W1)"}, - {"-E", "generate listing of expanded code (Erlang compiler)"}, - {"-S", "generate assembly listing (Erlang compiler)"}, - {"-P", "generate listing of preprocessed code (Erlang compiler)"}, - {"+term", "pass the Erlang term unchanged to the compiler"}, - }; - int i; - - fprintf(stderr, "Usage:\terlc [options] file.ext ...\n"); - fprintf(stderr, "Options:\n"); - for (i = 0; i < sizeof(options)/sizeof(options[0]); i++) { - fprintf(stderr, "%-14s %s\n", options[i].name, options[i].desc); - } - exit(1); -} - -static void error(char* format, ...) { char sbuf[1024]; @@ -709,6 +494,18 @@ strsave(char* string) return p; } +static int +file_exists(char *progname) +{ +#ifdef __WIN32__ + wchar_t wcsbuf[MAXPATHLEN]; + MultiByteToWideChar(CP_UTF8, 0, progname, -1, wcsbuf, MAXPATHLEN); + return (_waccess(wcsbuf, 0) != -1); +#else + return (access(progname, 1) != -1); +#endif +} + static char* get_default_emulator(char* progname) { @@ -722,15 +519,8 @@ get_default_emulator(char* progname) for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { strcpy(s+1, ERL_NAME); -#ifdef __WIN32__ - if (_access(sbuf, 0) != -1) { + if(file_exists(sbuf)) return strsave(sbuf); - } -#else - if (access(sbuf, 1) != -1) { - return strsave(sbuf); - } -#endif break; } } diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 30560f5a2f..00540662fe 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -42,7 +42,7 @@ #define DEFAULT_PROGNAME "erl" #ifdef __WIN32__ -#define INI_FILENAME "erl.ini" +#define INI_FILENAME L"erl.ini" #define INI_SECTION "erlang" #define DIRSEP "\\" #define PATHSEP ";" @@ -103,12 +103,18 @@ static char *plusM_other_switches[] = { "ea", "ummc", "uycs", + "usac", "im", "is", "it", + "lpm", "Mamcbf", "Mrmcbf", "Mmcs", + "Mscs", + "Mscrfsd", + "Msco", + "Mscrpm", "Ye", "Ym", "Ytp", @@ -1189,11 +1195,14 @@ start_epmd(char *epmd) strcat(epmd, arg1); } { - STARTUPINFO start; + wchar_t wcepmd[MAXPATHLEN+100]; + STARTUPINFOW start; PROCESS_INFORMATION pi; memset(&start, 0, sizeof (start)); start.cb = sizeof (start); - if (!CreateProcess(NULL, epmd, NULL, NULL, FALSE, + MultiByteToWideChar(CP_UTF8, 0, epmd, -1, wcepmd, MAXPATHLEN+100); + + if (!CreateProcessW(NULL, wcepmd, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | DETACHED_PROCESS, NULL, NULL, &start, &pi)) result = -1; @@ -1387,53 +1396,49 @@ static void get_start_erl_data(char *file) } -static char *replace_filename(char *path, char *new_base) +static wchar_t *replace_filename(wchar_t *path, wchar_t *new_base) { - int plen = strlen(path); - char *res = emalloc((plen+strlen(new_base)+1)*sizeof(char)); - char *p; + int plen = wcslen(path); + wchar_t *res = (wchar_t *) emalloc((plen+wcslen(new_base)+1)*sizeof(wchar_t)); + wchar_t *p; - strcpy(res,path); - for (p = res+plen-1 ;p >= res && *p != '\\'; --p) + wcscpy(res,path); + for (p = res+plen-1 ;p >= res && *p != L'\\'; --p) ; - *(p+1) ='\0'; - strcat(res,new_base); + *(p+1) =L'\0'; + wcscat(res,new_base); return res; } -static char *path_massage(char *long_path) +static char *path_massage(wchar_t *long_path) { char *p; - - p = emalloc(MAX_PATH+1); - strcpy(p, long_path); - GetShortPathName(p, p, MAX_PATH); + int len; + len = WideCharToMultiByte(CP_UTF8, 0, long_path, -1, NULL, 0, NULL, NULL); + p = emalloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, long_path, -1, p, len, NULL, NULL); return p; } static char *do_lookup_in_section(InitSection *inis, char *name, - char *section, char *filename, int is_path) + char *section, wchar_t *filename, int is_path) { char *p = lookup_init_entry(inis, name); if (p == NULL) { - error("Could not find key %s in section %s of file %s", + error("Could not find key %s in section %s of file %S", name,section,filename); } - if (is_path) { - return path_massage(p); - } else { - return strsave(p); - } + return strsave(p); } - +// Setup bindir, rootdir and progname as utf8 buffers static void get_parameters(int argc, char** argv) { - char *p; - char buffer[MAX_PATH]; - char *ini_filename; + wchar_t *p; + wchar_t buffer[MAX_PATH]; + wchar_t *ini_filename; HANDLE module = GetModuleHandle(NULL); /* This might look strange, but we want the erl.ini that resides in the same dir as erl.exe, not an erl.ini in our directory */ @@ -1444,34 +1449,35 @@ static void get_parameters(int argc, char** argv) error("Cannot GetModuleHandle()"); } - if (GetModuleFileName(module,buffer,MAX_PATH) == 0) { + if (GetModuleFileNameW(module,buffer,MAX_PATH) == 0) { error("Could not GetModuleFileName"); } ini_filename = replace_filename(buffer,INI_FILENAME); if ((inif = load_init_file(ini_filename)) == NULL) { + wchar_t wbindir[MAX_PATH]; + wchar_t wrootdir[MAX_PATH]; + /* Assume that the path is absolute and that it does not contain any symbolic link */ - - char buffer[MAX_PATH]; - + /* Determine bindir */ - if (GetEnvironmentVariable("ERLEXEC_DIR", buffer, MAX_PATH) == 0) { - strcpy(buffer, ini_filename); - for (p = buffer+strlen(buffer)-1; p >= buffer && *p != '\\'; --p) + if (GetEnvironmentVariableW(L"ERLEXEC_DIR", buffer, MAX_PATH) == 0) { + wcscpy(buffer, ini_filename); + for (p = buffer+wcslen(buffer)-1; p >= buffer && *p != L'\\'; --p) ; - *p ='\0'; + *p = L'\0'; } bindir = path_massage(buffer); /* Determine rootdir */ - for (p = buffer+strlen(buffer)-1; p >= buffer && *p != '\\'; --p) + for (p = buffer+wcslen(buffer)-1; p >= buffer && *p != L'\\'; --p) ; p--; - for (;p >= buffer && *p != '\\'; --p) + for (;p >= buffer && *p != L'\\'; --p) ; - *p ='\0'; + *p =L'\0'; rootdir = path_massage(buffer); /* Hardcoded progname */ diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c index 118bc6ef90..c92fedee4b 100644 --- a/erts/etc/common/escript.c +++ b/erts/etc/common/escript.c @@ -45,7 +45,8 @@ static int eargc; /* Number of arguments in eargv. */ # define QUOTE(s) possibly_quote(s) # define IS_DIRSEP(c) ((c) == '/' || (c) == '\\') # define DIRSEPSTR "\\" -# define PATHSEPSTR ";" +# define LDIRSEPSTR L"\\" +# define LPATHSEPSTR L";" # define PMAX MAX_PATH # define ERL_NAME "erl.exe" #else @@ -112,20 +113,31 @@ get_env(char *key) { #ifdef __WIN32__ DWORD size = 32; - char *value = NULL; + char *value=NULL; + wchar_t *wcvalue = NULL; + wchar_t wckey[256]; + int len; + + MultiByteToWideChar(CP_UTF8, 0, key, -1, wckey, 256); + while (1) { DWORD nsz; - if (value) - efree(value); - value = emalloc(size); + if (wcvalue) + efree(wcvalue); + wcvalue = (wchar_t *) emalloc(size*sizeof(wchar_t)); SetLastError(0); - nsz = GetEnvironmentVariable((LPCTSTR) key, (LPTSTR) value, size); + nsz = GetEnvironmentVariableW(wckey, wcvalue, size); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { - efree(value); + efree(wcvalue); return NULL; } - if (nsz <= size) + if (nsz <= size) { + len = WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, NULL, 0, NULL, NULL); + value = emalloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, value, len, NULL, NULL); + efree(wcvalue); return value; + } size = nsz; } #else @@ -145,6 +157,88 @@ free_env_val(char *value) * Find absolute path to this program */ +#ifdef __WIN32__ +static char * +find_prog(char *origpath) +{ + wchar_t relpath[PMAX]; + wchar_t abspath[PMAX]; + + if (strlen(origpath) >= PMAX) + error("Path too long"); + + MultiByteToWideChar(CP_UTF8, 0, origpath, -1, relpath, PMAX); + + if (wcsstr(relpath, LDIRSEPSTR) == NULL) { + /* Just a base name */ + int sz; + wchar_t *envpath; + sz = GetEnvironmentVariableW(L"PATH", NULL, 0); + if (sz) { + /* Try to find the executable in the path */ + wchar_t dir[PMAX]; + wchar_t *beg; + wchar_t *end; + + HANDLE dir_handle; /* Handle to directory. */ + wchar_t wildcard[PMAX]; /* Wildcard to search for. */ + WIN32_FIND_DATAW find_data; /* Data found by FindFirstFile() or FindNext(). */ + + BOOL look_for_sep = TRUE; + + envpath = (wchar_t *) emalloc(sz * sizeof(wchar_t*)); + GetEnvironmentVariableW(L"PATH", envpath, sz); + beg = envpath; + + while (look_for_sep) { + end = wcsstr(beg, LPATHSEPSTR); + if (end != NULL) { + sz = end - beg; + } else { + sz = wcslen(beg); + look_for_sep = FALSE; + } + if (sz >= PMAX) { + beg = end + 1; + continue; + } + wcsncpy(dir, beg, sz); + dir[sz] = L'\0'; + beg = end + 1; + + swprintf(wildcard, PMAX, L"%s" LDIRSEPSTR L"%s", + dir, relpath /* basename */); + dir_handle = FindFirstFileW(wildcard, &find_data); + if (dir_handle == INVALID_HANDLE_VALUE) { + /* Try next directory in path */ + continue; + } else { + /* Wow we found the executable. */ + wcscpy(relpath, wildcard); + FindClose(dir_handle); + look_for_sep = FALSE; + break; + } + } + efree(envpath); + } + } + + { + DWORD size; + wchar_t *absrest; + size = GetFullPathNameW(relpath, PMAX, abspath, &absrest); + if ((size == 0) || (size > PMAX)) { + /* Cannot determine absolute path to escript. Try the origin. */ + return strsave(origpath); + } else { + char utf8abs[PMAX]; + WideCharToMultiByte(CP_UTF8, 0, abspath, -1, utf8abs, PMAX, NULL, NULL); + return strsave(utf8abs); + } + } +} +#else static char * find_prog(char *origpath) { @@ -168,14 +262,8 @@ find_prog(char *origpath) char *end; int sz; -#ifdef __WIN32__ - HANDLE dir_handle; /* Handle to directory. */ - char wildcard[PMAX]; /* Wildcard to search for. */ - WIN32_FIND_DATA find_data; /* Data found by FindFirstFile() or FindNext(). */ -#else DIR *dp; /* Pointer to directory structure. */ struct dirent* dirp; /* Pointer to directory entry. */ -#endif /* __WIN32__ */ BOOL look_for_sep = TRUE; @@ -195,21 +283,6 @@ find_prog(char *origpath) dir[sz] = '\0'; beg = end + 1; -#ifdef __WIN32__ - erts_snprintf(wildcard, sizeof(wildcard), "%s" DIRSEPSTR "%s", - dir, relpath /* basename */); - dir_handle = FindFirstFile(wildcard, &find_data); - if (dir_handle == INVALID_HANDLE_VALUE) { - /* Try next directory in path */ - continue; - } else { - /* Wow we found the executable. */ - strcpy(relpath, wildcard); - FindClose(dir_handle); - look_for_sep = FALSE; - break; - } -#else dp = opendir(dir); if (dp != NULL) { while (TRUE) { @@ -230,21 +303,12 @@ find_prog(char *origpath) } } } -#endif /* __WIN32__ */ } } } { -#ifdef __WIN32__ - DWORD size; - char *absrest; - size = GetFullPathName(relpath, PMAX, abspath, &absrest); - if ((size == 0) || (size > PMAX)) { - -#else if (!realpath(relpath, abspath)) { -#endif /* __WIN32__ */ /* Cannot determine absolute path to escript. Try the origin. */ return strsave(origpath); } else { @@ -252,12 +316,21 @@ find_prog(char *origpath) } } } +#endif static void append_shebang_args(char* scriptname) { /* Open script file */ - FILE* fd = fopen (scriptname,"r"); + FILE* fd; +#ifdef __WIN32__ + wchar_t wcscriptname[PMAX]; + + MultiByteToWideChar(CP_UTF8, 0, scriptname, -1, wcscriptname, PMAX); + fd = _wfopen(wcscriptname, L"r"); +#else + fd = fopen (scriptname,"r"); +#endif if (fd != NULL) { /* Read first line in script file */ @@ -321,9 +394,15 @@ append_shebang_args(char* scriptname) } } +#ifdef __WIN32__ +int wmain(int argc, wchar_t **wcargv) +{ + char** argv; +#else int main(int argc, char** argv) { +#endif int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; @@ -333,6 +412,19 @@ main(int argc, char** argv) char scriptname[PMAX]; char** last_opt; char** first_opt; + +#ifdef __WIN32__ + int i; + int len; + /* Convert argv to utf8 */ + argv = malloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = malloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL); + } + argv[argc] = NULL; +#endif emulator = env = get_env("ESCRIPT_EMULATOR"); if (emulator == NULL) { @@ -412,9 +504,8 @@ main(int argc, char** argv) #endif erts_snprintf(scriptname, sizeof(scriptname), "%s.escript", - absname); + absname); efree(absname); - } /* @@ -483,63 +574,65 @@ push_words(char* src) PUSH(strsave(sbuf)); } #ifdef __WIN32__ -char *make_commandline(char **argv) +wchar_t *make_commandline(char **argv) { - static char *buff = NULL; + static wchar_t *buff = NULL; static int siz = 0; - int num = 0; - char **arg, *p; + int num = 0, len; + char **arg; + wchar_t *p; if (*argv == NULL) { - return ""; + return L""; } for (arg = argv; *arg != NULL; ++arg) { num += strlen(*arg)+1; } if (!siz) { siz = num; - buff = emalloc(siz*sizeof(char)); + buff = (wchar_t *) emalloc(siz*sizeof(wchar_t)); } else if (siz < num) { siz = num; - buff = realloc(buff,siz*sizeof(char)); + buff = (wchar_t *) realloc(buff,siz*sizeof(wchar_t)); } p = buff; + num=0; for (arg = argv; *arg != NULL; ++arg) { - strcpy(p,*arg); - p+=strlen(*arg); - *p++=' '; + len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, p, siz); + p+=(len-1); + *p++=L' '; } - *(--p) = '\0'; + *(--p) = L'\0'; if (debug) { - printf("Processed command line:%s\n",buff); + printf("Processed command line:%S\n",buff); } return buff; } int my_spawnvp(char **argv) { - STARTUPINFO siStartInfo; + STARTUPINFOW siStartInfo; PROCESS_INFORMATION piProcInfo; DWORD ec; - memset(&siStartInfo,0,sizeof(STARTUPINFO)); - siStartInfo.cb = sizeof(STARTUPINFO); + memset(&siStartInfo,0,sizeof(STARTUPINFOW)); + siStartInfo.cb = sizeof(STARTUPINFOW); siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); - if (!CreateProcess(NULL, - make_commandline(argv), - NULL, - NULL, - TRUE, - 0, - NULL, - NULL, - &siStartInfo, - &piProcInfo)) { + if (!CreateProcessW(NULL, + make_commandline(argv), + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &siStartInfo, + &piProcInfo)) { return -1; } CloseHandle(piProcInfo.hThread); @@ -623,6 +716,18 @@ strsave(char* string) return p; } +static int +file_exists(char *progname) +{ +#ifdef __WIN32__ + wchar_t wcsbuf[MAXPATHLEN]; + MultiByteToWideChar(CP_UTF8, 0, progname, -1, wcsbuf, MAXPATHLEN); + return (_waccess(wcsbuf, 0) != -1); +#else + return (access(progname, 1) != -1); +#endif +} + static char* get_default_emulator(char* progname) { @@ -636,15 +741,11 @@ get_default_emulator(char* progname) for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { strcpy(s+1, ERL_NAME); -#ifdef __WIN32__ - if (_access(sbuf, 0) != -1) { + if(file_exists(sbuf)) return strsave(sbuf); - } -#else - if (access(sbuf, 1) != -1) { + strcpy(s+1, "bin" DIRSEPSTR ERL_NAME); + if(file_exists(sbuf)) return strsave(sbuf); - } -#endif break; } } diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c index 81d797dc7e..2830641802 100644 --- a/erts/etc/common/heart.c +++ b/erts/etc/common/heart.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2012. All Rights Reserved. + * Copyright Ericsson AB 1996-2013. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -201,7 +201,6 @@ static BOOL do_shutdown(int); static void print_last_error(void); static HANDLE start_reader_thread(void); static DWORD WINAPI reader(LPVOID); -static int test_win95(void); #define read _read #define write _write #endif @@ -239,24 +238,39 @@ get_env(char *key) { #ifdef __WIN32__ DWORD size = 32; - char *value = NULL; + char *value=NULL; + wchar_t *wcvalue = NULL; + wchar_t wckey[256]; + int len; + + MultiByteToWideChar(CP_UTF8, 0, key, -1, wckey, 256); + while (1) { DWORD nsz; - if (value) - free(value); - value = malloc(size); - if (!value) { + if (wcvalue) + free(wcvalue); + wcvalue = malloc(size*sizeof(wchar_t)); + if (!wcvalue) { print_error("Failed to allocate memory. Terminating..."); exit(1); } SetLastError(0); - nsz = GetEnvironmentVariable((LPCTSTR) key, (LPTSTR) value, size); + nsz = GetEnvironmentVariableW(wckey, wcvalue, size); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { - free(value); + free(wcvalue); return NULL; } - if (nsz <= size) + if (nsz <= size) { + len = WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, NULL, 0, NULL, NULL); + value = malloc(len*sizeof(char)); + if (!value) { + print_error("Failed to allocate memory. Terminating..."); + exit(1); + } + WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, value, len, NULL, NULL); + free(wcvalue); return value; + } size = nsz; } #else @@ -564,13 +578,22 @@ void win_system(char *command) char *comspec; char * cmdbuff; char * extra = " /C "; + wchar_t *wccmdbuff; char *env; - STARTUPINFO start; + STARTUPINFOW start; SECURITY_ATTRIBUTES attr; PROCESS_INFORMATION info; + int len; - if (!debug_on || test_win95()) { - system(command); + if (!debug_on) { + len = MultiByteToWideChar(CP_UTF8, 0, command, -1, NULL, 0); + wccmdbuff = malloc(len*sizeof(wchar_t)); + if (!wccmdbuff) { + print_error("Failed to allocate memory. Terminating..."); + exit(1); + } + MultiByteToWideChar(CP_UTF8, 0, command, -1, wccmdbuff, len); + _wsystem(wccmdbuff); return; } comspec = env = get_env("COMSPEC"); @@ -602,20 +625,29 @@ void win_system(char *command) fflush(stderr); - if (!CreateProcess(NULL, - cmdbuff, - &attr, - NULL, - TRUE, - 0, - NULL, - NULL, - &start, - &info)) { + len = MultiByteToWideChar(CP_UTF8, 0, cmdbuff, -1, NULL, 0); + wccmdbuff = malloc(len*sizeof(wchar_t)); + if (!wccmdbuff) { + print_error("Failed to allocate memory. Terminating..."); + exit(1); + } + MultiByteToWideChar(CP_UTF8, 0, cmdbuff, -1, wccmdbuff, len); + + if (!CreateProcessW(NULL, + wccmdbuff, + &attr, + NULL, + TRUE, + 0, + NULL, + NULL, + &start, + &info)) { debugf("Could not create process for the command %s.\r\n", cmdbuff); } WaitForSingleObject(info.hProcess,INFINITE); free(cmdbuff); + free(wccmdbuff); } #endif /* defined(__WIN32__) */ @@ -966,16 +998,6 @@ void print_last_error() { LocalFree( lpMsgBuf ); } -static int test_win95(void) -{ - OSVERSIONINFO osinfo; - osinfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); - GetVersionEx(&osinfo); - if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) - return 1; - else - return 0; -} static BOOL enable_privilege() { HANDLE ProcessHandle; @@ -993,27 +1015,18 @@ static BOOL enable_privilege() { } static BOOL do_shutdown(int really_shutdown) { - if (test_win95()) { - if (ExitWindowsEx(EWX_REBOOT,0)) { - return TRUE; - } else { - print_last_error(); - return FALSE; - } - } else { - enable_privilege(); - if (really_shutdown) { - if (InitiateSystemShutdown(NULL,"shutdown by HEART",10,TRUE,TRUE)) - return TRUE; - } else if (InitiateSystemShutdown(NULL, - "shutdown by HEART\n" - "will be interrupted", - 30,TRUE,TRUE)) { - AbortSystemShutdown(NULL); + enable_privilege(); + if (really_shutdown) { + if (InitiateSystemShutdown(NULL,"shutdown by HEART",10,TRUE,TRUE)) return TRUE; - } - return FALSE; + } else if (InitiateSystemShutdown(NULL, + "shutdown by HEART\n" + "will be interrupted", + 30,TRUE,TRUE)) { + AbortSystemShutdown(NULL); + return TRUE; } + return FALSE; } DWORD WINAPI reader(LPVOID lpvParam) { diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c index c95959d52d..b45867f845 100644 --- a/erts/etc/common/typer.c +++ b/erts/etc/common/typer.c @@ -99,14 +99,33 @@ char *strerror(int errnum) } #endif /* !HAVE_STRERROR */ +#ifdef __WIN32__ +int wmain(int argc, wchar_t **wcargv) +{ + char** argv; +#else int main(int argc, char** argv) { +#endif int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; int need_shell = 0; +#ifdef __WIN32__ + int i; + int len; + /* Convert argv to utf8 */ + argv = malloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = malloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL); + } + argv[argc] = NULL; +#endif + emulator = get_default_emulator(argv[0]); /* @@ -193,66 +212,65 @@ push_words(char* src) PUSH(strsave(sbuf)); } #ifdef __WIN32__ -char *make_commandline(char **argv) +wchar_t *make_commandline(char **argv) { - static char *buff = NULL; + static wchar_t *buff = NULL; static int siz = 0; - int num = 0; - char **arg, *p; + int num = 0, len; + char **arg; + wchar_t *p; if (*argv == NULL) { - return ""; + return L""; } for (arg = argv; *arg != NULL; ++arg) { num += strlen(*arg)+1; } if (!siz) { siz = num; - buff = malloc(siz*sizeof(char)); + buff = (wchar_t *) emalloc(siz*sizeof(wchar_t)); } else if (siz < num) { siz = num; - buff = realloc(buff,siz*sizeof(char)); + buff = (wchar_t *) realloc(buff,siz*sizeof(wchar_t)); } p = buff; + num=0; for (arg = argv; *arg != NULL; ++arg) { - strcpy(p,*arg); - p+=strlen(*arg); - *p++=' '; + len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, p, siz); + p+=(len-1); + *p++=L' '; } - *(--p) = '\0'; + *(--p) = L'\0'; if (debug) { - printf("Processed commandline:%s\n",buff); + printf("Processed command line:%S\n",buff); } return buff; } int my_spawnvp(char **argv) { - STARTUPINFO siStartInfo; + STARTUPINFOW siStartInfo; PROCESS_INFORMATION piProcInfo; DWORD ec; - memset(&siStartInfo,0,sizeof(STARTUPINFO)); - siStartInfo.cb = sizeof(STARTUPINFO); + memset(&siStartInfo,0,sizeof(STARTUPINFOW)); + siStartInfo.cb = sizeof(STARTUPINFOW); siStartInfo.dwFlags = STARTF_USESTDHANDLES; siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); - siStartInfo.wShowWindow = SW_HIDE; - siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - - - if (!CreateProcess(NULL, - make_commandline(argv), - NULL, - NULL, - TRUE, - 0, - NULL, - NULL, - &siStartInfo, - &piProcInfo)) { + + if (!CreateProcessW(NULL, + make_commandline(argv), + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &siStartInfo, + &piProcInfo)) { return -1; } CloseHandle(piProcInfo.hThread); @@ -330,6 +348,18 @@ strsave(char* string) return p; } +static int +file_exists(char *progname) +{ +#ifdef __WIN32__ + wchar_t wcsbuf[MAXPATHLEN]; + MultiByteToWideChar(CP_UTF8, 0, progname, -1, wcsbuf, MAXPATHLEN); + return (_waccess(wcsbuf, 0) != -1); +#else + return (access(progname, 1) != -1); +#endif +} + static char* get_default_emulator(char* progname) { @@ -343,15 +373,8 @@ get_default_emulator(char* progname) for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { strcpy(s+1, ERL_NAME); -#ifdef __WIN32__ - if (_access(sbuf, 0) != -1) { - return strsave(sbuf); - } -#else - if (access(sbuf, 1) != -1) { + if(file_exists(sbuf)) return strsave(sbuf); - } -#endif break; } } diff --git a/erts/etc/unix/Install.src b/erts/etc/unix/Install.src index 0f33258a28..8eb1db75bd 100644 --- a/erts/etc/unix/Install.src +++ b/erts/etc/unix/Install.src @@ -137,9 +137,9 @@ case $start_option in esac cp -p ../releases/%I_SYSTEM_VSN%/start_*.boot . +cp -p ../releases/%I_SYSTEM_VSN%/no_dot_erlang.boot . cp -p $Name.boot start.boot cp -p ../releases/%I_SYSTEM_VSN%/$Name.script start.script - # # Fixing the man pages # diff --git a/erts/etc/unix/Makefile b/erts/etc/unix/Makefile index e85d2fab0c..c137a31ec2 100644 --- a/erts/etc/unix/Makefile +++ b/erts/etc/unix/Makefile @@ -29,7 +29,7 @@ opt debug: etc etc: etp-commands etp-commands: etp-commands.in - sed 's:@ERL_TOP@:${ERL_TOP}:g' etp-commands.in > etp-commands + $(gen_verbose)sed 's:@ERL_TOP@:${ERL_TOP}:g' etp-commands.in > etp-commands .PHONY: docs docs: diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 41baa323ed..be8343e87e 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -33,6 +33,7 @@ # You have to start beam in gdb using "run". # -rgdb Run the debug compiled emulator in gdb. # You have to start beam in gdb using "run". +# -dump Dump the bt of all threads in a core. # -break F Run the debug compiled emulator in emacs and gdb and set break. # The session is started, i.e. "run" is already don for you. # -xxgdb FIXME currently disabled @@ -178,6 +179,12 @@ while [ $# -gt 0 ]; do cargs="$cargs -frmptr" TYPE=.frmptr ;; + "-dump") + shift + GDB=dump + core="$1" + shift + ;; "-gdb") shift GDB=egdb @@ -331,7 +338,7 @@ elif [ "x$GDB" = "xgdb" ]; then echo "source $ROOTDIR/erts/etc/unix/etp-commands" > $cmdfile # Fire up gdb in emacs... exec gdb $GDBBP -x $cmdfile $gdbcmd -else +elif [ "x$GDB" = "xegdb" ]; then if [ "x$EMACS" = "x" ]; then EMACS=emacs fi @@ -339,7 +346,7 @@ else case "x$core" in x) # Get emu args to use from erlexec... - beam_args=`$EXEC -emu_args_exit ${1+"$@"}` + beam_args=`$EXEC -emu_args_exit ${1+"$@"} | tr '\n' ' '` gdbcmd="(insert-string \"set args $beam_args\") \ (comint-send-input)" ;; @@ -372,4 +379,23 @@ else (comint-send-input)" # Fire up gdb in emacs... exec $EMACS --eval "(progn (gdb \"gdb $GDBARGS$EMU_NAME\") $gdbcmd)" +elif [ "x$GDB" = "xdump" ]; then + cmdfile="/tmp/.cerlgdb.$$" + case "x$core" in + x/*) + gdbcmd="$EMU_NAME ${core}" + ;; + *) + dir=`pwd` + gdbcmd="$EMU_NAME ${dir}/${core}" + ;; + esac + echo "set width 0 +set height 0 +set verbose off + +source $ROOTDIR/erts/etc/unix/etp-commands +thread apply all bt +" > $cmdfile + exec gdb --batch --command=$cmdfile $gdbcmd fi diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c index b69e31f784..2018bc007c 100644 --- a/erts/etc/unix/run_erl.c +++ b/erts/etc/unix/run_erl.c @@ -60,7 +60,7 @@ #include <dirent.h> #include <termios.h> #include <time.h> -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H # include <syslog.h> #endif #ifdef HAVE_PTY_H @@ -197,8 +197,9 @@ static char* outbuf_in; #endif -#ifdef NO_SYSLOG +#ifndef HAVE_SYSLOG_H # define OPEN_SYSLOG() ((void) 0) +# define LOG_ERR NULL #else # define OPEN_SYSLOG() openlog(simple_basename(program_name), \ LOG_PID|LOG_CONS|LOG_NOWAIT,LOG_USER) @@ -415,7 +416,7 @@ int main(int argc, char **argv) } #endif -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H /* Before fiddling with file descriptors we make sure syslog is turned off or "closed". In the single case where we might want it again, we will open it again instead. Would not want syslog to @@ -1163,7 +1164,7 @@ static void error_logf(int priority, int line, const char *format, ...) va_list args; va_start(args, format); -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H if (run_daemon) { vsyslog(priority,format,args); } diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c index dd02a9c111..500fd166f8 100644 --- a/erts/etc/win32/Install.c +++ b/erts/etc/win32/Install.c @@ -21,58 +21,61 @@ * Dead simple installation program to set up init files etc after erlang is * copied to its destination. Also to be used after a patch is applied. */ + #include <windows.h> #include <stdio.h> #include <stdlib.h> #include "init_file.h" -int main(int argc, char **argv) +int wmain(int argc, wchar_t **argv) { int silent = 0; int start_sasl = 0; - char *root = NULL; + wchar_t *root = NULL; int i; - char buffer[MAX_PATH]; - char erts_dir[MAX_PATH]; - char release_dir[MAX_PATH]; - char bin_dir[MAX_PATH]; + wchar_t buffer[MAX_PATH]; + wchar_t erts_dir[MAX_PATH]; + wchar_t release_dir[MAX_PATH]; + wchar_t bin_dir[MAX_PATH]; char *tmp; - char my_ini_filename[MAX_PATH]; + char tmp_utf8[MAX_PATH*4]; + wchar_t my_ini_filename[MAX_PATH]; InitFile *my_ini_file; InitSection *my_ini_section; - char version_string[MAX_PATH]; + char erts_version[MAX_PATH]; InitFile *ini_file; InitSection *ini_section; HANDLE module = GetModuleHandle(NULL); - char *binaries[] = { "erl.exe", "werl.exe", "erlc.exe", - "dialyzer.exe", "typer.exe", - "escript.exe", "ct_run.exe", NULL }; - char *scripts[] = { "start_clean.boot", "start_sasl.boot", NULL }; - char fromname[MAX_PATH]; - char toname[MAX_PATH]; - + wchar_t *binaries[] = { L"erl.exe", L"werl.exe", L"erlc.exe", + L"dialyzer.exe", L"typer.exe", + L"escript.exe", L"ct_run.exe", NULL }; + wchar_t *scripts[] = { L"start_clean.boot", L"start_sasl.boot", L"no_dot_erlang.boot", NULL }; + wchar_t fromname[MAX_PATH]; + wchar_t toname[MAX_PATH]; + size_t converted; for (i = 1; i < argc; ++i) { switch(argv[i][0]) { - case '-' : + case L'-' : switch(argv[i][1]) { - case 's' : + case L's' : silent = 1; break; default: - fprintf(stderr, "Unknown command switch %s\n", + fprintf(stderr, "Unknown command switch %S\n", argv[i]); exit(1); } break; - default: + default: { if (root != NULL) { fprintf(stderr, "Only one root directory can be specified, " - "parameter %s is illegal\n", + "parameter %S is illegal\n", argv[i]); exit(1); - } + } root = argv[i]; + } break; } } @@ -82,19 +85,19 @@ int main(int argc, char **argv) exit(1); } - if (GetModuleFileName(module,buffer,MAX_PATH) == 0) { + if (GetModuleFileNameW(module,buffer,MAX_PATH) == 0) { fprintf(stderr,"Could not GetModuleFileName()\n"); exit(1); } - i = strlen(buffer) - 1; - while ( i >= 0 && buffer[i] != '\\') { + i = wcslen(buffer) - 1; + while ( i >= 0 && buffer[i] != L'\\') { --i; } if (i < 0) { fprintf(stderr,"GetModuleFileName returned broken path\n"); exit(1); } - buffer[i] = '\0'; + buffer[i] = L'\0'; root = buffer; } @@ -122,79 +125,78 @@ int main(int argc, char **argv) start_sasl = 0; } } - sprintf(my_ini_filename,"%s\\Install.ini",root); + swprintf(my_ini_filename, MAX_PATH, L"%s\\Install.ini", root); my_ini_file = load_init_file(my_ini_filename); if (my_ini_file == NULL) { - fprintf(stderr,"Cannot open init file %s\n",my_ini_filename); + fprintf(stderr,"Cannot open init file %S\n",my_ini_filename); exit(1); } if ((my_ini_section = lookup_init_section(my_ini_file,"Install")) == NULL) { - fprintf(stderr,"No [Install] section in init file %s\n", + fprintf(stderr,"No [Install] section in init file %S\n", my_ini_filename); exit(1); } if ((tmp = lookup_init_entry(my_ini_section, "VSN")) == NULL) { - fprintf(stderr,"No key VSN in init file %s\n", + fprintf(stderr,"No key VSN in init file %S\n", my_ini_filename); exit(1); } - - strcpy(version_string,tmp); + strcpy(erts_version,tmp); - sprintf(erts_dir,"%s\\erts-%s\\bin",root,tmp); + swprintf(erts_dir,MAX_PATH,L"%s\\erts-%S\\bin",root,erts_version); if ((tmp = lookup_init_entry(my_ini_section, "SYSTEM_VSN")) == NULL) { - fprintf(stderr,"No key SYSTEM_VSN in init file %s\n", - my_ini_filename); + fprintf(stderr,"No key SYSTEM_VSN in init file %S\n", + my_ini_filename); exit(1); } - sprintf(release_dir,"%s\\releases\\%s",root,tmp); + swprintf(release_dir,MAX_PATH,L"%s\\releases\\%S",root,tmp); - sprintf(bin_dir,"%s\\bin",root); - CreateDirectory(bin_dir,NULL); + swprintf(bin_dir,MAX_PATH,L"%s\\bin",root); + CreateDirectoryW(bin_dir,NULL); free_init_file(my_ini_file); for (i = 0; binaries[i] != NULL; ++i) { - sprintf(fromname,"%s\\%s",erts_dir,binaries[i]); - sprintf(toname,"%s\\%s",bin_dir,binaries[i]); - if (GetFileAttributes(fromname) == 0xFFFFFFFF) { - fprintf(stderr,"Could not find file %s\n", + swprintf(fromname,MAX_PATH,L"%s\\%s",erts_dir,binaries[i]); + swprintf(toname,MAX_PATH,L"%s\\%s",bin_dir,binaries[i]); + if (GetFileAttributesW(fromname) == 0xFFFFFFFF) { + fprintf(stderr,"Could not find file %S\n", fromname); exit(1); } - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", fromname,toname); fprintf(stderr,"Continuing installation anyway...\n"); } } for (i = 0; scripts[i] != NULL; ++i) { - sprintf(fromname,"%s\\%s",release_dir,scripts[i]); - sprintf(toname,"%s\\%s",bin_dir,scripts[i]); - if (GetFileAttributes(fromname) == 0xFFFFFFFF) { - fprintf(stderr,"Could not find file %s\n", + swprintf(fromname,MAX_PATH,L"%s\\%s",release_dir,scripts[i]); + swprintf(toname,MAX_PATH,L"%s\\%s",bin_dir,scripts[i]); + if (GetFileAttributesW(fromname) == 0xFFFFFFFF) { + fprintf(stderr,"Could not find file %S\n", fromname); exit(1); } - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", fromname,toname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); } } if (start_sasl) { - sprintf(fromname,"%s\\start_sasl.boot",bin_dir); + swprintf(fromname,MAX_PATH,L"%s\\start_sasl.boot",bin_dir); } else { - sprintf(fromname,"%s\\start_clean.boot",bin_dir); + swprintf(fromname,MAX_PATH,L"%s\\start_clean.boot",bin_dir); } - sprintf(toname,"%s\\start.boot",bin_dir); - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", + swprintf(toname,MAX_PATH,L"%s\\start.boot",bin_dir); + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", fromname,toname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); @@ -205,25 +207,27 @@ int main(int argc, char **argv) ini_file = create_init_file(); ini_section = create_init_section("erlang"); add_init_section(ini_file,ini_section); - add_init_entry(ini_section,"Bindir",erts_dir); + WideCharToMultiByte(CP_UTF8,0,erts_dir,-1,tmp_utf8,MAX_PATH*4,NULL,NULL); + add_init_entry(ini_section,"Bindir",tmp_utf8); add_init_entry(ini_section,"Progname","erl"); - add_init_entry(ini_section,"Rootdir",root); - sprintf(fromname,"%s\\erl.ini",erts_dir); - sprintf(toname,"%s\\erl.ini",bin_dir); + WideCharToMultiByte(CP_UTF8,0,root,-1,tmp_utf8,MAX_PATH*4,NULL,NULL); + add_init_entry(ini_section,"Rootdir",tmp_utf8); + swprintf(fromname,MAX_PATH,L"%s\\erl.ini",erts_dir); + swprintf(toname,MAX_PATH,L"%s\\erl.ini",bin_dir); if (store_init_file(ini_file,fromname) != 0) { - fprintf(stderr,"Could not create file %s\n", + fprintf(stderr,"Could not create file %S\n", fromname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); } - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", - fromname,toname); + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", + fromname,toname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); } if (!silent) { - printf("Erlang %s installed successfully\n", version_string); + printf("Erlang %s installed successfully\n", erts_version); } return 0; } diff --git a/erts/etc/win32/erl.c b/erts/etc/win32/erl.c index d341153966..1d116bf36e 100644 --- a/erts/etc/win32/erl.c +++ b/erts/etc/win32/erl.c @@ -27,96 +27,126 @@ typedef int ErlexecFunction(int, char **, HANDLE, int); -#define INI_FILENAME "erl.ini" +#define INI_FILENAME L"erl.ini" #define INI_SECTION "erlang" -#define ERLEXEC_BASENAME "erlexec.dll" +#define ERLEXEC_BASENAME L"erlexec.dll" static void get_parameters(void); static void error(char* format, ...); -static char *erlexec_name; -static char *erlexec_dir; +static wchar_t *erlexec_name; +static wchar_t *erlexec_dir; #ifdef WIN32_WERL #define WERL 1 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - PSTR szCmdLine, int iCmdShow) +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + PWSTR szCmdLine, int iCmdShow) { int argc = __argc; - char **argv = __argv; + wchar_t **argv = __wargv; #else #define WERL 0 -int main(int argc, char **argv) +int wmain(int argc, wchar_t **argv) { #endif HANDLE erlexec_handle; /* Instance */ ErlexecFunction *win_erlexec; - char *path = malloc(100); - char *npath; + wchar_t *path = malloc(100*sizeof(wchar_t)); + wchar_t *npath; int pathlen; + char ** utf8argv; + int i, len; get_parameters(); - if ((pathlen = GetEnvironmentVariable("PATH",path,100)) == 0) { + if ((pathlen = GetEnvironmentVariableW(L"PATH",path,100)) == 0) { error("No PATH variable (!)"); } else if (pathlen > 100) { - path = realloc(path,pathlen); - GetEnvironmentVariable("PATH",path,pathlen); + path = realloc(path,pathlen*sizeof(wchar_t)); + GetEnvironmentVariableW(L"PATH",path,pathlen); } - npath = malloc(strlen(path) + strlen(erlexec_dir) + 2); - sprintf(npath,"%s;%s",erlexec_dir,path); - SetEnvironmentVariable("PATH",npath); + pathlen = (wcslen(path) + wcslen(erlexec_dir) + 2); + npath = (wchar_t *) malloc(pathlen*sizeof(wchar_t)); + swprintf(npath,pathlen,L"%s;%s",erlexec_dir,path); + SetEnvironmentVariableW(L"PATH",npath); - if ((erlexec_handle = LoadLibrary(erlexec_name)) == NULL) { - error("Could not load module %s.",erlexec_name); + if ((erlexec_handle = LoadLibraryW(erlexec_name)) == NULL) { + error("Could not load module %S.",erlexec_name); } if ((win_erlexec = (ErlexecFunction *) GetProcAddress(erlexec_handle,"win_erlexec")) == NULL) { - error("Could not find entry point \"win_erlexec\" in %s.", erlexec_name); + error("Could not find entry point \"win_erlexec\" in %S.", erlexec_name); } - return (*win_erlexec)(argc,argv,erlexec_handle,WERL); + /* Convert argv to utf8 */ + utf8argv = malloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL); + utf8argv[i] = malloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, utf8argv[i], len, NULL, NULL); + } + utf8argv[argc] = NULL; + +#ifdef HARDDEBUG + { + wchar_t tempbuf[2048] = L""; + wchar_t *sbuf; + int i; + sbuf=tempbuf; + sbuf += swprintf(sbuf, 2048, L"utf16: %d\n", argc); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%s|", argv[i]); + }; + sbuf += swprintf(sbuf, 2048, L"\nutf8: \n"); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%S|", utf8argv[i]); + }; + MessageBoxW(NULL, tempbuf, L"erl_exec args", MB_OK|MB_ICONERROR); + } +#endif + + return (*win_erlexec)(argc,utf8argv,erlexec_handle,WERL); } -static char *replace_filename(char *path, char *new_base) +static wchar_t *replace_filename(wchar_t *path, wchar_t *new_base) { - int plen = strlen(path); - char *res = malloc((plen+strlen(new_base)+1)*sizeof(char)); - char *p; + int plen = wcslen(path); + wchar_t *res = malloc((plen+wcslen(new_base)+1)*sizeof(wchar_t)); + wchar_t *p; - strcpy(res,path); - for (p = res+plen-1 ;p >= res && *p != '\\'; --p) + wcscpy(res,path); + for (p = res+plen-1 ;p >= res && *p != L'\\'; --p) ; - *(p+1) ='\0'; - strcat(res,new_base); + *(p+1) =L'\0'; + wcscat(res,new_base); return res; } static char *do_lookup_in_section(InitSection *inis, char *name, - char *section, char *filename) + char *section, wchar_t *filename) { char *p = lookup_init_entry(inis, name); if (p == NULL) { - error("Could not find key %s in section %s of file %s", + error("Could not find key %s in section %s of file %S", name,section,filename); } - return _strdup(p); + return p; } -static void copy_latest_vsn(char *latest_vsn, char *next_vsn) +static void copy_latest_vsn(wchar_t *latest_vsn, wchar_t *next_vsn) { /* Copy */ - char *lp; - char *np; + wchar_t *lp; + wchar_t *np; /* Find vsn */ - for (lp = next_vsn+strlen(next_vsn)-1 ;lp >= next_vsn && *lp != '\\'; --lp) + for (lp = next_vsn+wcslen(next_vsn)-1 ;lp >= next_vsn && *lp != L'\\'; --lp) ; /* lp =+ length("erts-"); */ - for (np = next_vsn+strlen(next_vsn)-1 ;np >= next_vsn && *np != '\\'; --np) + for (np = next_vsn+wcslen(next_vsn)-1 ;np >= next_vsn && *np != L'\\'; --np) ; /* np =+ length("erts-"); */ @@ -124,95 +154,95 @@ static void copy_latest_vsn(char *latest_vsn, char *next_vsn) if (*lp == *np) { continue; } - if (*np == '.' || *np == '\0' || *np <= *lp) { + if (*np == L'.' || *np == L'\0' || *np <= *lp) { /* */ return; } - if (*lp == '.' || *lp == '\0') { - strcpy(latest_vsn, next_vsn); + if (*lp == L'.' || *lp == L'\0') { + wcscpy(latest_vsn, next_vsn); return; } } return; } -static char *find_erlexec_dir2(char *install_dir) +static wchar_t *find_erlexec_dir2(wchar_t *install_dir) { /* List install dir and look for latest erts-vsn */ HANDLE dir_handle; /* Handle to directory. */ - char wildcard[MAX_PATH]; /* Wildcard to search for. */ - WIN32_FIND_DATA find_data; /* Data found by FindFirstFile() or FindNext(). */ - char latest_vsn[MAX_PATH]; + wchar_t wildcard[MAX_PATH]; /* Wildcard to search for. */ + WIN32_FIND_DATAW find_data; /* Data found by FindFirstFile() or FindNext(). */ + wchar_t latest_vsn[MAX_PATH]; /* Setup wildcard */ - int length = strlen(install_dir); - char *p; + int length = wcslen(install_dir); + wchar_t *p; if (length+3 >= MAX_PATH) { error("Cannot find erlexec.exe"); } - strcpy(wildcard, install_dir); + wcscpy(wildcard, install_dir); p = wildcard+length-1; - if (*p != '/' && *p != '\\') - *++p = '\\'; - strcpy(++p, "erts-*"); + if (*p != L'/' && *p != L'\\') + *++p = L'\\'; + wcscpy(++p, L"erts-*"); /* Find first dir */ - dir_handle = FindFirstFile(wildcard, &find_data); + dir_handle = FindFirstFileW(wildcard, &find_data); if (dir_handle == INVALID_HANDLE_VALUE) { /* No erts-vsn found*/ return NULL; } - strcpy(latest_vsn, find_data.cFileName); + wcscpy(latest_vsn, find_data.cFileName); /* Find the rest */ - while(FindNextFile(dir_handle, &find_data)) { + while(FindNextFileW(dir_handle, &find_data)) { copy_latest_vsn(latest_vsn, find_data.cFileName); } FindClose(dir_handle); - p = malloc((strlen(install_dir)+1+strlen(latest_vsn)+4+1)*sizeof(char)); + p = (wchar_t *) malloc((wcslen(install_dir)+1+wcslen(latest_vsn)+4+1)*sizeof(wchar_t)); - strcpy(p,install_dir); - strcat(p,"\\"); - strcat(p,latest_vsn); - strcat(p,"\\bin"); + wcscpy(p,install_dir); + wcscat(p,L"\\"); + wcscat(p,latest_vsn); + wcscat(p,L"\\bin"); return p; } -static char *find_erlexec_dir(char *erlpath) +static wchar_t *find_erlexec_dir(wchar_t *erlpath) { /* Assume that the path to erl is absolute and * that it is not a symbolic link*/ - char *dir =_strdup(erlpath); - char *p; - char *p2; + wchar_t *dir =_wcsdup(erlpath); + wchar_t *p; + wchar_t *p2; /* Chop of base name*/ - for (p = dir+strlen(dir)-1 ;p >= dir && *p != '\\'; --p) + for (p = dir+wcslen(dir)-1 ;p >= dir && *p != L'\\'; --p) ; - *p ='\0'; + *p =L'\0'; p--; /* Check if dir path is like ...\install_dir\erts-vsn\bin */ - for (;p >= dir && *p != '\\'; --p) + for (;p >= dir && *p != L'\\'; --p) ; p--; for (p2 = p;p2 >= dir && *p2 != '\\'; --p2) ; p2++; - if (strncmp(p2, "erts-", strlen("erts-")) == 0) { - p = _strdup(dir); + if (wcsncmp(p2, L"erts-", wcslen(L"erts-")) == 0) { + p = _wcsdup(dir); free(dir); return p; } /* Assume that dir path is like ...\install_dir\bin */ - *++p ='\0'; /* chop off bin dir */ + *++p =L'\0'; /* chop off bin dir */ p = find_erlexec_dir2(dir); free(dir); @@ -225,18 +255,20 @@ static char *find_erlexec_dir(char *erlpath) static void get_parameters(void) { - char buffer[MAX_PATH]; - char *ini_filename; + wchar_t buffer[MAX_PATH]; + wchar_t *ini_filename; HANDLE module = GetModuleHandle(NULL); InitFile *inif; InitSection *inis; - char *bindir; + char *utf8dir; + int len; + if (module = NULL) { error("Cannot GetModuleHandle()"); } - if (GetModuleFileName(module,buffer,MAX_PATH) == 0) { + if (GetModuleFileNameW(module,buffer,MAX_PATH) == 0) { error("Could not GetModuleFileName"); } @@ -244,21 +276,28 @@ static void get_parameters(void) if ((inif = load_init_file(ini_filename)) == NULL) { erlexec_dir = find_erlexec_dir(ini_filename); - SetEnvironmentVariable("ERLEXEC_DIR", erlexec_dir); + SetEnvironmentVariableW(L"ERLEXEC_DIR", erlexec_dir); } else { if ((inis = lookup_init_section(inif,INI_SECTION)) == NULL) { - error("Could not find section %s in init file %s", + error("Could not find section %s in init file %S", INI_SECTION, ini_filename); } - erlexec_dir = do_lookup_in_section(inis, "Bindir", INI_SECTION, ini_filename); - free_init_file(inif); + utf8dir = do_lookup_in_section(inis, "Bindir", INI_SECTION, ini_filename); + len = MultiByteToWideChar(CP_UTF8, 0, utf8dir, -1, NULL, 0); + erlexec_dir = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8dir, -1, erlexec_dir, len); + if(len == 0) { + error("Bindir is not a valid utf8 '%s' in init file %S", + utf8dir, ini_filename); + } + free_init_file(inif); } - erlexec_name = malloc(strlen(erlexec_dir) + strlen(ERLEXEC_BASENAME) + 2); - strcpy(erlexec_name,erlexec_dir); - strcat(erlexec_name, "\\" ERLEXEC_BASENAME); + erlexec_name = malloc((wcslen(erlexec_dir) + wcslen(ERLEXEC_BASENAME) + 2)*sizeof(wchar_t)); + wcscpy(erlexec_name,erlexec_dir); + wcscat(erlexec_name, L"\\" ERLEXEC_BASENAME); free(ini_filename); } diff --git a/erts/etc/win32/erlsrv/erlsrv_global.h b/erts/etc/win32/erlsrv/erlsrv_global.h index d3922dc1e3..f25e09ea45 100644 --- a/erts/etc/win32/erlsrv/erlsrv_global.h +++ b/erts/etc/win32/erlsrv/erlsrv_global.h @@ -19,13 +19,13 @@ #ifndef _ERLSRV_GLOBAL_H #define _ERLSRV_GLOBAL_H -#define APP_NAME "ErlSrv" +#define APP_NAME L"ErlSrv" -#define ERLANG_MACHINE "erl.exe" +#define ERLANG_MACHINE L"erl.exe" -#define SERVICE_ENV "ERLSRV_SERVICE_NAME" -#define EXECUTABLE_ENV "ERLSRV_EXECUTABLE" -#define DEBUG_ENV "ERLSRV_DEBUG" +#define SERVICE_ENV L"ERLSRV_SERVICE_NAME" +#define EXECUTABLE_ENV L"ERLSRV_EXECUTABLE" +#define DEBUG_ENV L"ERLSRV_DEBUG" #ifdef _DEBUG #define HARDDEBUG 1 diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.c b/erts/etc/win32/erlsrv/erlsrv_interactive.c index e8d73ae047..260f0d9b97 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.c +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.c @@ -27,54 +27,60 @@ #include "erlsrv_interactive.h" #include "erlsrv_util.h" /* service_name */ -#define DBG fprintf(stderr,"argv[0]:%s line %d\n",argv[0],__LINE__) +#define DBG fwprintf(stderr,L"argv[0]:%s line %d\n",argv[0],__LINE__) +/* #define HARDDEBUG 1 */ + +#include <fcntl.h> /* Really HAS to correcpond to the enum in erlsrv_registry.h */ -static char *arg_tab[] = { - "stopaction", "st", - "onfail", "on", - "machine", "m", - "env", "e", - "workdir", "w", - "priority", "p", - "sname", "sn", - "name", "n", - "args", "ar", - "debugtype", "d", - "internalservicename","i", - "comment","c", +static wchar_t *arg_tab[] = { + L"stopaction", L"st", + L"onfail", L"on", + L"machine", L"m", + L"env", L"e", + L"workdir", L"w", + L"priority", L"p", + L"sname", L"sn", + L"name", L"n", + L"args", L"ar", + L"debugtype", L"d", + L"internalservicename",L"i", + L"comment",L"c", NULL, NULL }; -static char *generate_real_service_name(char *display_name){ +static wchar_t *generate_real_service_name(wchar_t *display_name){ SYSTEMTIME systime; FILETIME ftime; - char *buff = malloc(strlen(display_name)+ - (8*2)+1); - char *tmp = _strdup(display_name); + int len=(wcslen(display_name)+(8*2)+1); + wchar_t *buff; + wchar_t *tmp = _wcsdup(display_name); int i; + buff = (wchar_t*) malloc(len*sizeof(wchar_t)); + /* 2 Hex chars for each byte in a DWORD */ GetSystemTime(&systime); SystemTimeToFileTime(&systime,&ftime); /* Remove trailing version info to avoid user confusion */ - for(i = (strlen(tmp)-1);i > 0; --i) - if(tmp[i] == '_'){ - tmp[i] = '\0'; + for(i = (wcslen(tmp)-1);i > 0; --i) + if(tmp[i] == L'_'){ + tmp[i] = L'\0'; break; } - sprintf(buff,"%s%08x%08x",tmp,ftime.dwHighDateTime, - ftime.dwLowDateTime); + swprintf(buff,len,L"%s%08x%08x",tmp, + ftime.dwHighDateTime, + ftime.dwLowDateTime); free(tmp); return buff; } -static int lookup_arg(char *arg){ +static int lookup_arg(wchar_t *arg){ int i; - if(*arg != '-' && *arg != '/') + if(*arg != L'-' && *arg != L'/') return -1; for(i=0; arg_tab[i] != NULL; i += 2){ - if(!_strnicmp(arg_tab[i],arg+1,strlen(arg+1)) && - !_strnicmp(arg_tab[i+1],arg+1,strlen(arg_tab[i+1]))) + if(!_wcsnicmp(arg_tab[i],arg+1,wcslen(arg+1)) && + !_wcsnicmp(arg_tab[i+1],arg+1,wcslen(arg_tab[i+1]))) return (i / 2); } return -1; @@ -82,29 +88,29 @@ static int lookup_arg(char *arg){ -char *edit_env(char *edit, char *oldenv){ - char **arg; - char *value; - char *name = strdup(edit); +wchar_t *edit_env(wchar_t *edit, wchar_t *oldenv){ + wchar_t **arg; + wchar_t *value; + wchar_t *name = wcsdup(edit); int i; - char *tmp; + wchar_t *tmp; arg = env_to_arg(oldenv); - value = strchr(name,'='); + value = wcschr(name,L'='); if(value){ - *(value++) = '\0'; - if(*value == '\0') + *(value++) = L'\0'; + if(*value == L'\0') value = NULL; } for(i=0;arg[i] != NULL; ++i){ - tmp = strchr(arg[i],'='); - if(((int) strlen(name)) == (tmp - arg[i]) && - !_strnicmp(name,arg[i], tmp - arg[i])) + tmp = wcschr(arg[i],L'='); + if(((int) wcslen(name)) == (tmp - arg[i]) && + !_wcsnicmp(name,arg[i], tmp - arg[i])) break; } if(arg[i] != NULL){ free(arg[i]); if(value){ - arg[i] = strdup(edit); + arg[i] = wcsdup(edit); } else { do { arg[i] = arg[i+1]; @@ -113,7 +119,7 @@ char *edit_env(char *edit, char *oldenv){ } } else if(value){ /* add to arg, which is always allocated to hold one extra environment variable*/ - arg[i] = strdup(edit); + arg[i] = wcsdup(edit); arg[i+1] = NULL; } free(name); @@ -132,8 +138,8 @@ void print_last_error(void){ (LPTSTR) &mes, 0, NULL ); - fprintf(stderr,"Error: %s",mes); - LocalFree(mes); + fwprintf(stderr,L"Error: %S",mes); + LocalFree(mes); } static int get_last_error(void) @@ -144,19 +150,19 @@ static int get_last_error(void) static BOOL install_service(void){ SC_HANDLE scm; SC_HANDLE service; - char filename[MAX_PATH + 3]; + wchar_t filename[MAX_PATH + 3]; DWORD fnsiz=MAX_PATH; - char dependant[] = { 'L','a','n','m','a','n', - 'W','o','r','k','s','t', - 'a','t','i','o','n','\0','\0'}; + wchar_t dependant[] = { L'L',L'a',L'n',L'm',L'a',L'n', + L'W',L'o',L'r',L'k',L's',L't', + L'a',L't',L'i',L'o',L'n',L'\0',L'\0'}; - if(!(fnsiz = GetModuleFileName(NULL, filename, fnsiz))) + if(!(fnsiz = GetModuleFileNameW(NULL, filename, fnsiz))) return FALSE; - if(strchr(filename,' ')){ - memmove(filename+1,filename,fnsiz); - filename[0] ='\"'; /* " */ - filename[fnsiz+1] = '\"'; /* " */ - filename[fnsiz+2] = '\0'; + if(wcschr(filename,L' ')){ + memmove(filename+1,filename,fnsiz*sizeof(wchar_t)); + filename[0] = L'\"'; /* " */ + filename[fnsiz+1] = L'\"'; /* " */ + filename[fnsiz+2] = L'\0'; } if((scm = OpenSCManager(NULL, NULL, @@ -166,20 +172,20 @@ static BOOL install_service(void){ last_error = GetLastError(); return FALSE; } - service = CreateService(scm, - real_service_name, - service_name, - SERVICE_ALL_ACCESS & - ~(SERVICE_PAUSE_CONTINUE), - SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - filename, - NULL, - NULL, - dependant, - NULL, - NULL); + service = CreateServiceW(scm, + real_service_name, + service_name, + SERVICE_ALL_ACCESS & + ~(SERVICE_PAUSE_CONTINUE), + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + filename, + NULL, + NULL, + dependant, + NULL, + NULL); if(service == NULL){ CloseServiceHandle(scm); last_error = GetLastError(); @@ -198,9 +204,9 @@ static BOOL remove_service(void){ GENERIC_WRITE)) == NULL) return FALSE; - service = OpenService(scm, - real_service_name, - SERVICE_ALL_ACCESS); + service = OpenServiceW(scm, + real_service_name, + SERVICE_ALL_ACCESS); if(service == NULL){ CloseServiceHandle(scm); return FALSE; @@ -220,9 +226,9 @@ static BOOL open_service_control(SC_HANDLE *scm, SC_HANDLE *service){ SC_MANAGER_ALL_ACCESS)) == NULL) return FALSE; - *service = OpenService(*scm, - real_service_name, - SERVICE_ALL_ACCESS); + *service = OpenServiceW(*scm, + real_service_name, + SERVICE_ALL_ACCESS); if(service == NULL){ CloseServiceHandle(*scm); return FALSE; @@ -239,10 +245,10 @@ static BOOL open_service_config(SC_HANDLE *scm, SC_HANDLE *service){ last_error = GetLastError(); return FALSE; } - *service = OpenService(*scm, - real_service_name, - /*GENERIC_WRITE*/ - SERVICE_ALL_ACCESS); + *service = OpenServiceW(*scm, + real_service_name, + /*GENERIC_WRITE*/ + SERVICE_ALL_ACCESS); if(service == NULL){ last_error = GetLastError(); CloseServiceHandle(*scm); @@ -251,16 +257,16 @@ static BOOL open_service_config(SC_HANDLE *scm, SC_HANDLE *service){ return TRUE; } -static BOOL set_service_comment(char *comment) { +static BOOL set_service_comment(wchar_t *comment) { SC_HANDLE scm; SC_HANDLE service; - SERVICE_DESCRIPTION sd; + SERVICE_DESCRIPTIONW sd; BOOL ret = TRUE; sd.lpDescription = comment; if (!open_service_config(&scm,&service)) { return FALSE; } - if (!ChangeServiceConfig2(service,SERVICE_CONFIG_DESCRIPTION,&sd)) { + if (!ChangeServiceConfig2W(service,SERVICE_CONFIG_DESCRIPTION,&sd)) { last_error = GetLastError(); ret = FALSE; } @@ -325,7 +331,7 @@ static BOOL stop_service(void){ if(!open_service_control(&scm,&service)){ #ifdef HARDDEBUG - fprintf(stderr,"Failed to open service.\n"); + fwprintf(stderr,L"Failed to open service.\n"); #endif return FALSE; } @@ -338,7 +344,7 @@ static BOOL stop_service(void){ #ifdef HARDDEBUG if(!ret) { - fprintf(stderr,"Failed to control service.\n"); + fwprintf(stderr,L"Failed to control service.\n"); print_last_error(); } #endif @@ -466,115 +472,114 @@ void cleanup_old(){ } BOOL fill_in_defaults(RegEntry *new){ - char filename[MAX_PATH]; - char *ptr; + wchar_t filename[MAX_PATH]; + wchar_t *ptr; - if(!GetModuleFileName(NULL, filename, MAX_PATH)) + if(!GetModuleFileNameW(NULL, filename, MAX_PATH)) return FALSE; - for(ptr = filename + strlen(filename) - 1; - ptr > filename && *ptr != '\\'; + for(ptr = filename + wcslen(filename) - 1; + ptr > filename && *ptr != L'\\'; --ptr) ; - if(*ptr == '\\') + if(*ptr == L'\\') ++ptr; - *ptr = '\0'; + *ptr = L'\0'; - ptr = malloc(strlen(filename)+strlen(ERLANG_MACHINE)+1); - strcpy(ptr,filename); - strcat(ptr,ERLANG_MACHINE); + ptr = (wchar_t*) malloc((wcslen(filename)+wcslen(ERLANG_MACHINE)+1)*sizeof(wchar_t)); + wcscpy(ptr,filename); + wcscat(ptr,ERLANG_MACHINE); - new[StopAction].data.bytes = ""; + new[StopAction].data.string = L""; new[OnFail].data.value = ON_FAIL_IGNORE; - new[Machine].data.bytes = ptr; - new[Machine].data.expand.unexpanded = ptr; - new[Env].data.bytes = "\0"; - new[WorkDir].data.bytes = new[WorkDir].data.expand.unexpanded = - ""; + new[Machine].data.string = ptr; + new[Machine].data.expand.unexpanded = ptr; + new[Env].data.string = L"\0"; + new[WorkDir].data.string = new[WorkDir].data.expand.unexpanded = L""; new[Priority].data.value = NORMAL_PRIORITY_CLASS; - new[SName].data.bytes = service_name; - new[Name].data.bytes = ""; - new[Args].data.bytes = new[Args].data.expand.unexpanded = ""; + new[SName].data.string = service_name; + new[Name].data.string = L""; + new[Args].data.string = new[Args].data.expand.unexpanded = L""; new[DebugType].data.value = DEBUG_TYPE_NO_DEBUG; - new[InternalServiceName].data.bytes = real_service_name; - new[Comment].data.bytes = ""; + new[InternalServiceName].data.string = real_service_name; + new[Comment].data.string = L""; return TRUE; } -int do_usage(char *arg0){ - printf("Usage:\n"); - printf("%s {set | add} <servicename>\n" - "\t[-st[opaction] [<erlang shell command>]]\n" - "\t[-on[fail] [{reboot | restart | restart_always}]]\n" - "\t[-m[achine] [<erl-command>]]\n" - "\t[-e[nv] [<variable>[=<value>]]]\n" - "\t[-w[orkdir] [<directory>]]\n" - "\t[-p[riority] [{low|high|realtime}]]\n" - "\t[{-sn[ame] | -n[ame]} [<nodename>]]\n" - "\t[-d[ebugtype] [{new|reuse|console}]]\n" - "\t[-ar[gs] [<limited erl arguments>]]\n\n" - "%s {start | start_disabled | stop | disable | enable} <servicename>\n\n" - "%s remove <servicename>\n\n" - "%s rename <servicename> <servicename>\n\n" - "%s list [<servicename>]\n\n" - "%s help\n\n", +int do_usage(wchar_t *arg0){ + wprintf(L"Usage:\n"); + wprintf(L"%s {set | add} <servicename>\n" + L"\t[-st[opaction] [<erlang shell command>]]\n" + L"\t[-on[fail] [{reboot | restart | restart_always}]]\n" + L"\t[-m[achine] [<erl-command>]]\n" + L"\t[-e[nv] [<variable>[=<value>]]]\n" + L"\t[-w[orkdir] [<directory>]]\n" + L"\t[-p[riority] [{low|high|realtime}]]\n" + L"\t[{-sn[ame] | -n[ame]} [<nodename>]]\n" + L"\t[-d[ebugtype] [{new|reuse|console}]]\n" + L"\t[-ar[gs] [<limited erl arguments>]]\n\n" + L"%s {start | start_disabled | stop | disable | enable} <servicename>\n\n" + L"%s remove <servicename>\n\n" + L"%s rename <servicename> <servicename>\n\n" + L"%s list [<servicename>]\n\n" + L"%s help\n\n", arg0,arg0,arg0,arg0,arg0,arg0); - printf("Manipulates Erlang system services on Windows NT.\n\n"); - printf("When no parameter to an option is specified, the option\n" - "is reset to it's default value. To set an empty argument\n" - "list, give option -args as last option on command line " - "with\n" - "no arguments.\n\n"); - printf("See Erlang documentation for full description.\n"); + wprintf(L"Manipulates Erlang system services on Windows NT.\n\n"); + wprintf(L"When no parameter to an option is specified, the option\n" + L"is reset to it's default value. To set an empty argument\n" + L"list, give option -args as last option on command line " + L"with\n" + L"no arguments.\n\n"); + wprintf(L"See Erlang documentation for full description.\n"); return 0; } -int do_manage(int argc,char **argv){ - char *action = argv[1]; +int do_manage(int argc, wchar_t **argv){ + wchar_t *action = argv[1]; RegEntry *current = empty_reg_tab(); if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; if(!fetch_current(current)){ - fprintf(stderr,"%s: The service %s is not an erlsrv controlled service.\n", + fwprintf(stderr,L"%s: The service %s is not an erlsrv controlled service.\n", argv[0],service_name); return 1; } - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); free_keys(current); - if(!_stricmp(action,"start")){ + if(!_wcsicmp(action,L"start")){ if(!start_service()){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_RUNNING, 60)){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s started.\n", + wprintf(L"%s: Service %s started.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"start_disabled")){ + if(!_wcsicmp(action,L"start_disabled")){ if(!enable_service()){ - fprintf(stderr,"%s: Failed to enable service %s.\n", + fwprintf(stderr,L"%s: Failed to enable service %s.\n", argv[0],service_name); print_last_error(); return 1; } if(!start_service() && get_last_error() != ERROR_SERVICE_ALREADY_RUNNING){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); goto failure_starting; @@ -582,84 +587,84 @@ int do_manage(int argc,char **argv){ if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_RUNNING, 60)){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); goto failure_starting; } if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s started.\n", + wprintf(L"%s: Service %s started.\n", argv[0],service_name); return 0; failure_starting: if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); } return 1; } - if(!_stricmp(action,"stop")){ + if(!_wcsicmp(action,L"stop")){ if(!stop_service()){ - fprintf(stderr,"%s: Failed to stop service %s.\n", + fwprintf(stderr,L"%s: Failed to stop service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { if(!wait_service_trans(SERVICE_RUNNING, SERVICE_STOP_PENDING, SERVICE_STOPPED, 60)){ - fprintf(stderr,"%s: Failed to stop service %s.\n", + fwprintf(stderr,L"%s: Failed to stop service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s stopped.\n", + wprintf(L"%s: Service %s stopped.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"disable")){ + if(!_wcsicmp(action,L"disable")){ #if 0 if(stop_service()){ - printf("%s: Service %s stopped.\n", + wprintf(L"%s: Service %s stopped.\n", argv[0],service_name); } #endif if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { - printf("%s: Service %s disabled.\n", + wprintf(L"%s: Service %s disabled.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"enable")){ + if(!_wcsicmp(action,L"enable")){ if(!enable_service()){ - fprintf(stderr,"%s: Failed to enable service %s.\n", + fwprintf(stderr,L"%s: Failed to enable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { - printf("%s: Service %s enabled.\n", + wprintf(L"%s: Service %s enabled.\n", argv[0],service_name); return 0; } } - fprintf(stderr,"%s: Unrecignized argument %s.\n", + fwprintf(stderr,L"%s: Unrecignized argument %s.\n", argv[0],action); return 1; } -int do_add_or_set(int argc, char **argv){ +int do_add_or_set(int argc, wchar_t **argv){ RegEntry *new_entries; RegEntry *default_entries; int add = 0; @@ -669,40 +674,40 @@ int do_add_or_set(int argc, char **argv){ new_entries = empty_reg_tab(); default_entries = empty_reg_tab(); if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; - if(!_stricmp(argv[1],"add")){ + if(!_wcsicmp(argv[1],L"add")){ if(fetch_current(default_entries)){ - fprintf(stderr,"%s: A service with the name %s already " - "exists.\n", + fwprintf(stderr,L"%s: A service with the name %s already " + L"exists.\n", argv[0],service_name); return 1; } real_service_name = generate_real_service_name(service_name); if(!fill_in_defaults(new_entries)){ - fprintf(stderr,"%s: Internal error.\n", argv[0]); + fwprintf(stderr,L"%s: Internal error.\n", argv[0]); return 1; } add = 1; } else { if(!fetch_current(new_entries)){ - fprintf(stderr,"%s: No service with the name %s exists.\n", + fwprintf(stderr,L"%s: No service with the name %s exists.\n", argv[0], service_name); return 1; } - real_service_name = new_entries[InternalServiceName].data.bytes; + real_service_name = new_entries[InternalServiceName].data.string; } if(!fill_in_defaults(default_entries)){ - fprintf(stderr,"%s: Internal error.\n", argv[0]); + fwprintf(stderr,L"%s: Internal error.\n", argv[0]); return 1; } /* make sure env is malloced... */ - new_entries[Env].data.bytes = envdup(new_entries[Env].data.bytes); + new_entries[Env].data.string = envdup(new_entries[Env].data.string); for(i = 3; i < argc; ++i){ switch((current = lookup_arg(argv[i]))){ @@ -712,43 +717,43 @@ int do_add_or_set(int argc, char **argv){ case WorkDir: case Args: if(i+1 >= argc){ - new_entries[current].data.bytes = - default_entries[current].data.bytes; + new_entries[current].data.string = + default_entries[current].data.string; new_entries[current].data.expand.unexpanded = default_entries[current].data.expand.unexpanded; } else { new_entries[current].data.expand.unexpanded = - new_entries[current].data.bytes = argv[i+1]; + new_entries[current].data.string = argv[i+1]; ++i; } break; case SName: - new_entries[Name].data.bytes = ""; + new_entries[Name].data.string = L""; case StopAction: case Name: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ - new_entries[current].data.bytes = - default_entries[current].data.bytes; + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ + new_entries[current].data.string = + default_entries[current].data.string; } else { - new_entries[current].data.bytes = argv[i+1]; + new_entries[current].data.string = argv[i+1]; ++i; } break; case OnFail: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"reboot")) + if(!_wcsicmp(argv[i+1],L"reboot")) new_entries[current].data.value = ON_FAIL_REBOOT; - else if(!_stricmp(argv[i+1],"restart")) + else if(!_wcsicmp(argv[i+1],L"restart")) new_entries[current].data.value = ON_FAIL_RESTART; - else if(!_stricmp(argv[i+1],"restart_always")) + else if(!_wcsicmp(argv[i+1],L"restart_always")) new_entries[current].data.value = ON_FAIL_RESTART_ALWAYS; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -757,18 +762,18 @@ int do_add_or_set(int argc, char **argv){ break; case DebugType: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"new")) + if(!_wcsicmp(argv[i+1],L"new")) new_entries[current].data.value = DEBUG_TYPE_NEW; - else if(!_stricmp(argv[i+1],"reuse")) + else if(!_wcsicmp(argv[i+1],L"reuse")) new_entries[current].data.value = DEBUG_TYPE_REUSE; - else if(!_stricmp(argv[i+1],"console")) + else if(!_wcsicmp(argv[i+1],L"console")) new_entries[current].data.value = DEBUG_TYPE_CONSOLE; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -777,18 +782,18 @@ int do_add_or_set(int argc, char **argv){ break; case Priority: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"high")) + if(!_wcsicmp(argv[i+1],L"high")) new_entries[current].data.value = HIGH_PRIORITY_CLASS; - else if(!_stricmp(argv[i+1],"low")) + else if(!_wcsicmp(argv[i+1],L"low")) new_entries[current].data.value = IDLE_PRIORITY_CLASS; - else if(!_stricmp(argv[i+1],"realtime")) + else if(!_wcsicmp(argv[i+1],L"realtime")) new_entries[current].data.value = REALTIME_PRIORITY_CLASS; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -798,64 +803,64 @@ int do_add_or_set(int argc, char **argv){ case Env: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ - fprintf(stderr,"%s: %s requires a parameter.\n", + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ + fwprintf(stderr,L"%s: %s requires a parameter.\n", argv[0],argv[i]); return 1; } - new_entries[current].data.bytes = - edit_env(argv[i+1], - new_entries[current].data.bytes); + new_entries[current].data.string = + edit_env(argv[i+1], new_entries[current].data.string); ++i; break; case InternalServiceName: if (!add) { - fprintf(stderr,"%s: %s only allowed when adding a new service.\n", + fwprintf(stderr,L"%s: %s only allowed when adding a new service.\n", argv[0],argv[i]); return 1; } if(i+1 >= argc){ - fprintf(stderr,"%s: %s requires a parameter.\n", + fwprintf(stderr,L"%s: %s requires a parameter.\n", argv[0],argv[i]); return 1; } new_entries[InternalServiceName].data.expand.unexpanded = - new_entries[InternalServiceName].data.bytes = argv[i+1]; + new_entries[InternalServiceName].data.string = argv[i+1]; ++i; /* Discard old, should maybe be fred' but we'll exit anyway */ - real_service_name = new_entries[InternalServiceName].data.bytes; + real_service_name = new_entries[InternalServiceName].data.string; break; default: - fprintf(stderr,"%s: Unrecognized option %s.\n", argv[0], + fwprintf(stderr,L"%s: Unrecognized option %s.\n", argv[0], argv[i]); return 1; } } - if(*new_entries[SName].data.bytes && - *new_entries[Name].data.bytes){ + if(*new_entries[SName].data.string && + *new_entries[Name].data.string){ #if 0 - fprintf(stderr,"%s: Both -sname and -name specified.\n", + fwprintf(stderr,L"%s: Both -sname and -name specified.\n", argv[0]); return 1; #else - new_entries[SName].data.bytes = ""; + new_entries[SName].data.string = L""; #endif } - if(add && !(*new_entries[SName].data.bytes) && - !(*new_entries[Name].data.bytes)){ - fprintf(stderr,"%s: Neither -sname nor -name specified.\n", + if(add && !(*new_entries[SName].data.string) && + !(*new_entries[Name].data.string)){ + fwprintf(stderr,L"%s: Neither -sname nor -name specified.\n", argv[0]); return 1; } + if(add && !install_service()){ - fprintf(stderr,"%s: Unable to register service with service manager.\n", + fwprintf(stderr,L"%s: Unable to register %s service with service manager.\n", argv[0], service_name); print_last_error(); return 1; } if(!set_interactive(new_entries[DebugType].data.value == DEBUG_TYPE_CONSOLE)){ - fprintf(stderr,"%s: Warning, could not set correct interactive mode.\n", + fwprintf(stderr,L"%s: Warning, could not set correct interactive mode. %s\n", argv[0], service_name); print_last_error(); /* Not severe or??? */ @@ -865,9 +870,9 @@ int do_add_or_set(int argc, char **argv){ set_keys(service_name, new_entries); /* Update service comment if needed */ if(set_comment) { - if (!set_service_comment(new_entries[Comment].data.bytes)) { - fprintf(stderr,"%s: Warning, could not set correct " - "service description (comment)", + if (!set_service_comment(new_entries[Comment].data.string)) { + fwprintf(stderr,L"%s: Warning, could not set correct " + L"service description (comment) %s", argv[0], service_name); print_last_error(); } @@ -878,64 +883,64 @@ int do_add_or_set(int argc, char **argv){ malloced, but we'll exit anyway, so... */ cleanup_old(); if(add) - printf("%s: Service %s added to system.\n", + wprintf(L"%s: Service %s added to system.\n", argv[0], service_name); else - printf("%s: Service %s updated.\n", + wprintf(L"%s: Service %s updated.\n", argv[0], service_name); return 0; } -int do_rename(int argc, char **argv){ +int do_rename(int argc, wchar_t **argv){ RegEntry *current = empty_reg_tab(); RegEntry *dummy = empty_reg_tab(); SC_HANDLE scm; SC_HANDLE service; if(argc < 3){ - fprintf(stderr,"%s: No old servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No old servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } if(argc < 4){ - fprintf(stderr,"%s: No new servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No new servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[3]; if(fetch_current(dummy)){ - fprintf(stderr,"%s: A service with the name %s already " - "exists.\n", + fwprintf(stderr,L"%s: A service with the name %s already " + L"exists.\n", argv[0],service_name); return 1; } service_name = argv[2]; if(!fetch_current(current)){ - fprintf(stderr,"%s: Error, old service name %s does not exist.\n", + fwprintf(stderr,L"%s: Error, old service name %s does not exist.\n", argv[0],service_name); return 1; } - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); if(!open_service_config(&scm,&service)){ - fprintf(stderr,"%s: Error, unable to communicate with service control" - " manager.\n", + fwprintf(stderr,L"%s: Error, unable to communicate with service control" + L" manager.\n", argv[0]); print_last_error(); return 1; } - if(!ChangeServiceConfig(service, - SERVICE_NO_CHANGE, - SERVICE_NO_CHANGE, - SERVICE_NO_CHANGE, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - argv[3])){ - fprintf(stderr,"%s: Error, unable to communicate with service control" - " manager.\n", + if(!ChangeServiceConfigW(service, + SERVICE_NO_CHANGE, + SERVICE_NO_CHANGE, + SERVICE_NO_CHANGE, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + argv[3])){ + fwprintf(stderr,L"%s: Error, unable to communicate with service control" + L" manager.\n", argv[0]); print_last_error(); CloseServiceHandle(scm); @@ -946,154 +951,154 @@ int do_rename(int argc, char **argv){ CloseServiceHandle(service); if(remove_keys(service_name) != 0) - fprintf(stderr,"%s: Warning, old service parameter keys could not " - "be removed, continuing.\n", argv[0]); + fwprintf(stderr,L"%s: Warning, old service parameter keys could not " + L"be removed, continuing.\n", argv[0]); /* Update registry */ register_logkeys(); set_keys(argv[3], current); - printf("%s: Service %s renamed to %s.\n", + wprintf(L"%s: Service %s renamed to %s.\n", argv[0], service_name, argv[3]); return 0; } -int do_remove(int argc, char **argv){ +int do_remove(int argc, wchar_t **argv){ RegEntry *current = empty_reg_tab(); int rem_res; BOOL found; if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; found = fetch_current(current); if(found){ - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); } else { - real_service_name = _strdup(service_name); + real_service_name = _wcsdup(service_name); } if(found) free_keys(current); if(stop_service() && !wait_service_trans(SERVICE_RUNNING, SERVICE_STOP_PENDING, SERVICE_STOPPED, 60)){ - fprintf(stderr,"%s: Failed to stop running service %s.\n", + fwprintf(stderr,L"%s: Failed to stop running service %s.\n", argv[0],service_name); print_last_error(); return 1; } if(!remove_service()){ - fprintf(stderr,"%s: Unable to remove service (not enough " - "privileges?)\n",argv[0]); + fwprintf(stderr,L"%s: Unable to remove service (not enough " + L"privileges?)\n",argv[0]); print_last_error(); return 1; } if((rem_res = remove_keys(service_name)) > 0){ - fprintf(stderr,"%s: Warning, service parameter keys belonged to old " - "erlsrv version.\n", argv[0]); + fwprintf(stderr,L"%s: Warning, service parameter keys belonged to old " + L"erlsrv version.\n", argv[0]); /* Backward compatibility... */ } else if(rem_res < 0) { - fprintf(stderr,"%s: Error, service parameter keys nonexistent.\n", + fwprintf(stderr,L"%s: Error, service parameter keys nonexistent.\n", argv[0]); return 1; } - printf("%s: Service %s removed from system.\n", + wprintf(L"%s: Service %s removed from system.\n", argv[0], service_name); return 0; } -BOOL list_one(char *servicename, RegEntry *keys, BOOL longlist){ - char *onfail; - char *prio; - char *debugtype; +BOOL list_one(wchar_t *servicename, RegEntry *keys, BOOL longlist){ + wchar_t *onfail; + wchar_t *prio; + wchar_t *debugtype; switch(keys[OnFail].data.value){ case ON_FAIL_RESTART: - onfail = "restart"; + onfail = L"restart"; break; case ON_FAIL_RESTART_ALWAYS: - onfail = "restart_always"; + onfail = L"restart_always"; break; case ON_FAIL_REBOOT: - onfail = "reboot"; + onfail = L"reboot"; break; default: - onfail = "ignore"; + onfail = L"ignore"; } switch(keys[DebugType].data.value){ case DEBUG_TYPE_NEW: - debugtype = "new"; + debugtype = L"new"; break; case DEBUG_TYPE_REUSE: - debugtype = "reuse"; + debugtype = L"reuse"; break; case DEBUG_TYPE_CONSOLE: - debugtype = "console"; + debugtype = L"console"; break; default: - debugtype = "none"; + debugtype = L"none"; } switch(keys[Priority].data.value){ case HIGH_PRIORITY_CLASS: - prio = "high"; + prio = L"high"; break; case IDLE_PRIORITY_CLASS: - prio = "low"; + prio = L"low"; break; case REALTIME_PRIORITY_CLASS: - prio = "realtime"; + prio = L"realtime"; break; case NORMAL_PRIORITY_CLASS: - prio = "default"; + prio = L"default"; break; default: - prio = "unknown/faulty"; + prio = L"unknown/faulty"; } if(longlist){ - char *env = envdup(keys[Env].data.bytes); - char **arg = env_to_arg(env); - char **pek = arg; - printf("Service name: %s\n", + wchar_t *env = envdup(keys[Env].data.string); + wchar_t **arg = env_to_arg(env); + wchar_t **pek = arg; + wprintf(L"Service name: %s\n", servicename); - printf("StopAction: %s\n", - keys[StopAction].data.bytes); - printf("OnFail: %s\n",onfail); - printf("Machine: %s\n", + wprintf(L"StopAction: %s\n", + keys[StopAction].data.string); + wprintf(L"OnFail: %s\n",onfail); + wprintf(L"Machine: %s\n", keys[Machine].data.expand.unexpanded); - printf("WorkDir: %s\n", + wprintf(L"WorkDir: %s\n", keys[WorkDir].data.expand.unexpanded); - if(*keys[SName].data.bytes) - printf("SName: %s\n", - keys[SName].data.bytes); + if(*keys[SName].data.string) + wprintf(L"SName: %s\n", + keys[SName].data.string); else - printf("Name: %s\n", - keys[Name].data.bytes); - printf("Priority: %s\n",prio); - printf("DebugType: %s\n",debugtype); - printf("Args: %s\n", + wprintf(L"Name: %s\n", + keys[Name].data.string); + wprintf(L"Priority: %s\n",prio); + wprintf(L"DebugType: %s\n",debugtype); + wprintf(L"Args: %s\n", keys[Args].data.expand.unexpanded); - printf("InternalServiceName: %s\n", - keys[InternalServiceName].data.bytes); - printf("Comment: %s\n", - keys[Comment].data.bytes); - printf("Env:\n"); + wprintf(L"InternalServiceName: %s\n", + keys[InternalServiceName].data.string); + wprintf(L"Comment: %s\n", + keys[Comment].data.string); + wprintf(L"Env:\n"); while(*pek){ - printf("\t%s\n",*pek); + wprintf(L"\t%s\n",*pek); ++pek; } /* env is easier to free...*/ env = arg_to_env(arg); free(env); } else { - printf("%s\t%s\t%s\t%s\t%s\n", + wprintf(L"%s\t%s\t%s\t%s\t%s\n", servicename, - (*keys[Name].data.bytes) ? - keys[Name].data.bytes : - keys[SName].data.bytes, + (*keys[Name].data.string) ? + keys[Name].data.string : + keys[SName].data.string, prio, onfail, keys[Args].data.expand.unexpanded); @@ -1102,15 +1107,15 @@ BOOL list_one(char *servicename, RegEntry *keys, BOOL longlist){ } -int do_list(int argc, char **argv){ +int do_list(int argc, wchar_t **argv){ if(argc < 3){ RegEntryDesc *all_keys = get_all_keys(); if(!all_keys){ - fprintf(stderr,"%s: No services found in registry.\n", + fwprintf(stderr,L"%s: No services found in registry.\n", argv[0]); return 0; } - printf("Service\t(S)Name\tPrio\tOnFail\tArgs\n"); + wprintf(L"Service\t(S)Name\tPrio\tOnFail\tArgs\n"); while(all_keys->servicename){ list_one(all_keys->servicename,all_keys->entries,FALSE); ++all_keys; @@ -1121,8 +1126,8 @@ int do_list(int argc, char **argv){ service_name = argv[2]; keys = get_keys(service_name); if(!keys){ - fprintf(stderr,"%s: Could not retrieve any " - "registered data for %s.\n",argv[0],service_name); + fwprintf(stderr,L"%s: Could not retrieve any " + L"registered data for %s.\n",argv[0],service_name); return 1; } list_one(service_name, keys, TRUE); @@ -1133,15 +1138,15 @@ int do_list(int argc, char **argv){ #define READ_CHUNK 100 #define ARGV_CHUNK 20 -char *safe_get_line(void){ +wchar_t *safe_get_line(void){ int lsize = READ_CHUNK; - char *line = malloc(READ_CHUNK); + wchar_t *line = malloc(READ_CHUNK*sizeof(wchar_t)); int pos = 0; int ch; - while((ch = getchar()) != EOF && ch != '\n'){ + while((ch = getwchar()) != EOF && ch != L'\n'){ if(pos + 1 >= lsize){ - line = realloc(line,(lsize += READ_CHUNK)); + line = realloc(line,(lsize += READ_CHUNK)*sizeof(wchar_t)); assert(line); } line[pos++] = ch; @@ -1150,22 +1155,22 @@ char *safe_get_line(void){ free(line); return NULL; } - line[pos] = '\0'; + line[pos] = L'\0'; return line; } -void read_arguments(int *pargc, char ***pargv){ +void read_arguments(int *pargc, wchar_t ***pargv){ int argc = 0; int asize = ARGV_CHUNK; - char **argv = malloc(ARGV_CHUNK*sizeof(char *)); - char *tmp; + wchar_t **argv = malloc(ARGV_CHUNK*sizeof(wchar_t *)); + wchar_t *tmp; argv[0] = (*pargv)[0]; argc = 1; while((tmp = safe_get_line()) != NULL){ if(argc + 1 >= asize){ - argv = realloc(argv,(asize += ARGV_CHUNK)*sizeof(char *)); + argv = realloc(argv,(asize += ARGV_CHUNK)*sizeof(wchar_t *)); assert(argv); } argv[argc++] = tmp; @@ -1258,40 +1263,54 @@ void release_lock(void) { -int interactive_main(int argc, char **argv){ - char *action = argv[1]; +int interactive_main(int argc, wchar_t **argv){ + wchar_t *action = argv[1]; int res; - + + _setmode(_fileno(stdin), _O_U8TEXT); /* set stdin to UTF8 */ + _setmode(_fileno(stdout), _O_U8TEXT); /* set stdout to UTF8 */ + _setmode(_fileno(stderr), _O_U8TEXT); /* set stderr to UTF8 */ + if (take_lock() != 0) { - fprintf(stderr,"%s: unable to acquire global lock (%s).\n",argv[0], + fwprintf(stderr,L"%s: unable to acquire global lock (%s).\n",argv[0], ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE); return 1; } - if(!_stricmp(action,"readargs")){ + if(!_wcsicmp(action,L"readargs")){ read_arguments(&argc,&argv); action = argv[1]; } - if(!_stricmp(action,"set") || !_stricmp(action,"add")) + +#ifdef HARDDEBUG + {int i; + for(i=0; i < argc; i++) { + fwprintf(stderr, L"%s ", argv[i]); + } + fwprintf(stderr, L"\n"); + } +#endif + + if(!_wcsicmp(action,L"set") || !_wcsicmp(action,L"add")) res = do_add_or_set(argc,argv); - else if(!_stricmp(action,"rename")) + else if(!_wcsicmp(action,L"rename")) res = do_rename(argc,argv); - else if(!_stricmp(action,"remove")) + else if(!_wcsicmp(action,L"remove")) res = do_remove(argc,argv); - else if(!_stricmp(action,"list")) + else if(!_wcsicmp(action,L"list")) res = do_list(argc,argv); - else if(!_stricmp(action,"start") || - !_stricmp(action,"start_disabled") || - !_stricmp(action,"stop") || - !_stricmp(action,"enable") || - !_stricmp(action,"disable")) + else if(!_wcsicmp(action,L"start") || + !_wcsicmp(action,L"start_disabled") || + !_wcsicmp(action,L"stop") || + !_wcsicmp(action,L"enable") || + !_wcsicmp(action,L"disable")) res = do_manage(argc,argv); - else if(_stricmp(action,"?") && - _stricmp(action,"/?") && - _stricmp(action,"-?") && - *action != 'h' && - *action != 'H') { - fprintf(stderr,"%s: action %s not implemented.\n",argv[0],action); + else if(_wcsicmp(action,L"?") && + _wcsicmp(action,L"/?") && + _wcsicmp(action,L"-?") && + *action != L'h' && + *action != L'H') { + fwprintf(stderr,L"%s: action %s not implemented.\n",argv[0],action); do_usage(argv[0]); res = 1; } else { diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.h b/erts/etc/win32/erlsrv/erlsrv_interactive.h index 23e69e508d..bc6e55fdef 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.h +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.h @@ -21,6 +21,6 @@ #define ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE "{468d6954-e355-415f-968f-d257cb0feef4}" -int interactive_main(int argc, char **argv); +int interactive_main(int argc, wchar_t **argv); #endif /* _ERLSRV_INTERACTIVE_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_main.c b/erts/etc/win32/erlsrv/erlsrv_main.c index 920a4a1827..6d8e208fc8 100644 --- a/erts/etc/win32/erlsrv/erlsrv_main.c +++ b/erts/etc/win32/erlsrv/erlsrv_main.c @@ -25,7 +25,7 @@ #include "erlsrv_interactive.h" #include "erlsrv_service.h" -int main(int argc, char **argv){ +int wmain(int argc, wchar_t **argv){ if(argc > 1) return interactive_main(argc,argv); else diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.c b/erts/etc/win32/erlsrv/erlsrv_registry.c index c1aa9f2b67..ad50da89a4 100644 --- a/erts/etc/win32/erlsrv/erlsrv_registry.c +++ b/erts/etc/win32/erlsrv/erlsrv_registry.c @@ -24,38 +24,37 @@ #include "erlsrv_global.h" #include "erlsrv_registry.h" -#define LOG_TYPE "System" -#define LOG_ROOT \ -"SYSTEM\\CurrentControlSet\\Services\\EventLog\\" LOG_TYPE "\\" +#define LOG_TYPE L"System" +#define LOG_ROOT L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\" LOG_TYPE L"\\" #define LOG_APP_KEY APP_NAME #define BASE_KEY HKEY_LOCAL_MACHINE #define PRODUCT_NAME APP_NAME -#define OLD_PRODUCT_VERSION "1.0" -#define PRODUCT_VERSION "1.1" -#define PROG_KEY "SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME "\\" PRODUCT_VERSION -#define OLD_PROG_KEY "SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME "\\" OLD_PRODUCT_VERSION +#define OLD_PRODUCT_VERSION L"1.0" +#define PRODUCT_VERSION L"1.1" +#define PROG_KEY L"SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME L"\\" PRODUCT_VERSION +#define OLD_PROG_KEY L"SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME L"\\" OLD_PRODUCT_VERSION #define MAX_KEY_LEN MAX_PATH -static const char * const noString = "\0"; +static const wchar_t * const noString = L"\0"; #define MAX_MANDATORY_REG_ENTRY 10 /* InternalServiceName == reg_entries[10] */ static RegEntry reg_entries[] = { - {"StopAction",REG_SZ,NULL}, - {"OnFail",REG_DWORD,NULL}, - {"Machine",REG_EXPAND_SZ,NULL}, - {"Env", REG_MULTI_SZ,NULL}, - {"WorkDir", REG_EXPAND_SZ,NULL}, - {"Priority",REG_DWORD,NULL}, - {"SName",REG_SZ,NULL}, - {"Name",REG_SZ,NULL}, - {"Args",REG_EXPAND_SZ,NULL}, - {"DebugType",REG_DWORD,NULL}, - {"InternalServiceName",REG_SZ,NULL}, + {L"StopAction",REG_SZ,NULL}, + {L"OnFail",REG_DWORD,NULL}, + {L"Machine",REG_EXPAND_SZ,NULL}, + {L"Env", REG_MULTI_SZ,NULL}, + {L"WorkDir", REG_EXPAND_SZ,NULL}, + {L"Priority",REG_DWORD,NULL}, + {L"SName",REG_SZ,NULL}, + {L"Name",REG_SZ,NULL}, + {L"Args",REG_EXPAND_SZ,NULL}, + {L"DebugType",REG_DWORD,NULL}, + {L"InternalServiceName",REG_SZ,NULL}, /* Non mandatory follows */ - {"Comment",REG_SZ,NULL} + {L"Comment",REG_SZ,NULL} }; @@ -73,8 +72,8 @@ void free_keys(RegEntry *keys){ for(i=0;i<num_reg_entries && keys[i].name != NULL;++i){ if((keys[i].type == REG_SZ || keys[i].type == REG_EXPAND_SZ || keys[i].type == REG_MULTI_SZ) && - keys[i].data.bytes != noString){ - free(keys[i].data.bytes); + keys[i].data.string != noString){ + free(keys[i].data.string); if(keys[i].type == REG_EXPAND_SZ && keys[i].data.expand.unexpanded != noString) free(keys[i].data.expand.unexpanded); @@ -92,32 +91,32 @@ void free_all_keys(RegEntryDesc *descs){ free(descs); } -RegEntry *get_keys(char *servicename){ +RegEntry *get_keys(wchar_t *servicename){ RegEntry *res = NULL; HKEY prog_key; int key_opened = 0; int i; DWORD ret; - char *copy; - char *tmpbuf; + wchar_t *copy; + wchar_t *tmpbuf; DWORD tmpbuflen; - char key_to_open[MAX_KEY_LEN]; + wchar_t key_to_open[MAX_KEY_LEN]; DWORD val_type; - char *val_data = malloc(MAX_KEY_LEN); + wchar_t *val_data = (wchar_t *)malloc(MAX_KEY_LEN * sizeof(wchar_t)); DWORD val_datalen; DWORD val_datasiz = MAX_KEY_LEN; - if(strlen(PROG_KEY) + strlen(servicename) + 2 > MAX_KEY_LEN) + if(wcslen(PROG_KEY) + wcslen(servicename) + 2 > MAX_KEY_LEN) goto error; - sprintf(key_to_open,"%s\\%s",PROG_KEY,servicename); + swprintf(key_to_open,MAX_KEY_LEN,L"%s\\%s",PROG_KEY,servicename); - if(RegOpenKeyEx(BASE_KEY, - key_to_open, - 0, - KEY_QUERY_VALUE, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, + key_to_open, + 0, + KEY_QUERY_VALUE, + &prog_key) != ERROR_SUCCESS) goto error; key_opened = 1; @@ -128,12 +127,12 @@ RegEntry *get_keys(char *servicename){ for(i=0;i<num_reg_entries;++i){ for(;;){ val_datalen = val_datasiz; - ret = RegQueryValueEx(prog_key, - reg_entries[i].name, - NULL, - &val_type, - (BYTE *) val_data, - &val_datalen); + ret = RegQueryValueExW(prog_key, + reg_entries[i].name, + NULL, + &val_type, + (BYTE *) val_data, + &val_datalen); if(ret == ERROR_SUCCESS){ if(reg_entries[i].type == val_type) break; @@ -167,41 +166,41 @@ RegEntry *get_keys(char *servicename){ copy = NULL; switch(reg_entries[i].type){ case REG_EXPAND_SZ: - if(!val_datalen || val_data[0] == '\0'){ - copy = (char *) noString; - res[i].data.expand.unexpanded = (char *) noString; + if(!val_datalen || val_data[0] == L'\0'){ + copy = (wchar_t *) noString; + res[i].data.expand.unexpanded = (wchar_t *) noString; } else { - tmpbuf = malloc(MAX_KEY_LEN); + tmpbuf = (wchar_t *) malloc(MAX_KEY_LEN * sizeof(wchar_t)); tmpbuflen = (DWORD) MAX_KEY_LEN; for(;;){ - ret = ExpandEnvironmentStrings(val_data,tmpbuf,tmpbuflen); + ret = ExpandEnvironmentStringsW(val_data,tmpbuf,tmpbuflen); if(!ret){ free(tmpbuf); goto error; }else if(ret > tmpbuflen){ - tmpbuf=realloc(tmpbuf,tmpbuflen=ret); + tmpbuf=realloc(tmpbuf,(tmpbuflen=ret)*sizeof(wchar_t)); } else { - copy = strdup(tmpbuf); + copy = wcsdup(tmpbuf); free(tmpbuf); break; } } - res[i].data.expand.unexpanded = strdup(val_data); + res[i].data.expand.unexpanded = wcsdup(val_data); } case REG_MULTI_SZ: case REG_SZ: if(!copy){ if(!val_datalen || - ((val_datalen == 1 && val_data[0] == '\0') || - (val_datalen == 2 && val_data[0] == '\0' && - val_data[1] == '\0'))){ - copy = (char *) noString; + ((val_datalen == 2 && val_data[0] == L'\0') || + (val_datalen == 4 && val_data[0] == L'\0' && + val_data[1] == L'\0'))){ + copy = (wchar_t *) noString; } else { - copy = malloc(val_datalen); - memcpy(copy,val_data,val_datalen); + copy = malloc(val_datalen); /* val_datalen in bytes */ + memcpy(copy,val_data,val_datalen); } } - res[i].data.bytes = copy; + res[i].data.string = copy; break; case REG_DWORD: memcpy(&res[i].data.value,val_data,sizeof(DWORD)); @@ -222,32 +221,32 @@ error: return NULL; } -int set_keys(char *servicename, RegEntry *keys){ +int set_keys(wchar_t *servicename, RegEntry *keys){ HKEY prog_key; int key_opened = 0; int i; - char key_to_open[MAX_KEY_LEN]; + wchar_t key_to_open[MAX_KEY_LEN]; DWORD disposition; - if(strlen(PROG_KEY) + strlen(servicename) + 2 > MAX_KEY_LEN) + if(wcslen(PROG_KEY) + wcslen(servicename) + 2 > MAX_KEY_LEN) goto error; - sprintf(key_to_open,"%s\\%s",PROG_KEY,servicename); + swprintf(key_to_open,MAX_KEY_LEN,L"%s\\%s",PROG_KEY,servicename); - if(RegOpenKeyEx(BASE_KEY, - key_to_open, - 0, - KEY_SET_VALUE, - &prog_key) != ERROR_SUCCESS){ - if(RegCreateKeyEx(BASE_KEY, - key_to_open, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_SET_VALUE, - NULL, - &prog_key, - &disposition) != ERROR_SUCCESS) - goto error; + if(RegOpenKeyExW(BASE_KEY, + key_to_open, + 0, + KEY_SET_VALUE, + &prog_key) != ERROR_SUCCESS){ + if(RegCreateKeyExW(BASE_KEY, + key_to_open, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, + NULL, + &prog_key, + &disposition) != ERROR_SUCCESS) + goto error; } key_opened = 1; @@ -258,19 +257,19 @@ int set_keys(char *servicename, RegEntry *keys){ int j; switch(keys[i].type){ case REG_SZ: - ptr = keys[i].data.bytes; - siz = strlen(ptr)+1; + ptr = keys[i].data.string; + siz = (wcslen(ptr)+1)*sizeof(wchar_t); break; case REG_EXPAND_SZ: ptr = keys[i].data.expand.unexpanded; - siz = strlen(ptr)+1; + siz = (wcslen(ptr)+1)*sizeof(wchar_t); break; case REG_MULTI_SZ: - ptr = keys[i].data.bytes; - for(j=0;!(((char *)ptr)[j] == '\0' && - ((char *)ptr)[j+1] == '\0');++j) + ptr = keys[i].data.string; + for(j=0;!(((wchar_t *)ptr)[j] == L'\0' && + ((wchar_t *)ptr)[j+1] == L'\0');++j) ; - siz=(DWORD)j+2; + siz=(j+2)*sizeof(wchar_t); break; case REG_DWORD: ptr = &keys[i].data.value; @@ -280,15 +279,15 @@ int set_keys(char *servicename, RegEntry *keys){ goto error; } #ifdef HARDDEBUG - fprintf(stderr,"%s %s:%d\n",keys[i].name, - (keys[i].type == REG_DWORD) ? "(dword)" : ptr,siz); + fprintf(stderr,"%S %S:%d\n",keys[i].name, + (keys[i].type == REG_DWORD) ? L"(dword)" : ptr,siz); #endif - if(RegSetValueEx(prog_key, - keys[i].name, - 0, - keys[i].type, - ptr, - siz) != ERROR_SUCCESS) + if(RegSetValueExW(prog_key, + keys[i].name, + 0, + keys[i].type, + ptr, + siz) != ERROR_SUCCESS) goto error; } RegCloseKey(prog_key); @@ -299,15 +298,15 @@ error: return 1; } -static int do_remove_keys(char *servicename, const char *prog_key_name){ +static int do_remove_keys(wchar_t *servicename, const wchar_t *prog_key_name){ HKEY prog_key; - if(RegOpenKeyEx(BASE_KEY, - prog_key_name, - 0, - KEY_ALL_ACCESS, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, + prog_key_name, + 0, + KEY_ALL_ACCESS, + &prog_key) != ERROR_SUCCESS) return -1; - if(RegDeleteKey(prog_key,servicename) != ERROR_SUCCESS){ + if(RegDeleteKeyW(prog_key,servicename) != ERROR_SUCCESS){ RegCloseKey(prog_key); return -1; } @@ -315,7 +314,7 @@ static int do_remove_keys(char *servicename, const char *prog_key_name){ return 0; } -int remove_keys(char *servicename){ +int remove_keys(wchar_t *servicename){ int ret; if((ret = do_remove_keys(servicename, PROG_KEY)) < 0){ @@ -335,33 +334,33 @@ RegEntryDesc *get_all_keys(void){ HKEY prog_key; int key_opened = 0; DWORD enum_index; - char name[MAX_KEY_LEN]; + wchar_t name[MAX_KEY_LEN]; DWORD namelen; - char class[MAX_KEY_LEN]; + wchar_t class[MAX_KEY_LEN]; DWORD classlen; FILETIME ft; res[ndx].servicename = NULL; - if(RegOpenKeyEx(BASE_KEY, PROG_KEY, 0, - KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, PROG_KEY, 0, + KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, + &prog_key) != ERROR_SUCCESS) goto error; key_opened = 1; for(enum_index = 0, namelen = MAX_KEY_LEN, classlen = MAX_KEY_LEN; - ERROR_SUCCESS == RegEnumKeyEx(prog_key, - enum_index, - name, - &namelen, - NULL, - class, - &classlen, - &ft); + ERROR_SUCCESS == RegEnumKeyExW(prog_key, + enum_index, + name, + &namelen, + NULL, + class, + &classlen, + &ft); ++enum_index, namelen = MAX_KEY_LEN, classlen = MAX_KEY_LEN){ if(ndx >= res_siz - 1) res = realloc(res, (res_siz += 10)*sizeof(RegEntryDesc)); if(!(res[ndx].entries = get_keys(name))) - goto error; - res[ndx].servicename = strdup(name); + goto error; + res[ndx].servicename = wcsdup(name); res[++ndx].servicename = NULL; } RegCloseKey(prog_key); @@ -380,24 +379,24 @@ int register_logkeys(void){ EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; DWORD catcount=1; - char filename[2048]; + wchar_t filename[2048]; DWORD fnsiz=2048; - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, - LOG_ROOT LOG_APP_KEY, 0, - NULL, REG_OPTION_NON_VOLATILE, - KEY_SET_VALUE, NULL, - &key, &disposition) != ERROR_SUCCESS) + if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, + LOG_ROOT LOG_APP_KEY, 0, + NULL, REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, NULL, + &key, &disposition) != ERROR_SUCCESS) return -1; - if(!GetModuleFileName(NULL, filename, fnsiz)) + if(!GetModuleFileNameW(NULL, filename, fnsiz)) return -1; - if(RegSetValueEx(key, "EventMessageFile", - 0, REG_EXPAND_SZ, (LPBYTE) filename, - strlen(filename)+1) != ERROR_SUCCESS) + if(RegSetValueExW(key, L"EventMessageFile", + 0, REG_EXPAND_SZ, (LPBYTE) filename, + (wcslen(filename)+1)*sizeof(wchar_t)) != ERROR_SUCCESS) return -1; - if(RegSetValueEx(key, "TypesSupported", - 0, REG_DWORD, (LPBYTE) &types, - sizeof(DWORD)) != ERROR_SUCCESS) + if(RegSetValueExW(key, L"TypesSupported", + 0, REG_DWORD, (LPBYTE) &types, + sizeof(DWORD)) != ERROR_SUCCESS) return -1; return 0; } diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.h b/erts/etc/win32/erlsrv/erlsrv_registry.h index fbccc5416a..4be10e9ff2 100644 --- a/erts/etc/win32/erlsrv/erlsrv_registry.h +++ b/erts/etc/win32/erlsrv/erlsrv_registry.h @@ -20,20 +20,20 @@ #define _ERLSRV_REGISTRY_H typedef struct _reg_entry { - char *name; + wchar_t *name; DWORD type; union { - char *bytes; + wchar_t *string; DWORD value; struct { - char *bytes; - char *unexpanded; + wchar_t *string; + wchar_t *unexpanded; } expand; } data; } RegEntry; typedef struct _reg_entry_desc { - char *servicename; + wchar_t *servicename; RegEntry *entries; } RegEntryDesc; @@ -67,10 +67,10 @@ extern int num_reg_entries; RegEntry *empty_reg_tab(void); void free_keys(RegEntry *keys); void free_all_keys(RegEntryDesc *descs); -RegEntry *get_keys(char *servicename); -int set_keys(char *servicename, RegEntry *keys); +RegEntry *get_keys(wchar_t *servicename); +int set_keys(wchar_t *servicename, RegEntry *keys); RegEntryDesc *get_all_keys(void); -int remove_keys(char *servicename); +int remove_keys(wchar_t *servicename); int register_logkeys(void); #endif /* _ERLSRV_REGISTRY_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_service.c b/erts/etc/win32/erlsrv/erlsrv_service.c index 58738ee445..2e56c579a2 100644 --- a/erts/etc/win32/erlsrv/erlsrv_service.c +++ b/erts/etc/win32/erlsrv/erlsrv_service.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2012. All Rights Reserved. + * Copyright Ericsson AB 1998-2013. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -99,8 +99,8 @@ static BOOL reset_current(){ } static VOID WINAPI handler(DWORD control){ - char buffer[1024]; - sprintf(buffer,"handler called with control = %d.",(int) control); + wchar_t buffer[1024]; + swprintf(buffer,1024,L"handler called with control = %d.",(int) control); log_debug(buffer); switch(control){ case SERVICE_CONTROL_STOP: @@ -119,7 +119,7 @@ typedef struct _server_info { RegEntry *keys; PROCESS_INFORMATION info; HANDLE erl_stdin; - char *event_name; + wchar_t *event_name; } ServerInfo; @@ -138,7 +138,7 @@ static BOOL reset_acl(SaveAclStruct *save_acl){ return FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ - log_warning("Failed to open access token."); + log_warning(L"Failed to open access token."); return FALSE; } save_acl->initialized = FALSE; @@ -146,7 +146,7 @@ static BOOL reset_acl(SaveAclStruct *save_acl){ TokenDefaultDacl, save_acl->defdacl, sizeof(TOKEN_DEFAULT_DACL))){ - log_warning("Failed to get default ACL from token."); + log_warning(L"Failed to get default ACL from token."); CloseHandle(tokenh); LocalFree(save_acl->defdacl); LocalFree(save_acl->newacl); @@ -177,7 +177,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ save_acl->initialized = FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ - log_warning("Failed to open access token."); + log_warning(L"Failed to open access token."); return FALSE; } save_acl->defdacl = &dummy; @@ -188,7 +188,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ sizeof(TOKEN_DEFAULT_DACL), &required); if(required == 0){ - log_warning("Failed to get any ACL info from token."); + log_warning(L"Failed to get any ACL info from token."); CloseHandle(tokenh); return FALSE; } @@ -200,7 +200,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ &required)){ #ifdef HARDDEBUG { - char *mes; + wchar_t *mes; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, @@ -213,7 +213,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ LocalFree(mes); } #endif - log_warning("Failed to get default ACL from token."); + log_warning(L"Failed to get default ACL from token."); CloseHandle(tokenh); return FALSE; } @@ -221,7 +221,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ oldacl = save_acl->defdacl->DefaultDacl; if(!GetAclInformation(oldacl, &si, sizeof(si), AclSizeInformation)){ - log_warning("Failed to get size information for ACL"); + log_warning(L"Failed to get size information for ACL"); CloseHandle(tokenh); return FALSE; } @@ -237,7 +237,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ 0, 0, &extra_sid)){ - log_warning("Failed to initialize administrator SID."); + log_warning(L"Failed to initialize administrator SID."); CloseHandle(tokenh); return FALSE; } @@ -248,7 +248,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ newacl = LocalAlloc(LPTR,newsize); if(!InitializeAcl(newacl, newsize, ACL_REVISION)){ - log_warning("Failed to initialize new ACL."); + log_warning(L"Failed to initialize new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -258,7 +258,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ for(i=0;i<((int)si.AceCount);++i){ ACE_HEADER *ace_header; if (!GetAce (oldacl, i, &ace_header)){ - log_warning("Failed to get ACE from old ACL."); + log_warning(L"Failed to get ACE from old ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -266,7 +266,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ } if(!AddAce(newacl,ACL_REVISION,0xffffffff,ace_header, ace_header->AceSize)){ - log_warning("Failed to set ACE in new ACL."); + log_warning(L"Failed to set ACE in new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -277,7 +277,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ ACL_REVISION2, PROCESS_ALL_ACCESS, extra_sid)){ - log_warning("Failed to add system ACE to new ACL."); + log_warning(L"Failed to add system ACE to new ACL."); LocalFree(newacl); FreeSid(extra_sid); return FALSE; @@ -288,7 +288,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ TokenDefaultDacl, &newdacl, sizeof(newdacl))){ - log_warning("Failed to set token information"); + log_warning(L"Failed to set token information"); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -302,18 +302,18 @@ static BOOL new_acl(SaveAclStruct *save_acl){ return TRUE; } -static char **find_arg(char **arg, char *str){ - char *tmp; +static wchar_t **find_arg(wchar_t **arg, wchar_t *str){ + wchar_t *tmp; int len; - str = strdup(str); - if((tmp = strchr(str,'=')) == NULL) + str = wcsdup(str); + if((tmp = wcschr(str,L'=')) == NULL) goto fail; tmp++; - *tmp = '\0'; + *tmp = L'\0'; len = tmp - str; while(*arg != NULL){ - if(!_strnicmp(*arg,str,len)){ + if(!_wcsnicmp(*arg,str,len)){ free(str); return arg; } @@ -324,11 +324,11 @@ fail: return NULL; } -static char **merge_environment(char *current, char *add){ - char **c_arg = env_to_arg(envdup(current)); - char **a_arg = env_to_arg(envdup(add)); - char **new; - char **tmp; +static wchar_t **merge_environment(wchar_t *current, wchar_t *add){ + wchar_t **c_arg = env_to_arg(envdup(current)); + wchar_t **a_arg = env_to_arg(envdup(add)); + wchar_t **new; + wchar_t **tmp; int i,j; for(i=0;c_arg[i] != NULL;++i) @@ -336,19 +336,19 @@ static char **merge_environment(char *current, char *add){ for(j=0;a_arg[j] != NULL;++j) ; - new = malloc(sizeof(char *)*(i + j + 3)); + new = malloc(sizeof(wchar_t *)*(i + j + 3)); for(i = 0; c_arg[i] != NULL; ++i) - new[i] = strdup(c_arg[i]); + new[i] = wcsdup(c_arg[i]); new[i] = NULL; for(j = 0; a_arg[j] != NULL; ++j){ if((tmp = find_arg(new,a_arg[j])) != NULL){ free(*tmp); - *tmp = strdup(a_arg[j]); + *tmp = wcsdup(a_arg[j]); } else { - new[i++] = strdup(a_arg[j]); + new[i++] = wcsdup(a_arg[j]); new[i] = NULL; } } @@ -358,12 +358,12 @@ static char **merge_environment(char *current, char *add){ } -static char *get_next_debug_file(char *prefix){ - char *buffer = malloc(strlen(prefix)+12); +static wchar_t *get_next_debug_file(wchar_t *prefix){ + wchar_t *buffer = malloc((wcslen(prefix)+12)*sizeof(wchar_t)); int i; for(i=1;i<100;++i){ - sprintf(buffer,"%s.%d",prefix,i); - if(GetFileAttributes(buffer) == 0xFFFFFFFF) + swprintf(buffer,wcslen(prefix)+12,L"%s.%d",prefix,i); + if(GetFileAttributesW(buffer) == 0xFFFFFFFF) return buffer; } return NULL; @@ -372,56 +372,66 @@ static char *get_next_debug_file(char *prefix){ static BOOL start_a_service(ServerInfo *srvi){ - STARTUPINFO start; - char execbuff[MAX_PATH*4]; /* FIXME: Can get overflow! */ - char namebuff[MAX_PATH]; - char errbuff[MAX_PATH*4]; /* hmmm.... */ + STARTUPINFOW start; + wchar_t namebuff[MAX_PATH]; + wchar_t *execbuff; + wchar_t *errbuff; HANDLE write_pipe = NULL, read_pipe = NULL; SECURITY_ATTRIBUTES pipe_security; SECURITY_ATTRIBUTES attr; HANDLE nul; SaveAclStruct save_acl; - char *my_environ; + wchar_t *my_environ; BOOL console_allocated = FALSE; + int bufflen=0; - if(!(*(srvi->keys[Env].data.bytes))){ + if(!(*(srvi->keys[Env].data.string))){ my_environ = NULL; } else { - char *tmp; - char **merged = merge_environment((tmp = GetEnvironmentStrings()), - srvi->keys[Env].data.bytes); - FreeEnvironmentStrings(tmp); + wchar_t *tmp; + wchar_t **merged = merge_environment((tmp = GetEnvironmentStringsW()), + srvi->keys[Env].data.string); + FreeEnvironmentStringsW(tmp); my_environ = arg_to_env(merged); } - if(!*(srvi->keys[Machine].data.bytes) || - (!*(srvi->keys[SName].data.bytes) && - !*(srvi->keys[Name].data.bytes))){ - log_error("Not enough parameters for erlang service."); + if(!*(srvi->keys[Machine].data.string) || + (!*(srvi->keys[SName].data.string) && + !*(srvi->keys[Name].data.string))){ + log_error(L"Not enough parameters for erlang service."); if(my_environ) free(my_environ); return FALSE; } - if(*(srvi->keys[SName].data.bytes)) - sprintf(namebuff,"-nohup -sname %s",srvi->keys[SName].data.bytes); + if(*(srvi->keys[SName].data.string)) + swprintf(namebuff,MAX_PATH,L"-nohup -sname %s",srvi->keys[SName].data.string); else - sprintf(namebuff,"-nohup -name %s",srvi->keys[Name].data.bytes); + swprintf(namebuff,MAX_PATH,L"-nohup -name %s",srvi->keys[Name].data.string); if(srvi->keys[DebugType].data.value == DEBUG_TYPE_CONSOLE) - strcat(namebuff," -keep_window"); + wcscat(namebuff,L" -keep_window"); + + bufflen = MAX_PATH + + wcslen(srvi->keys[Machine].data.string) + + wcslen(srvi->event_name) + + wcslen(namebuff) + + wcslen(srvi->keys[Args].data.string); + + execbuff = malloc(bufflen * sizeof(wchar_t)); + errbuff = malloc((MAX_PATH + bufflen) * sizeof(wchar_t)); if (srvi->event_name != NULL) { - sprintf(execbuff,"\"%s\" -service_event %s %s %s", - srvi->keys[Machine].data.bytes, - srvi->event_name, - namebuff, - srvi->keys[Args].data.bytes); + swprintf(execbuff,bufflen,L"\"%s\" -service_event %s %s %s", + srvi->keys[Machine].data.string, + srvi->event_name, + namebuff, + srvi->keys[Args].data.string); } else { - sprintf(execbuff,"\"%s\" %s %s", - srvi->keys[Machine].data.bytes, - namebuff, - srvi->keys[Args].data.bytes); + swprintf(execbuff,bufflen,L"\"%s\" %s %s", + srvi->keys[Machine].data.string, + namebuff, + srvi->keys[Args].data.string); } memset (&start, 0, sizeof (start)); @@ -435,45 +445,49 @@ static BOOL start_a_service(ServerInfo *srvi){ if(console_allocated = AllocConsole()) SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),coord); else - log_warning("Unable to allocate debugging console!"); - } else if(*(srvi->keys[StopAction].data.bytes) || + log_warning(L"Unable to allocate debugging console!"); + } else if(*(srvi->keys[StopAction].data.string) || srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG){ pipe_security.nLength = sizeof(pipe_security); pipe_security.lpSecurityDescriptor = NULL; pipe_security.bInheritHandle = TRUE; if(!CreatePipe(&read_pipe,&write_pipe,&pipe_security,0)){ - log_error("Could not create pipe for erlang service."); + log_error(L"Could not create pipe for erlang service."); if(my_environ) - free(my_environ); + free(my_environ); + free(execbuff); + free(errbuff); return FALSE; } if(srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG){ - char *filename; - if(*(srvi->keys[WorkDir].data.bytes)){ - filename = malloc(strlen(srvi->keys[WorkDir].data.bytes) + 1 + - strlen(service_name)+strlen(".debug")+1); - sprintf(filename,"%s\\%s.debug", - srvi->keys[WorkDir].data.bytes, - service_name); + wchar_t *filename; + if(*(srvi->keys[WorkDir].data.string)){ + int filenamelen = (wcslen(srvi->keys[WorkDir].data.string) + 1 + + wcslen(service_name)+wcslen(L".debug")+1); + filename = malloc(filenamelen*sizeof(wchar_t)); + swprintf(filename,filenamelen,L"%s\\%s.debug", + srvi->keys[WorkDir].data.string, + service_name); } else { - filename = malloc(strlen(service_name)+strlen(".debug")+1); - sprintf(filename,"%s.debug",service_name); + int filenamelen = wcslen(service_name)+wcslen(L".debug")+1; + filename = malloc(filenamelen*sizeof(wchar_t)); + swprintf(filename,filenamelen,L"%s.debug",service_name); } log_debug(filename); if(srvi->keys[DebugType].data.value == DEBUG_TYPE_NEW){ - char *tmpfn = get_next_debug_file(filename); + wchar_t *tmpfn = get_next_debug_file(filename); if(tmpfn){ free(filename); filename = tmpfn; } else { - log_warning("Number of debug files exceeds system defined " - "limit, reverting to DebugType: reuse. "); + log_warning(L"Number of debug files exceeds system defined " + L"limit, reverting to DebugType: reuse. "); } } - nul = CreateFile(filename, + nul = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &pipe_security, @@ -492,9 +506,9 @@ static BOOL start_a_service(ServerInfo *srvi){ } if(nul == NULL){ log_error((srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG) - ? "Could not create debug file. " - "(Working directory not valid?)" - : "Cold not open NUL!"); + ? L"Could not create debug file. " + L"(Working directory not valid?)" + : L"Cold not open NUL!"); start.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); start.hStdError = GetStdHandle(STD_ERROR_HANDLE); } @@ -510,23 +524,24 @@ static BOOL start_a_service(ServerInfo *srvi){ new_acl(&save_acl); - if(!CreateProcess(NULL, - execbuff, - &attr, - NULL, - (read_pipe != NULL), - CREATE_DEFAULT_ERROR_MODE | - (srvi->keys[Priority].data.value), - my_environ, - (*(srvi->keys[WorkDir].data.bytes)) ? - srvi->keys[WorkDir].data.bytes : NULL, - &start, - &(srvi->info))){ - sprintf(errbuff,"Could not start erlang service " - "with commandline \"%s\".", - service_name, - execbuff - ); + if(!CreateProcessW(NULL, + execbuff, + &attr, + NULL, + (read_pipe != NULL), + CREATE_UNICODE_ENVIRONMENT | + CREATE_DEFAULT_ERROR_MODE | + (srvi->keys[Priority].data.value), + my_environ, + (*(srvi->keys[WorkDir].data.string)) ? + srvi->keys[WorkDir].data.string : NULL, + &start, + &(srvi->info))){ + swprintf(errbuff,bufflen+MAX_PATH,L"Could not start erlang service \"%s\"" + L"with commandline [%s].", + service_name, + execbuff + ); log_error(errbuff); if(read_pipe != NULL){ CloseHandle(read_pipe); @@ -539,14 +554,16 @@ static BOOL start_a_service(ServerInfo *srvi){ reset_acl(&save_acl); if(my_environ) free(my_environ); + free(execbuff); + free(errbuff); return FALSE; } if(console_allocated) FreeConsole(); #ifdef HARDDEBUG - sprintf(errbuff, - "Started %s with the following commandline: " - "%s",service_name,execbuff); + swprintf(errbuff,bufflen+MAX_PATH, + L"Started %s with the following commandline: %s", + service_name,execbuff); log_debug(errbuff); #endif if(read_pipe != NULL){ @@ -559,19 +576,21 @@ static BOOL start_a_service(ServerInfo *srvi){ reset_acl(&save_acl); if(my_environ) free(my_environ); + free(execbuff); + free(errbuff); return TRUE; } -static HANDLE create_erlang_event(char *event_name) +static HANDLE create_erlang_event(wchar_t *event_name) { HANDLE e; - if ((e = OpenEvent(EVENT_ALL_ACCESS,FALSE,event_name)) == NULL) { - if ((e = CreateEvent(NULL, TRUE, FALSE, event_name)) == NULL) { - log_warning("Could not create or access erlang termination event"); + if ((e = OpenEventW(EVENT_ALL_ACCESS,FALSE,event_name)) == NULL) { + if ((e = CreateEventW(NULL, TRUE, FALSE, event_name)) == NULL) { + log_warning(L"Could not create or access erlang termination event"); } } else { if (!ResetEvent(e)) { - log_warning("Could not reset erlang termination event."); + log_warning(L"Could not reset erlang termination event."); } } return e; @@ -580,17 +599,18 @@ static HANDLE create_erlang_event(char *event_name) static BOOL stop_erlang(ServerInfo *srvi, int waithint, int *checkpoint){ DWORD written = 0; - char *action = srvi->keys[StopAction].data.bytes; - DWORD towrite = strlen(action)+1; - char *toerl; + wchar_t *wc_action = srvi->keys[StopAction].data.string; + DWORD towrite = wcslen(wc_action); + char *toerl; DWORD exitcode; int i; int kill; if(towrite > 2 && srvi->erl_stdin != NULL){ - toerl = malloc(towrite+1); - strcpy(toerl,action); - strcat(toerl,"\n"); + towrite = WideCharToMultiByte(CP_UTF8, 0, wc_action, -1, NULL, 0, NULL, NULL); + toerl = malloc((1+towrite)*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wc_action, -1, toerl, towrite, NULL, NULL); + strcat(toerl, "\n"); WriteFile(srvi->erl_stdin, toerl, towrite, &written,0); free(toerl); /* Give it 45 seconds to terminate */ @@ -605,9 +625,9 @@ static BOOL stop_erlang(ServerInfo *srvi, int waithint, ++(*checkpoint); set_stop_pending(waithint,*checkpoint); } - log_warning("StopAction did not terminate erlang. Trying forced kill."); + log_warning(L"StopAction did not terminate erlang. Trying forced kill."); } - log_debug("Terminating erlang..."); + log_debug(L"Terminating erlang..."); kill = 1; if(eventKillErlang != NULL && SetEvent(eventKillErlang) != 0){ for(i=0;i<10;++i){ @@ -621,25 +641,25 @@ static BOOL stop_erlang(ServerInfo *srvi, int waithint, } else { #ifdef HARDDEBUG { - char *mes; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &mes, - 0, - NULL ); + wchar_t *mes; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &mes, + 0, + NULL ); log_info(mes); LocalFree(mes); } #endif - log_debug("Could not send control event to Erlang process"); + log_debug(L"Could not send control event to Erlang process"); } if(kill){ - log_warning("Using TerminateProcess to kill erlang."); + log_warning(L"Using TerminateProcess to kill erlang."); if(!TerminateProcess(srvi->info.hProcess,NO_ERROR)) - log_error("TerminateProcess failed"); + log_error(L"TerminateProcess failed"); } GetExitCodeProcess(srvi->info.hProcess,&exitcode); CloseHandle(srvi->info.hProcess); @@ -668,14 +688,14 @@ static BOOL enable_privilege(void) { static BOOL pull_service_name(void){ SC_HANDLE scm; DWORD sz = 1024; - static char service_name_buff[1024]; + static wchar_t service_name_buff[1024]; if((scm = OpenSCManager(NULL, NULL, GENERIC_READ)) == NULL){ return FALSE; } - if(!GetServiceDisplayName(scm,real_service_name,service_name_buff,&sz)) + if(!GetServiceDisplayNameW(scm,real_service_name,service_name_buff,&sz)) return FALSE; CloseServiceHandle(scm); service_name = service_name_buff; @@ -683,7 +703,7 @@ static BOOL pull_service_name(void){ } -static VOID WINAPI service_main_loop(DWORD argc, char **argv){ +static VOID WINAPI service_main_loop(DWORD argc, wchar_t **argv){ int waithint = 30000; int checkpoint = 1; RegEntry *keys; @@ -692,36 +712,35 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ HANDLE harr[2]; FILETIME creationt,exitt,kernelt,usert; LONGLONG creationl,exitl,diffl; - char event_name[MAX_PATH] = "ErlSrv_"; - char executable_name[MAX_PATH]; + wchar_t event_name[MAX_PATH] = L"ErlSrv_"; + wchar_t executable_name[MAX_PATH]; #ifdef DEBUG - char errorbuff[2048]; /* FIXME... */ + wchar_t errorbuff[2048]; /* FIXME... */ #endif int success_wait = NO_SUCCESS_WAIT; real_service_name = argv[0]; if(!pull_service_name()){ - log_error("Could not get Display name of erlang service."); + log_error(L"Could not get Display name of erlang service."); set_stopped(ERROR_CANTREAD); return; } - SetEnvironmentVariable((LPCTSTR) SERVICE_ENV, (LPCTSTR) service_name); + SetEnvironmentVariableW(SERVICE_ENV, service_name); - strncat(event_name, service_name, MAX_PATH - strlen(event_name)); - event_name[MAX_PATH - 1] = '\0'; + wcsncat(event_name, service_name, MAX_PATH - wcslen(event_name)); + event_name[MAX_PATH - 1] = L'\0'; - if(!GetModuleFileName(NULL, executable_name, MAX_PATH)){ - log_error("Unable to retrieve module file name, " EXECUTABLE_ENV - " will not be set."); + if(!GetModuleFileNameW(NULL, executable_name, MAX_PATH)){ + log_error(L"Unable to retrieve module file name, " EXECUTABLE_ENV + L" will not be set."); } else { - char quoted_exe_name[MAX_PATH+4]; - sprintf(quoted_exe_name, "\"%s\"", executable_name); - SetEnvironmentVariable((LPCTSTR) EXECUTABLE_ENV, - (LPCTSTR) quoted_exe_name); + wchar_t quoted_exe_name[MAX_PATH+4]; + swprintf(quoted_exe_name, MAX_PATH+4, L"\"%s\"", executable_name); + SetEnvironmentVariableW(EXECUTABLE_ENV, quoted_exe_name); } - log_debug("Here we go, service_main_loop..."); + log_debug(L"Here we go, service_main_loop..."); currentState = SERVICE_START_PENDING; InitializeCriticalSection(&crit); eventStop = CreateEvent(NULL,FALSE,FALSE,NULL); @@ -730,13 +749,13 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } else { srvi.event_name = NULL; } - statusHandle = RegisterServiceCtrlHandler(real_service_name, &handler); + statusHandle = RegisterServiceCtrlHandlerW(real_service_name, &handler); if(!statusHandle) return; set_start_pending(waithint,checkpoint); keys = get_keys(service_name); if(!keys){ - log_error("Could not get registry keys for erlang service."); + log_error(L"Could not get registry keys for erlang service."); set_stopped(ERROR_CANTREAD); return; } @@ -745,7 +764,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ ++checkpoint; if(!start_a_service(&srvi)){ - log_error("Could not start erlang machine"); + log_error(L"Could not start erlang machine"); set_stopped(ERROR_PROCESS_ABORTED); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); @@ -769,16 +788,16 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ if(ret == WAIT_TIMEOUT){ /* Just do the "success reporting" and continue */ if(success_wait == INITIAL_SUCCESS_WAIT){ - log_info("Erlang service started successfully."); + log_info(L"Erlang service started successfully."); } else { - log_warning("Erlang service restarted"); + log_warning(L"Erlang service restarted"); } success_wait = NO_SUCCESS_WAIT; continue; } if(ret == WAIT_FAILED || (int)(ret-WAIT_OBJECT_0) >= 2){ set_stopped(WAIT_FAILED); - log_error("Internal error, could not wait for objects."); + log_error(L"Internal error, could not wait for objects."); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); } @@ -791,7 +810,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ checkpoint = 2; /* 1 is taken by the handler */ set_stop_pending(waithint,checkpoint); if(stop_erlang(&srvi,waithint,&checkpoint)){ - log_debug("Erlang machine is stopped"); + log_debug(L"Erlang machine is stopped"); CloseHandle(eventStop); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); @@ -802,7 +821,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ free_keys(keys); return; } else { - log_warning("Unable to stop erlang service."); + log_warning(L"Unable to stop erlang service."); set_running(); continue; } @@ -811,12 +830,12 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ save_keys = keys; keys = get_keys(service_name); if(!keys){ - log_error("Could not reload registry keys."); + log_error(L"Could not reload registry keys."); keys = srvi.keys = save_keys; } else { #ifdef HARDDEBUG - sprintf(errorbuff,"Reloaded the registry keys because %s stopped.", - service_name); + swprintf(errorbuff,2048,L"Reloaded the registry keys because %s stopped.", + service_name); log_debug(errorbuff); #endif /* HARDDEBUG */ free_keys(save_keys); @@ -827,7 +846,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ if(!GetProcessTimes(srvi.info.hProcess,&creationt, &exitt,&kernelt,&usert)){ DWORD rcode = GetLastError(); - log_error("Could not get process time of terminated process."); + log_error(L"Could not get process time of terminated process."); CloseHandle(srvi.info.hProcess); CloseHandle(srvi.info.hThread); CloseHandle(eventStop); @@ -850,15 +869,14 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ diffl = exitl - creationl; diffl /= 10000000; #ifdef DEBUG - sprintf(errorbuff,"Process lived for %d seconds", (int) diffl); + swprintf(errorbuff,2048,L"Process lived for %d seconds", (int) diffl); log_debug(errorbuff); #endif if(diffl > CYCLIC_RESTART_LIMIT || srvi.keys[OnFail].data.value == ON_FAIL_RESTART_ALWAYS){ if(!start_a_service(&srvi)){ - log_error("Unable to restart failed erlang service, " - "aborting."); + log_error(L"Unable to restart failed erlang service, aborting."); CloseHandle(eventStop); set_stopped(ERROR_PROCESS_ABORTED); if (eventKillErlang != NULL) { @@ -867,19 +885,19 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ free_keys(keys); return; } - log_warning("Restarted erlang machine."); + log_warning(L"Restarted erlang machine."); if(diffl <= CYCLIC_RESTART_LIMIT) - log_warning("Possible cyclic restarting of erlang machine."); + log_warning(L"Possible cyclic restarting of erlang machine."); success_wait = RESTART_SUCCESS_WAIT; harr[0] = srvi.info.hProcess; } else { if(success_wait == INITIAL_SUCCESS_WAIT){ - log_error("Erlang machine stopped instantly " - "(distribution name conflict?). " - "The service is not restarted, ignoring OnFail option."); + log_error(L"Erlang machine stopped instantly " + L"(distribution name conflict?). " + L"The service is not restarted, ignoring OnFail option."); } else { - log_error("Erlang machine seems to die " - "continously, not restarted."); + log_error(L"Erlang machine seems to die " + L"continously, not restarted."); } CloseHandle(eventStop); set_stopped(ERROR_PROCESS_ABORTED); @@ -890,21 +908,21 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ return; } } else if(srvi.keys[OnFail].data.value == ON_FAIL_REBOOT){ - log_error("Rebooting because erlang machine stopped."); + log_error(L"Rebooting because erlang machine stopped."); enable_privilege(); if(!InitiateSystemShutdown("",NULL,0,TRUE,TRUE)){ - log_error("Failed to reboot!"); + log_error(L"Failed to reboot!"); #ifdef HARDDEBUG { - char *mes; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &mes, - 0, - NULL ); + wchar_t *mes; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &mes, + 0, + NULL ); log_debug(mes); LocalFree(mes); } @@ -923,13 +941,13 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } else { DWORD ecode = NO_ERROR; if(success_wait == NO_SUCCESS_WAIT){ - log_warning("Erlang machine voluntarily stopped. " - "The service is not restarted as OnFail " - "is set to ignore."); + log_warning(L"Erlang machine voluntarily stopped. " + L"The service is not restarted as OnFail " + L"is set to ignore."); } else { - log_error("Erlang machine stopped instantly " - "(distribution name conflict?). " - "The service is not restarted as OnFail is set to ignore."); + log_error(L"Erlang machine stopped instantly " + L"(distribution name conflict?). " + L"The service is not restarted as OnFail is set to ignore."); ecode = ERROR_PROCESS_ABORTED; } CloseHandle(srvi.info.hProcess); @@ -946,20 +964,19 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } } -int service_main(int argc, char **argv){ - char dummy_name[] = ""; - SERVICE_TABLE_ENTRY serviceTable[] = +int service_main(int argc, wchar_t **argv){ + wchar_t dummy_name[] = L""; + SERVICE_TABLE_ENTRYW serviceTable[] = { { dummy_name, - (LPSERVICE_MAIN_FUNCTION) service_main_loop}, + (LPSERVICE_MAIN_FUNCTIONW) service_main_loop}, { NULL, NULL } }; BOOL success; - success = - StartServiceCtrlDispatcher(serviceTable); + success = StartServiceCtrlDispatcherW(serviceTable); if (!success) - log_error("Could not initiate service"); - log_debug("service_main done its job"); + log_error(L"Could not initiate service"); + log_debug(L"service_main done its job"); return 0; } diff --git a/erts/etc/win32/erlsrv/erlsrv_service.h b/erts/etc/win32/erlsrv/erlsrv_service.h index 3eab275836..c46689d83e 100644 --- a/erts/etc/win32/erlsrv/erlsrv_service.h +++ b/erts/etc/win32/erlsrv/erlsrv_service.h @@ -27,6 +27,6 @@ #define RESTART_SUCCESS_WAIT 2 -int service_main(int argc, char **argv); +int service_main(int argc, wchar_t **argv); #endif /* _ERLSRV_SERVICE_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_util.c b/erts/etc/win32/erlsrv/erlsrv_util.c index da3c6f5ef7..4b1ba071e8 100644 --- a/erts/etc/win32/erlsrv/erlsrv_util.c +++ b/erts/etc/win32/erlsrv/erlsrv_util.c @@ -25,76 +25,76 @@ #include "erlsrv_util.h" #include "erlsrv_logmess.h" -char *service_name = ""; -char *real_service_name = ""; +wchar_t *service_name = L""; +wchar_t *real_service_name = L""; -void log_warning(char *mess){ +void log_warning(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_WARNING_TYPE, 0, MSG_WARNING, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_WARNING_TYPE, 0, MSG_WARNING, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } -void log_error(char *mess){ +void log_error(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_ERROR_TYPE, 0, MSG_ERROR, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_ERROR_TYPE, 0, MSG_ERROR, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } -void log_info(char *mess){ +void log_info(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_INFORMATION_TYPE, 0, MSG_INFO, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_INFORMATION_TYPE, 0, MSG_INFO, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } #ifndef NDEBUG -void log_debug(char *mess){ - char *buff=malloc(strlen(mess)+100); - sprintf(buff,"DEBUG! %s",mess); +void log_debug(wchar_t *mess){ + wchar_t *buff=malloc((wcslen(mess)+100)*sizeof(wchar_t)); + swprintf(buff,wcslen(mess)+100,L"DEBUG! %s",mess); log_info(buff); free(buff); } #endif -char *envdup(char *env){ - char *tmp; +wchar_t *envdup(wchar_t *env){ + wchar_t *tmp; int len; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1) + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1) ; len = (tmp - env) + 1; if(len == 1) ++len; - tmp = malloc(len); - memcpy(tmp,env,len); + tmp = malloc(len*sizeof(wchar_t)); + memcpy(tmp,env,len*sizeof(wchar_t)); return tmp; } -char **env_to_arg(char *env){ - char **ret; - char *tmp; +wchar_t **env_to_arg(wchar_t *env){ + wchar_t **ret; + wchar_t *tmp; int i; int num_strings = 0; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1) + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1) ++num_strings; /* malloc enough to insert ONE string */ - ret = malloc(sizeof(char *) * (num_strings + 2)); + ret = malloc(sizeof(wchar_t *) * (num_strings + 2)); i = 0; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1){ - ret[i++] = strdup(tmp); + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1){ + ret[i++] = wcsdup(tmp); } ret[i] = NULL; free(env); @@ -102,52 +102,52 @@ char **env_to_arg(char *env){ } static int compare(const void *a, const void *b){ - char *s1 = *((char **) a); - char *s2 = *((char **) b); - char *e1 = strchr(s1,'='); - char *e2 = strchr(s2,'='); + wchar_t *s1 = *((wchar_t **) a); + wchar_t *s2 = *((wchar_t **) b); + wchar_t *e1 = wcschr(s1,L'='); + wchar_t *e2 = wcschr(s2,L'='); int ret; int len; if(!e1) - e1 = s1 + strlen(s1); + e1 = s1 + wcslen(s1); if(!e2) - e2 = s2 + strlen(s2); + e2 = s2 + wcslen(s2); if((e1 - s1) > (e2 - s2)) len = (e2 - s2); else len = (e1 - s1); - ret = _strnicmp(s1,s2,len); + ret = _wcsnicmp(s1,s2,len); if(ret == 0) return ((e1 - s1) - (e2 - s2)); else return ret; } -char *arg_to_env(char **arg){ - char *block; - char *pek; +wchar_t *arg_to_env(wchar_t **arg){ + wchar_t *block; + wchar_t *pek; int i; int totlen = 1; /* extra '\0' */ for(i=0;arg[i] != NULL;++i) - totlen += strlen(arg[i])+1; + totlen += wcslen(arg[i])+1; /* sort the environment vector */ - qsort(arg,i,sizeof(char *),&compare); + qsort(arg,i,sizeof(wchar_t *),&compare); if(totlen == 1){ - block = malloc(2); - block[0] = block[1] = '\0'; + block = malloc(2*sizeof(wchar_t)); + block[0] = block[1] = L'\0'; } else { - block = malloc(totlen); + block = malloc(totlen*sizeof(wchar_t)); pek = block; for(i=0; arg[i] != NULL; ++i){ - strcpy(pek, arg[i]); + wcscpy(pek, arg[i]); free(arg[i]); - pek += strlen(pek)+1; + pek += wcslen(pek)+1; } - *pek = '\0'; + *pek = L'\0'; } free(arg); return block; diff --git a/erts/etc/win32/erlsrv/erlsrv_util.h b/erts/etc/win32/erlsrv/erlsrv_util.h index b98a6cd3ef..6881906a52 100644 --- a/erts/etc/win32/erlsrv/erlsrv_util.h +++ b/erts/etc/win32/erlsrv/erlsrv_util.h @@ -19,30 +19,30 @@ #ifndef _ERLSRV_UTIL_H #define _ERLSRV_UTIL_H -extern char *service_name; -extern char *real_service_name; -void log_warning(char *mess); -void log_error(char *mess); -void log_info(char *mess); +extern wchar_t *service_name; +extern wchar_t *real_service_name; +void log_warning(wchar_t *mess); +void log_error(wchar_t *mess); +void log_info(wchar_t *mess); -char *envdup(char *env); +wchar_t *envdup(wchar_t *env); /* ** Call before env_to_arg to get a 'freeable' environment block. */ -char *arg_to_env(char **arg); +wchar_t *arg_to_env(wchar_t **arg); /* ** Frees the argument list before returning! */ -char **env_to_arg(char *env); +wchar_t **env_to_arg(wchar_t *env); /* ** Frees the environment block before returning! */ #ifndef NDEBUG -void log_debug(char *mess); +void log_debug(wchar_t *mess); #else #define log_debug(mess) /* Debug removed */ #endif diff --git a/erts/etc/win32/init_file.c b/erts/etc/win32/init_file.c index 52f6c41d1d..d452afa65c 100644 --- a/erts/etc/win32/init_file.c +++ b/erts/etc/win32/init_file.c @@ -173,7 +173,7 @@ static void digout_key_value(char *line, char **key, char **value) } } -InitFile *load_init_file(char *filename) +InitFile *load_init_file(wchar_t *filename) { HANDLE infile; InitFile *inif; @@ -187,13 +187,13 @@ InitFile *load_init_file(char *filename) int i; - if ( (infile = CreateFile(filename, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) { + if ( (infile = CreateFileW(filename, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) { return NULL; } @@ -280,7 +280,7 @@ InitFile *load_init_file(char *filename) return inif; } -int store_init_file(InitFile *inif, char *filename) +int store_init_file(InitFile *inif, wchar_t *filename) { char *buff; int size = 10; @@ -297,13 +297,13 @@ int store_init_file(InitFile *inif, char *filename) buff[num++] = (Char); \ } while(0) - if ( (outfile = CreateFile(filename, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) { + if ( (outfile = CreateFileW(filename, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) { return INIT_FILE_OPEN_ERROR; } buff = ALLOC(size); diff --git a/erts/etc/win32/init_file.h b/erts/etc/win32/init_file.h index 48d2d2df62..ae40e88520 100644 --- a/erts/etc/win32/init_file.h +++ b/erts/etc/win32/init_file.h @@ -36,10 +36,10 @@ typedef struct { } InitFile; /* Load a file structure from a disk file */ -InitFile *load_init_file(char *filename); +InitFile *load_init_file(wchar_t *filename); /* Stores a file structure into a disk file */ -int store_init_file(InitFile *inif, char *filename); +int store_init_file(InitFile *inif, wchar_t *filename); /* Create an empty file structure */ InitFile *create_init_file(void); diff --git a/erts/etc/win32/start_erl.c b/erts/etc/win32/start_erl.c index facf79e5ff..0ca12f09c9 100644 --- a/erts/etc/win32/start_erl.c +++ b/erts/etc/win32/start_erl.c @@ -30,7 +30,7 @@ #include <windows.h> #include <assert.h> -char *progname; +wchar_t *progname; /* * If CASE_SENSITIVE_OPTIONS is specified, options are case sensitive @@ -43,26 +43,26 @@ char *progname; #define strnicmp _strnicmp #endif -#define RELEASE_SUBDIR "\\releases" -#define ERTS_SUBDIR_PREFIX "\\erts-" -#define BIN_SUBDIR "\\bin" -#define REGISTRY_BASE "Software\\Ericsson\\Erlang\\" -#define DEFAULT_DATAFILE "start_erl.data" +#define RELEASE_SUBDIR L"\\releases" +#define ERTS_SUBDIR_PREFIX L"\\erts-" +#define BIN_SUBDIR L"\\bin" +#define REGISTRY_BASE L"Software\\Ericsson\\Erlang\\" +#define DEFAULT_DATAFILE L"start_erl.data" /* Global variables holding option values and command lines */ -char *CommandLineStart = NULL; -char *ErlCommandLine = NULL; -char *MyCommandLine = NULL; -char *DataFileName = NULL; -char *RelDir = NULL; -char *BootFlagsFile = NULL; -char *BootFlags = NULL; -char *RegistryKey = NULL; -char *BinDir = NULL; -char *RootDir = NULL; -char *VsnDir = NULL; -char *Version = NULL; -char *Release = NULL; +wchar_t *CommandLineStart = NULL; +wchar_t *ErlCommandLine = NULL; +wchar_t *MyCommandLine = NULL; +wchar_t *DataFileName = NULL; +wchar_t *RelDir = NULL; +wchar_t *BootFlagsFile = NULL; +wchar_t *BootFlags = NULL; +wchar_t *RegistryKey = NULL; +wchar_t *BinDir = NULL; +wchar_t *RootDir = NULL; +wchar_t *VsnDir = NULL; +wchar_t *Version = NULL; +wchar_t *Release = NULL; BOOL NoConfig=FALSE; PROCESS_INFORMATION ErlProcessInfo; @@ -100,7 +100,7 @@ void exit_help(char *err) ShowLastError(); fprintf(stderr, "** Error: %s\n", err); - printf("Usage:\n%s\n" + printf("Usage:\n%S\n" " [<erlang options>] ++\n" " [-data <datafile>]\n" " {-rootdir <erlang root directory> | \n" @@ -119,56 +119,56 @@ void exit_help(char *err) */ void split_commandline(void) { - char *cmdline = CommandLineStart; + wchar_t *cmdline = CommandLineStart; progname=cmdline; /* Remove the first (quoted) string (our program name) */ - if(*cmdline == '"') { + if(*cmdline == L'"') { cmdline++; /* Skip " */ - while( (*cmdline != '\0') && (*cmdline++) != '"' ) + while( (*cmdline != L'\0') && (*cmdline++) != L'"' ) ; } else { - while( (*cmdline != '\0') && (*cmdline++) != ' ' ) + while( (*cmdline != L'\0') && (*cmdline++) != L' ' ) ; } - while( (*cmdline) == ' ' ) + while( (*cmdline) == L' ' ) cmdline++; - if( *cmdline == '\0') { - ErlCommandLine = ""; - MyCommandLine = ""; + if( *cmdline == L'\0') { + ErlCommandLine = L""; + MyCommandLine = L""; return; } - cmdline[-1] = '\0'; + cmdline[-1] = L'\0'; /* Start from the end of the string and search for "++ " (PLUS PLUS SPACE) */ ErlCommandLine = cmdline; - if(strncmp(cmdline,"++ ",3)) - cmdline = strstr(cmdline," ++ "); + if(wcsncmp(cmdline,L"++ ",3)) + cmdline = wcsstr(cmdline,L" ++ "); if( cmdline == NULL ) { - MyCommandLine = ""; + MyCommandLine = L""; return; } /* Terminate the ErlCommandLine where MyCommandLine starts */ *cmdline++ = '\0'; /* Skip 'whitespace--whitespace' (WHITESPACE MINUS MINUS WHITESPACE) */ - while( (*cmdline) == ' ' ) + while( (*cmdline) == L' ' ) cmdline++; - while( (*cmdline) == '+' ) + while( (*cmdline) == L'+' ) cmdline++; - while( (*cmdline) == ' ' ) + while( (*cmdline) == L' ' ) cmdline++; MyCommandLine = cmdline; #ifdef _DEBUG - fprintf(stderr, "ErlCommandLine: '%s'\n", ErlCommandLine); - fprintf(stderr, "MyCommandLine: '%s'\n", MyCommandLine); + fprintf(stderr, "ErlCommandLine: '%S'\n", ErlCommandLine); + fprintf(stderr, "MyCommandLine: '%S'\n", MyCommandLine); #endif } @@ -178,30 +178,30 @@ void split_commandline(void) * Skips any leading spaces and parses up to NULL or end of quoted string. * Calls exit_help() if an unterminated quote is detected. */ -char * unquote_optionarg(char *str, char **strp) +wchar_t * unquote_optionarg(wchar_t *str, wchar_t **strp) { - char *newstr = (char *)malloc(strlen(str)+1); /* This one is - realloc:ed later */ + /* This one is realloc:ed later */ + wchar_t *newstr = (wchar_t *)malloc((wcslen(str)+1)*sizeof(wchar_t)); int i = 0, inquote = 0; assert(newstr); assert(str); /* Skip leading spaces */ - while( *str == ' ' ) + while( *str == L' ' ) str++; /* Loop while in quote or until EOS or unquoted space */ - while( (inquote==1) || ( (*str!=0) && (*str!=' ') ) ) { + while( (inquote==1) || ( (*str!=0) && (*str!=L' ') ) ) { switch( *str ) { - case '\\': + case L'\\': /* If we are inside a quoted string we should convert \c to c */ - if( inquote && str[1] == '"' ) + if( inquote && str[1] == L'"' ) str++; newstr[i++]=*str++; break; - case '"': + case L'"': inquote = 1-inquote; *str++; break; @@ -220,7 +220,7 @@ char * unquote_optionarg(char *str, char **strp) *strp = str; /* Adjust memblock of newstr */ - newstr = (char *)realloc(newstr, i); + newstr = (wchar_t *)realloc(newstr, i*sizeof(wchar_t)); assert(newstr); return(newstr); } @@ -232,34 +232,34 @@ char * unquote_optionarg(char *str, char **strp) */ void parse_commandline(void) { - char *cmdline = MyCommandLine; + wchar_t *cmdline = MyCommandLine; - while( *cmdline != '\0' ) { + while( *cmdline != L'\0' ) { switch( *cmdline ) { case '-': /* Handle both -arg and /arg */ case '/': *cmdline++; - if( strnicmp(cmdline, "data", 4) == 0) { + if( _wcsnicmp(cmdline, L"data", 4) == 0) { DataFileName = unquote_optionarg(cmdline+4, &cmdline); - } else if( strnicmp(cmdline, "rootdir", 7) == 0) { + } else if( _wcsnicmp(cmdline, L"rootdir", 7) == 0) { RootDir = unquote_optionarg(cmdline+7, &cmdline); #ifdef _DEBUG - fprintf(stderr, "RootDir: '%s'\n", RootDir); + fprintf(stderr, "RootDir: '%S'\n", RootDir); #endif - } else if( strnicmp(cmdline, "reldir", 6) == 0) { + } else if( _wcsnicmp(cmdline, L"reldir", 6) == 0) { RelDir = unquote_optionarg(cmdline+6, &cmdline); #ifdef _DEBUG - fprintf(stderr, "RelDir: '%s'\n", RelDir); + fprintf(stderr, "RelDir: '%S'\n", RelDir); #endif - } else if( strnicmp(cmdline, "bootflags", 9) == 0) { + } else if( _wcsnicmp(cmdline, L"bootflags", 9) == 0) { BootFlagsFile = unquote_optionarg(cmdline+9, &cmdline); - } else if( strnicmp(cmdline, "noconfig", 8) == 0) { + } else if( _wcsnicmp(cmdline, L"noconfig", 8) == 0) { NoConfig=TRUE; #ifdef _DEBUG fprintf(stderr, "NoConfig=TRUE\n"); #endif } else { - fprintf(stderr, "Unkown option: '%s'\n", cmdline); + fprintf(stderr, "Unkown option: '%S'\n", cmdline); exit_help("Unknown command line option"); } break; @@ -281,32 +281,35 @@ void parse_commandline(void) void read_datafile(void) { FILE *fp; - char *newname; + wchar_t *newname; long size; + char *ver; + char *rel; - if(!DataFileName){ - DataFileName = malloc(strlen(DEFAULT_DATAFILE) + 1); - strcpy(DataFileName,DEFAULT_DATAFILE); + if(!DataFileName){ + DataFileName = malloc((wcslen(DEFAULT_DATAFILE) + 1)*sizeof(wchar_t)); + wcscpy(DataFileName,DEFAULT_DATAFILE); } /* Is DataFileName relative or absolute ? */ - if( (DataFileName[0] != '\\') && (strncmp(DataFileName+1, ":\\", 2)!=0) ) { + if( (DataFileName[0] != L'\\') && (wcsncmp(DataFileName+1, L":\\", 2)!=0) ) { /* Relative name, we have to prepend RelDir to it. */ if( !RelDir ) { exit_help("Need -reldir when -data filename has relative path."); } else { - newname = (char *)malloc(strlen(DataFileName)+strlen(RelDir)+2); + size = (wcslen(DataFileName)+wcslen(RelDir)+2); + newname = (wchar_t *)malloc(size*sizeof(wchar_t)); assert(newname); - sprintf(newname, "%s\\%s", RelDir, DataFileName); + swprintf(newname, size, L"%s\\%s", RelDir, DataFileName); free(DataFileName); DataFileName=newname; } } #ifdef _DEBUG - fprintf(stderr, "DataFileName: '%s'\n", DataFileName); + fprintf(stderr, "DataFileName: '%S'\n", DataFileName); #endif - if( (fp=fopen(DataFileName, "rb")) == NULL) { + if( (fp=_wfopen(DataFileName, L"rb")) == NULL) { exit_help("Cannot find the datafile."); } @@ -314,21 +317,33 @@ void read_datafile(void) size=ftell(fp); fseek(fp, 0, SEEK_SET); - Version = (char *)malloc(size+1); - Release = (char *)malloc(size+1); - assert(Version); - assert(Release); + ver = (char *)malloc(size+1); + rel = (char *)malloc(size+1); + assert(ver); + assert(rel); - if( (fscanf(fp, "%s %s", Version, Release)) == 0) { + if( (fscanf(fp, "%s %s", ver, rel)) == 0) { fclose(fp); exit_help("Format error in datafile."); } fclose(fp); + size = MultiByteToWideChar(CP_UTF8, 0, ver, -1, NULL, 0); + Version = malloc(size*sizeof(wchar_t)); + assert(Version); + MultiByteToWideChar(CP_UTF8, 0, ver, -1, Version, size); + free(ver); + + size = MultiByteToWideChar(CP_UTF8, 0, rel, -1, NULL, 0); + Release = malloc(size*sizeof(wchar_t)); + assert(Release); + MultiByteToWideChar(CP_UTF8, 0, rel, -1, Release, size); + free(rel); + #ifdef _DEBUG - fprintf(stderr, "DataFile version: '%s'\n", Version); - fprintf(stderr, "DataFile release: '%s'\n", Release); + fprintf(stderr, "DataFile version: '%S'\n", Version); + fprintf(stderr, "DataFile release: '%S'\n", Release); #endif } @@ -340,31 +355,33 @@ void read_bootflags(void) { FILE *fp; long fsize; - char *newname; - + wchar_t *newname; + char *bootf; + if(BootFlagsFile) { /* Is BootFlagsFile relative or absolute ? */ - if( (BootFlagsFile[0] != '\\') && - (strncmp(BootFlagsFile+1, ":\\", 2)!=0) ) { + if( (BootFlagsFile[0] != L'\\') && + (wcsncmp(BootFlagsFile+1, L":\\", 2)!=0) ) { /* Relative name, we have to prepend RelDir\\Version to it. */ if( !RelDir ) { exit_help("Need -reldir when -bootflags " "filename has relative path."); } else { - newname = (char *)malloc(strlen(BootFlagsFile)+ - strlen(RelDir)+strlen(Release)+3); + int len = wcslen(BootFlagsFile)+ + wcslen(RelDir)+wcslen(Release)+3; + newname = (wchar_t *)malloc(len*sizeof(wchar_t)); assert(newname); - sprintf(newname, "%s\\%s\\%s", RelDir, Release, BootFlagsFile); + swprintf(newname, len, L"%s\\%s\\%s", RelDir, Release, BootFlagsFile); free(BootFlagsFile); BootFlagsFile=newname; } } #ifdef _DEBUG - fprintf(stderr, "BootFlagsFile: '%s'\n", BootFlagsFile); + fprintf(stderr, "BootFlagsFile: '%S'\n", BootFlagsFile); #endif - if( (fp=fopen(BootFlagsFile, "rb")) == NULL) { + if( (fp=_wfopen(BootFlagsFile, L"rb")) == NULL) { exit_help("Could not open BootFlags file."); } @@ -372,80 +389,86 @@ void read_bootflags(void) fsize=ftell(fp); fseek(fp, 0, SEEK_SET); - BootFlags = (char *)malloc(fsize+1); - assert(BootFlags); - if( (fgets(BootFlags, fsize+1, fp)) == NULL) { + bootf = (char *)malloc(fsize+1); + assert(bootf); + if( (fgets(bootf, fsize+1, fp)) == NULL) { exit_help("Error while reading BootFlags file"); } fclose(fp); /* Adjust buffer size */ - BootFlags = (char *)realloc(BootFlags, strlen(BootFlags)+1); - assert(BootFlags); + bootf = (char *)realloc(bootf, strlen(bootf)+1); + assert(bootf); /* Strip \r\n from BootFlags */ - fsize = strlen(BootFlags); + fsize = strlen(bootf); while( fsize > 0 && - ( (BootFlags[fsize-1] == '\r') || - (BootFlags[fsize-1] == '\n') ) ) { - BootFlags[--fsize]=0; + ( (bootf[fsize-1] == '\r') || + (bootf[fsize-1] == '\n') ) ) { + bootf[--fsize]=0; } - + fsize = MultiByteToWideChar(CP_UTF8, 0, bootf, -1, NULL, 0); + BootFlags = malloc(fsize*sizeof(wchar_t)); + assert(BootFlags); + MultiByteToWideChar(CP_UTF8, 0, bootf, -1, BootFlags, fsize); + free(bootf); } else { /* Set empty BootFlags */ - BootFlags = ""; + BootFlags = L""; } #ifdef _DEBUG - fprintf(stderr, "BootFlags: '%s'\n", BootFlags); + fprintf(stderr, "BootFlags: '%S'\n", BootFlags); #endif } long start_new_node(void) { - char *CommandLine; + wchar_t *CommandLine; unsigned long i; - STARTUPINFO si; - DWORD dwExitCode; + STARTUPINFOW si; + DWORD dwExitCode; - i = strlen(RelDir) + strlen(Release) + 4; - VsnDir = (char *)malloc(i); + i = wcslen(RelDir) + wcslen(Release) + 4; + VsnDir = (wchar_t *)malloc(i*sizeof(wchar_t)); assert(VsnDir); - sprintf(VsnDir, "%s\\%s", RelDir, Release); + swprintf(VsnDir, i, L"%s\\%s", RelDir, Release); if( NoConfig ) { - i = strlen(BinDir) + strlen(ErlCommandLine) + - strlen(BootFlags) + 64; - CommandLine = (char *)malloc(i); + i = wcslen(BinDir) + wcslen(ErlCommandLine) + + wcslen(BootFlags) + 64; + CommandLine = (wchar_t *)malloc(i*sizeof(wchar_t)); assert(CommandLine); - sprintf(CommandLine, - "\"%s\\erl.exe\" -boot \"%s\\start\" %s %s", - BinDir, - VsnDir, - ErlCommandLine, - BootFlags); + swprintf(CommandLine, + i, + L"\"%s\\erl.exe\" -boot \"%s\\start\" %s %s", + BinDir, + VsnDir, + ErlCommandLine, + BootFlags); } else { - i = strlen(BinDir) + strlen(ErlCommandLine) - + strlen(BootFlags) + strlen(VsnDir)*2 + 64; - CommandLine = (char *)malloc(i); + i = wcslen(BinDir) + wcslen(ErlCommandLine) + + wcslen(BootFlags) + wcslen(VsnDir)*2 + 64; + CommandLine = (wchar_t *)malloc(i*sizeof(wchar_t)); assert(CommandLine); - sprintf(CommandLine, - "\"%s\\erl.exe\" -boot \"%s\\start\" -config \"%s\\sys\" %s %s", - BinDir, - VsnDir, - VsnDir, - ErlCommandLine, - BootFlags); + swprintf(CommandLine, + i, + L"\"%s\\erl.exe\" -boot \"%s\\start\" -config \"%s\\sys\" %s %s", + BinDir, + VsnDir, + VsnDir, + ErlCommandLine, + BootFlags); } #ifdef _DEBUG - fprintf(stderr, "CommandLine: '%s'\n", CommandLine); + fprintf(stderr, "CommandLine: '%S'\n", CommandLine); #endif /* Initialize the STARTUPINFO structure. */ - memset(&si, 0, sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); + memset(&si, 0, sizeof(STARTUPINFOW)); + si.cb = sizeof(STARTUPINFOW); si.lpTitle = NULL; si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); @@ -453,19 +476,19 @@ long start_new_node(void) si.hStdError = GetStdHandle(STD_ERROR_HANDLE); /* Create the new Erlang process */ - if( (CreateProcess( - NULL, /* pointer to name of executable module */ - CommandLine, /* pointer to command line string */ - NULL, /* pointer to process security attributes */ - NULL, /* pointer to thread security attributes */ - TRUE, /* handle inheritance flag */ - GetPriorityClass(GetCurrentProcess()), - /* creation flags */ - NULL, /* pointer to new environment block */ - BinDir,/* pointer to current directory name */ - &si, /* pointer to STARTUPINFO */ - &ErlProcessInfo /* pointer to PROCESS_INFORMATION */ - )) == FALSE) { + if( (CreateProcessW( + NULL, /* pointer to name of executable module */ + CommandLine, /* pointer to command line string */ + NULL, /* pointer to process security attributes */ + NULL, /* pointer to thread security attributes */ + TRUE, /* handle inheritance flag */ + GetPriorityClass(GetCurrentProcess()), + /* creation flags */ + NULL, /* pointer to new environment block */ + BinDir,/* pointer to current directory name */ + &si, /* pointer to STARTUPINFO */ + &ErlProcessInfo /* pointer to PROCESS_INFORMATION */ + )) == FALSE) { ShowLastError(); exit_help("Failed to start new node"); } @@ -504,6 +527,7 @@ long start_new_node(void) */ void complete_options(void) { + int len; /* Try to find a descent RelDir */ if( !RelDir ) { DWORD sz = 32; @@ -511,15 +535,13 @@ void complete_options(void) DWORD nsz; if (RelDir) free(RelDir); - RelDir = malloc(sz); + RelDir = malloc(sz*sizeof(wchar_t)); if (!RelDir) { fprintf(stderr, "** Error : failed to allocate memory\n"); exit(1); } SetLastError(0); - nsz = GetEnvironmentVariable((LPCTSTR) "RELDIR", - (LPTSTR) RelDir, - sz); + nsz = GetEnvironmentVariableW(L"RELDIR", RelDir, sz); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { free(RelDir); RelDir = NULL; @@ -536,9 +558,10 @@ void complete_options(void) exit_help("Need either Root directory nor Release directory."); } /* Ok, construct our own RelDir from RootDir */ - RelDir = (char *) malloc(strlen(RootDir)+strlen(RELEASE_SUBDIR)+1); + sz = wcslen(RootDir)+wcslen(RELEASE_SUBDIR)+1; + RelDir = (wchar_t *) malloc(sz * sizeof(wchar_t)); assert(RelDir); - sprintf(RelDir, "%s" RELEASE_SUBDIR, RootDir); + swprintf(RelDir, sz, L"%s" RELEASE_SUBDIR, RootDir); read_datafile(); } else { read_datafile(); @@ -548,32 +571,32 @@ void complete_options(void) } if( !RootDir ) { /* Try to construct RootDir from RelDir */ - char *p; - RootDir = malloc(strlen(RelDir)+1); - strcpy(RootDir,RelDir); - p = RootDir+strlen(RootDir)-1; - if (p >= RootDir && (*p == '/' || *p == '\\')) + wchar_t *p; + RootDir = malloc((wcslen(RelDir)+1)*sizeof(wchar_t)); + wcscpy(RootDir,RelDir); + p = RootDir+wcslen(RootDir)-1; + if (p >= RootDir && (*p == L'/' || *p == L'\\')) --p; - while (p >= RootDir && *p != '/' && *p != '\\') + while (p >= RootDir && *p != L'/' && *p != L'\\') --p; if (p <= RootDir) { /* Empty RootDir is also an error */ exit_help("Cannot determine Root directory from " "Release directory."); } - *p = '\0'; + *p = L'\0'; } - - BinDir = (char *) malloc(strlen(RootDir)+strlen(ERTS_SUBDIR_PREFIX)+ - strlen(Version)+strlen(BIN_SUBDIR)+1); + len = wcslen(RootDir)+wcslen(ERTS_SUBDIR_PREFIX)+ + wcslen(Version)+wcslen(BIN_SUBDIR)+1; + BinDir = (wchar_t *) malloc(len * sizeof(wchar_t)); assert(BinDir); - sprintf(BinDir, "%s" ERTS_SUBDIR_PREFIX "%s" BIN_SUBDIR, RootDir, Version); + swprintf(BinDir, len, L"%s" ERTS_SUBDIR_PREFIX L"%s" BIN_SUBDIR, RootDir, Version); read_bootflags(); #ifdef _DEBUG - fprintf(stderr, "RelDir: '%s'\n", RelDir); - fprintf(stderr, "BinDir: '%s'\n", BinDir); + fprintf(stderr, "RelDir: '%S'\n", RelDir); + fprintf(stderr, "BinDir: '%S'\n", BinDir); #endif } @@ -598,17 +621,17 @@ BOOL WINAPI LogoffHandlerRoutine( DWORD dwCtrlType ) int main(void) { DWORD dwExitCode; - char *cmdline; + wchar_t *cmdline; /* Make sure a logoff does not distrurb us. */ SetConsoleCtrlHandler(LogoffHandlerRoutine, TRUE); - cmdline = GetCommandLine(); + cmdline = GetCommandLineW(); assert(cmdline); - CommandLineStart = (char *) malloc(strlen(cmdline) + 1); + CommandLineStart = (wchar_t *) malloc((wcslen(cmdline) + 1)*sizeof(wchar_t)); assert(CommandLineStart); - strcpy(CommandLineStart,cmdline); + wcscpy(CommandLineStart,cmdline); split_commandline(); parse_commandline(); diff --git a/erts/etc/win32/win_erlexec.c b/erts/etc/win32/win_erlexec.c index 11cc6a30f7..c622e6eeee 100644 --- a/erts/etc/win32/win_erlexec.c +++ b/erts/etc/win32/win_erlexec.c @@ -62,12 +62,18 @@ static SysGetKeyFunction *sys_get_key_p; static ErlStartFunction *erl_start_p; static SysPrimitiveInitFunction *sys_primitive_init_p; -static HMODULE load_win_beam_dll(char *name) +/* + * To enable debugging of argument processing etc + * #define ARGS_HARDDEBUG 1 + * #define HARDDEBUG 1 + */ + +static HMODULE load_win_beam_dll(wchar_t *name) { HMODULE beam_module; - beam_module=LoadLibrary(name); + beam_module=LoadLibraryW(name); if (beam_module == INVALID_HANDLE_VALUE || beam_module == NULL) { - error("Unable to load emulator DLL\n(%s)",name); + error("Unable to load emulator DLL\n(%S)",name); return NULL; } sys_get_key_p = (SysGetKeyFunction *) @@ -83,9 +89,21 @@ static HMODULE load_win_beam_dll(char *name) #define DLL_ENV "ERL_EMULATOR_DLL" static void -set_env(char *key, char *value) +set_env(char *key, char *value) /* Both in UTF-8 encoding */ { - if (!SetEnvironmentVariable((LPCTSTR) key, (LPCTSTR) value)) + wchar_t *wkey=NULL; + wchar_t *wvalue=NULL; + int keylen; + int valuelen; + + + keylen = MultiByteToWideChar(CP_UTF8, 0, key, -1, NULL, 0); + valuelen = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0); + wkey = malloc(keylen*sizeof(wchar_t)); + wvalue = malloc(valuelen*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, keylen); + MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, valuelen); + if (!SetEnvironmentVariableW( wkey, wvalue)) error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value); } @@ -121,55 +139,97 @@ free_env_val(char *value) int -start_win_emulator(char* emu, char *start_prog, char** argv, int start_detached) +start_win_emulator(char* utf8emu, char *utf8start_prog, char** utf8argv, int start_detached) { - int result; + int len; + int argc = 0; windowed = 1; + while (utf8argv[argc] != NULL) { + ++argc; + } + if (start_detached) { - char *buff; + wchar_t *start_prog=NULL; + int result; + int i; + wchar_t **argv; close(0); close(1); close(2); set_env("ERL_CONSOLE_MODE", "detached"); - set_env(DLL_ENV, emu); + set_env(DLL_ENV, utf8emu); + + utf8argv[0] = utf8start_prog; + utf8argv = fnuttify_argv(utf8argv); - argv[0] = start_prog; - argv = fnuttify_argv(argv); - result = spawnv(_P_DETACH, start_prog, argv); - free_fnuttified(argv); + len = MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, NULL, 0); + start_prog = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, start_prog, len); + + /* Convert utf8argv to multibyte argv */ + argv = malloc((argc+1) * sizeof(wchar_t*)); + for (i=0; i<argc; i++) { + len = MultiByteToWideChar(CP_UTF8, 0, utf8argv[i], -1, NULL, 0); + argv[i] = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8argv[i], -1, argv[i], len); + } + argv[argc] = NULL; + +#ifdef ARGS_HARDDEBUG + { + wchar_t tempbuf[2048] = L""; + wchar_t *sbuf; + int i; + sbuf=tempbuf; + sbuf += swprintf(sbuf, 2048, L"utf16: %s\n", start_prog); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%s|", argv[i]); + }; + sbuf += swprintf(sbuf, 2048, L"\nutf8: \n"); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%S|", utf8argv[i]); + }; + MessageBoxW(NULL, tempbuf, L"respawn args", MB_OK|MB_ICONERROR); + } +#endif + + result = _wspawnv(_P_DETACH, start_prog, argv); + free_fnuttified(utf8argv); + if (result == -1) { + error("Failed to execute %S: %s", start_prog, win32_errorstr(_doserrno)); + } } else { - int argc = 0; + wchar_t *emu=NULL; #ifdef LOAD_BEAM_DYNAMICALLY - HMODULE beam_module = load_win_beam_dll(emu); -#endif - set_env("ERL_CONSOLE_MODE", "window"); - while (argv[argc] != NULL) { - ++argc; - } + HMODULE beam_module = NULL; + len = MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, NULL, 0); + emu = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, emu, len); #ifdef ARGS_HARDDEBUG { char sbuf[2048] = ""; int i; + strcat(sbuf,utf8emu); + strcat(sbuf,":"); for (i = 0; i < argc; ++i) { strcat(sbuf,"|"); - strcat(sbuf, argv[i]); + strcat(sbuf, utf8argv[i]); strcat(sbuf,"| "); } - MessageBox(NULL, sbuf, "Werl", MB_OK|MB_ICONERROR); + MessageBox(NULL, sbuf, "erl_start args", MB_OK|MB_ICONERROR); } #endif + beam_module = load_win_beam_dll(emu); +#endif + set_env("ERL_CONSOLE_MODE", "window"); #ifdef LOAD_BEAM_DYNAMICALLY (*sys_primitive_init_p)(beam_module); - (*erl_start_p)(argc,argv); + (*erl_start_p)(argc,utf8argv); #else - erl_start(argc, argv); + erl_start(argc,utf8argv); #endif - result = 0; - } - if (result == -1) { - error("Failed to execute %s: %s", emu, win32_errorstr(_doserrno)); } return 0; } @@ -186,61 +246,103 @@ do_keep_window(void) } int -start_emulator(char* emu, char *start_prog, char** argv, int start_detached) +start_emulator(char* utf8emu, char *utf8start_prog, char** utf8argv, int start_detached) { - int result; static char console_mode[] = "tty:ccc"; char* fd_type; char* title; + int len; + int argc = 0; #ifdef HARDDEBUG - fprintf(stderr,"emu = %s, start_prog = %s\n",emu, start_prog); + fprintf(stderr,"utf8emu = %s, start_prog = %s\n", utf8emu, utf8start_prog); #endif fd_type = strchr(console_mode, ':'); fd_type++; _flushall(); - + + while (utf8argv[argc] != NULL) { + ++argc; + } + /* * If no console, we will spawn the emulator detached. */ if (start_detached) { - char *buff; + int result; + int i; + wchar_t *start_prog=NULL; + wchar_t **argv; close(0); close(1); close(2); set_env("ERL_CONSOLE_MODE", "detached"); - set_env(DLL_ENV, emu); + set_env(DLL_ENV, utf8emu); + + utf8argv[0] = utf8start_prog; + utf8argv = fnuttify_argv(utf8argv); + + len = MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, NULL, 0); + start_prog = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, start_prog, len); + + /* Convert utf8argv to multibyte argv */ + argv = malloc((argc+1) * sizeof(wchar_t*)); + for (i=0; i<argc; i++) { + len = MultiByteToWideChar(CP_UTF8, 0,utf8argv[i], -1, NULL, 0); + argv[i] = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8argv[i], -1, argv[i], len); + } + argv[argc] = NULL; - argv[0] = start_prog; - argv = fnuttify_argv(argv); #ifdef ARGS_HARDDEBUG { - char buffer[2048]; + wchar_t buffer[2048]; int i; - sprintf(buffer,"Start detached [%s]\n",start_prog); + wsprintfW(buffer,L"Start detached [%s]\n",start_prog); for(i=0;argv[i] != NULL;++i) { - strcat(buffer,"|"); - strcat(buffer,argv[i]); - strcat(buffer,"|\n"); + wcscat(buffer,L"|"); + wcscat(buffer,argv[i]); + wcscat(buffer,L"|\n"); } - MessageBox(NULL, buffer,"Start detached",MB_OK); + MessageBoxW(NULL, buffer, L"Start detached",MB_OK); } -#endif - result = spawnv(_P_DETACH, start_prog, argv); - free_fnuttified(argv); +#endif + result = _wspawnv(_P_DETACH, start_prog, argv); + free_fnuttified(utf8argv); + free(start_prog); + if (result == -1) { #ifdef ARGS_HARDDEBUG - MessageBox(NULL, "_spawnv failed","Start detached",MB_OK); + MessageBox(NULL, "_wspawnv failed","Start detached",MB_OK); #endif return 1; } SetPriorityClass((HANDLE) result, GetPriorityClass(GetCurrentProcess())); } else { - int argc = 0; + wchar_t *emu=NULL; #ifdef LOAD_BEAM_DYNAMICALLY - HMODULE beam_module = load_win_beam_dll(emu); + HMODULE beam_module; + len = MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, NULL, 0); + emu = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, emu, len); +#ifdef ARGS_HARDDEBUG + { + char sbuf[2048] = ""; + int i; + strcat(sbuf,utf8emu); + strcat(sbuf,":"); + for (i = 0; i < argc; ++i) { + strcat(sbuf,"|"); + strcat(sbuf, utf8argv[i]); + strcat(sbuf,"| "); + } + MessageBox(NULL, sbuf, "erl_start args", MB_OK|MB_ICONERROR); + } +#endif + beam_module = load_win_beam_dll(emu); #endif /* @@ -254,9 +356,6 @@ start_emulator(char* emu, char *start_prog, char** argv, int start_detached) free_env_val(title); set_env("ERL_CONSOLE_MODE", console_mode); - while (argv[argc] != NULL) { - ++argc; - } if (keep_window) { atexit(do_keep_window); } @@ -266,17 +365,17 @@ start_emulator(char* emu, char *start_prog, char** argv, int start_detached) int i; for (i = 0; i < argc; ++i) { strcat(sbuf,"|"); - strcat(sbuf, argv[i]); + strcat(sbuf, utf8argv[i]); strcat(sbuf,"|\n"); } - MessageBox(NULL, sbuf, "erl", MB_OK); + MessageBox(NULL, sbuf, "erl_start", MB_OK); } #endif #ifdef LOAD_BEAM_DYNAMICALLY (*sys_primitive_init_p)(beam_module); - (*erl_start_p)(argc,argv); + (*erl_start_p)(argc,utf8argv); #else - erl_start(argc, argv); + erl_start(argc, utf8argv); #endif } return 0; |