aboutsummaryrefslogtreecommitdiffstats
path: root/erts/etc/common
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2013-06-04 12:38:31 +0200
committerDan Gudmundsson <[email protected]>2013-06-04 12:38:31 +0200
commite83fd8f94aba352b6cc055d2b4cfff007911b6d4 (patch)
tree66b22e7e79813d9ec2b0f5a9817a3908682a22ee /erts/etc/common
parente00d6bbbabd7b76c050665fc417e81554a83e341 (diff)
parentee23d4b549618044d4a4f800db839483b359cb9f (diff)
downloadotp-e83fd8f94aba352b6cc055d2b4cfff007911b6d4.tar.gz
otp-e83fd8f94aba352b6cc055d2b4cfff007911b6d4.tar.bz2
otp-e83fd8f94aba352b6cc055d2b4cfff007911b6d4.zip
Merge branch 'dgud/win32_unicode'
* dgud/win32_unicode: erts: Windows, convert erlsrv to use widestring erts: Window start_erl now uses widechars/unicode Quote windows paths with spaces Handle space in paths in test Makefiles erts: Fix windows widestring args and paths in tools erts: Windows, use widechars for all paths during startup OTP-11135
Diffstat (limited to 'erts/etc/common')
-rw-r--r--erts/etc/common/ct_run.c82
-rw-r--r--erts/etc/common/dialyzer.c104
-rw-r--r--erts/etc/common/erlc.c117
-rw-r--r--erts/etc/common/erlexec.c76
-rw-r--r--erts/etc/common/escript.c247
-rw-r--r--erts/etc/common/heart.c117
-rw-r--r--erts/etc/common/typer.c97
7 files changed, 530 insertions, 310 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..add65b87ca 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -114,20 +114,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 +155,32 @@ 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)
{
- char cwd[MAXPATHLEN]; /* Current working directory. */
+#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]);
@@ -194,20 +221,7 @@ main(int argc, char** argv)
/*
* 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.
@@ -520,48 +534,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 +586,7 @@ int my_spawnvp(char **argv)
siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
- if (!CreateProcess(NULL,
+ if (!CreateProcessW(NULL,
make_commandline(argv),
NULL,
NULL,
@@ -709,6 +725,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 +750,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 01134dd718..f72930ea2a 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 ";"
@@ -1173,11 +1173,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;
@@ -1371,53 +1374,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 */
@@ -1428,34 +1427,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;
}
}