diff options
Diffstat (limited to 'erts/etc/common')
| -rw-r--r-- | erts/etc/common/ct_run.c | 82 | ||||
| -rw-r--r-- | erts/etc/common/dialyzer.c | 104 | ||||
| -rw-r--r-- | erts/etc/common/erlc.c | 384 | ||||
| -rw-r--r-- | erts/etc/common/erlexec.c | 76 | ||||
| -rw-r--r-- | erts/etc/common/escript.c | 247 | ||||
| -rw-r--r-- | erts/etc/common/heart.c | 117 | ||||
| -rw-r--r-- | erts/etc/common/typer.c | 97 | 
7 files changed, 548 insertions, 559 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..5ef7df0d8d 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 ";" @@ -1189,11 +1189,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 +1390,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 +1443,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;  	}      }  | 
