aboutsummaryrefslogtreecommitdiffstats
path: root/erts/etc/common
diff options
context:
space:
mode:
Diffstat (limited to 'erts/etc/common')
-rw-r--r--erts/etc/common/Makefile21
-rw-r--r--erts/etc/common/Makefile.in95
-rw-r--r--erts/etc/common/ct_run.c109
-rw-r--r--erts/etc/common/dialyzer.c125
-rw-r--r--erts/etc/common/erlc.c403
-rw-r--r--erts/etc/common/erlexec.c192
-rw-r--r--erts/etc/common/escript.c266
-rw-r--r--erts/etc/common/heart.c179
-rw-r--r--erts/etc/common/inet_gethost.c21
-rw-r--r--erts/etc/common/typer.c118
10 files changed, 804 insertions, 725 deletions
diff --git a/erts/etc/common/Makefile b/erts/etc/common/Makefile
index 73ab79d145..bbf51d0efd 100644
--- a/erts/etc/common/Makefile
+++ b/erts/etc/common/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 1997-2009. 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
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in
index 5c1ce51644..05d925f19f 100644
--- a/erts/etc/common/Makefile.in
+++ b/erts/etc/common/Makefile.in
@@ -1,18 +1,19 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2012. All Rights Reserved.
+# Copyright Ericsson AB 1996-2014. 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
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
#
# %CopyrightEnd%
#
@@ -62,7 +63,9 @@ LIBS = @LIBS@
LDFLAGS = @LDFLAGS@
# For clock_gettime in heart
+ifneq ($(TARGET),arm-unknown-linux-androideabi)
RTLIBS = @LIBRT@
+endif
ifeq ($(TARGET),win32)
ifeq ($(TYPE),debug)
@@ -78,10 +81,15 @@ EMUOSDIR = $(ERL_TOP)/erts/emulator/@ERLANG_OSTYPE@
SYSDIR = $(ERL_TOP)/erts/emulator/sys/@ERLANG_OSTYPE@
DRVDIR = $(ERL_TOP)/erts/emulator/drivers/@ERLANG_OSTYPE@
UXETC = ../unix
-OSEETC = ../ose
WINETC = ../win32
ifeq ($(TARGET), win32)
+ETC = $(WINETC)
+else
+ETC = $(UXETC)
+endif
+
+ifeq ($(TARGET), win32)
ERLEXEC = erlexec.dll
else
ERLEXEC = erlexec
@@ -147,7 +155,8 @@ INSTALL_TOP_BIN = $(BINDIR)/Install.exe
INSTALL_PROGS = \
$(INET_GETHOST) \
$(BINDIR)/heart.exe $(BINDIR)/erlsrv.exe \
- $(BINDIR)/erl.exe $(BINDIR)/werl.exe \
+ $(BINDIR)/erl.exe $(BINDIR)/erl_log.exe \
+ $(BINDIR)/werl.exe \
$(BINDIR)/$(ERLEXEC) \
$(INSTALL_EMBEDDED_PROGS)
@@ -161,7 +170,7 @@ endif
PORT_ENTRY_POINT=erl_port_entry
ENTRY_LDFLAGS=-entry:$(PORT_ENTRY_POINT)
-else # UNIX (!win32)
+else
ENTRY_LDFLAGS=
ENTRY_OBJ=
ERLSRV_OBJECTS=
@@ -170,11 +179,11 @@ INET_GETHOST = $(BINDIR)/inet_gethost@EXEEXT@
INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer@EXEEXT@ $(BINDIR)/dialyzer@EXEEXT@ \
$(BINDIR)/erlc@EXEEXT@ $(BINDIR)/escript@EXEEXT@ $(BINDIR)/ct_run@EXEEXT@ \
$(BINDIR)/run_erl $(BINDIR)/to_erl $(BINDIR)/dyn_erl
-INSTALL_EMBEDDED_DATA = ../unix/start.src ../unix/start_erl.src
+INSTALL_EMBEDDED_DATA = $(UXETC)/start.src $(UXETC)/start_erl.src
INSTALL_TOP = Install
INSTALL_TOP_BIN =
-INSTALL_MISC = ../unix/format_man_pages ../unix/makewhatis
-INSTALL_SRC = ../unix/setuid_socket_wrap.c #delivered as an example
+INSTALL_MISC = $(UXETC)/format_man_pages $(UXETC)/makewhatis
+INSTALL_SRC = $(UXETC)/setuid_socket_wrap.c #delivered as an example
ERLEXECDIR = .
INSTALL_LIBS =
INSTALL_OBJS =
@@ -230,11 +239,14 @@ endif
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_erl.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/to_erl.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/dyn_erl.o
- rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/safe_string.o
+ rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/safe_string.o
+ rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_erl.o
+ rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/to_erl.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/typer.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/ct_run.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/vxcall.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/erl.o
+ rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/erl_log.o
rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/werl.o
rm -f $(TEXTFILES)
rm -f *~ core
@@ -258,6 +270,9 @@ $(BINDIR)/erl@EXEEXT@: $(OBJDIR)/erl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_
$(BINDIR)/werl@EXEEXT@: $(OBJDIR)/werl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ)
$(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/werl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ)
+$(BINDIR)/erl_log@EXEEXT@: $(OBJDIR)/erl_log.o
+ $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/erl_log.o
+
$(BINDIR)/start_erl@EXEEXT@: $(OBJDIR)/start_erl.o
$(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/start_erl.o
@@ -311,6 +326,10 @@ $(OBJDIR)/werl.o: $(WINETC)/erl.c $(WINETC)/init_file.h $(RC_GENERATED)
$(V_CC) $(CFLAGS) -DBUILD_TYPE=\"-$(TYPE)\" -DERL_RUN_SHARED_LIB=1 \
-DWIN32_WERL -o $@ -c $(WINETC)/erl.c
+$(OBJDIR)/erl_log.o: $(WINETC)/erl_log.c $(RC_GENERATED)
+ $(V_CC) $(CFLAGS) -DBUILD_TYPE=\"-$(TYPE)\" -DERL_RUN_SHARED_LIB=1 \
+ -o $@ -c $(WINETC)/erl_log.c
+
$(OBJDIR)/erl.o: $(WINETC)/erl.c $(WINETC)/init_file.h $(RC_GENERATED)
$(V_CC) $(CFLAGS) -DBUILD_TYPE=\"-$(TYPE)\" -DERL_RUN_SHARED_LIB=1 \
-o $@ -c $(WINETC)/erl.c
@@ -370,29 +389,29 @@ $(OBJDIR)/heart.o: heart.c $(RC_GENERATED)
$(OBJDIR)/inet_gethost.o: inet_gethost.c $(RC_GENERATED)
$(V_CC) $(CFLAGS) -o $@ -c inet_gethost.c
+# inet_gethost
$(BINDIR)/inet_gethost@EXEEXT@: $(OBJDIR)/inet_gethost.o $(ENTRY_OBJ) $(ERTS_LIB)
$(ld_verbose)$(PURIFY) $(LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(OBJDIR)/inet_gethost.o $(ENTRY_OBJ) $(LIBS) $(ERTS_INTERNAL_LIBS)
+# run_erl
$(BINDIR)/run_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o
$(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o $(LIBS)
+$(OBJDIR)/run_erl.o: $(ETC)/run_erl.c $(RC_GENERATED)
+ $(V_CC) $(CFLAGS) -o $@ -c $(ETC)/run_erl.c
-$(OBJDIR)/run_erl.o: ../unix/run_erl.c $(RC_GENERATED)
- $(V_CC) $(CFLAGS) -o $@ -c ../unix/run_erl.c
-
+# to_erl
$(BINDIR)/to_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o
$(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o
+$(OBJDIR)/to_erl.o: $(ETC)/to_erl.c $(RC_GENERATED)
+ $(V_CC) $(CFLAGS) -o $@ -c $(ETC)/to_erl.c
-$(OBJDIR)/to_erl.o: ../unix/to_erl.c $(RC_GENERATED)
- $(V_CC) $(CFLAGS) -o $@ -c ../unix/to_erl.c
-
+# dyn_erl
$(BINDIR)/dyn_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o
$(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o
-
-$(OBJDIR)/dyn_erl.o: ../unix/dyn_erl.c $(RC_GENERATED)
- $(V_CC) $(CFLAGS) -o $@ -c ../unix/dyn_erl.c
-
-$(OBJDIR)/safe_string.o: ../unix/safe_string.c $(RC_GENERATED)
- $(V_CC) $(CFLAGS) -o $@ -c ../unix/safe_string.c
+$(OBJDIR)/dyn_erl.o: $(UXETC)/dyn_erl.c $(RC_GENERATED)
+ $(V_CC) $(CFLAGS) -o $@ -c $(UXETC)/dyn_erl.c
+$(OBJDIR)/safe_string.o: $(ETC)/safe_string.c $(RC_GENERATED)
+ $(V_CC) $(CFLAGS) -o $@ -c $(ETC)/safe_string.c
ifneq ($(TARGET),win32)
$(BINDIR)/$(ERLEXEC): $(OBJDIR)/$(ERLEXEC).o $(ERTS_LIB)
@@ -401,6 +420,7 @@ $(BINDIR)/$(ERLEXEC): $(OBJDIR)/$(ERLEXEC).o $(ERTS_LIB)
$(OBJDIR)/$(ERLEXEC).o: $(ERLEXECDIR)/$(ERLEXEC).c $(RC_GENERATED)
$(V_CC) -I$(EMUDIR) $(CFLAGS) -o $@ -c $(ERLEXECDIR)/$(ERLEXEC).c
endif
+
$(BINDIR)/erlc@EXEEXT@: $(OBJDIR)/erlc.o $(ERTS_LIB)
$(ld_verbose)$(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/erlc.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS)
@@ -433,18 +453,18 @@ $(OBJDIR)/ct_run.o: ct_run.c $(RC_GENERATED)
-Install: ../unix/Install.src ../../vsn.mk $(TARGET)/Makefile
+Install: $(UXETC)/Install.src ../../vsn.mk $(TARGET)/Makefile
$(vsn_verbose)sed -e 's;%I_VSN%;$(VSN);' \
-e 's;%EMULATOR%;$(EMULATOR);' \
-e 's;%EMULATOR_NUMBER%;$(EMULATOR_NUMBER);' \
-e 's;%I_SYSTEM_VSN%;$(SYSTEM_VSN);' \
- ../unix/Install.src > Install
+ $(UXETC)/Install.src > Install
-erl.src: ../unix/erl.src.src ../../vsn.mk $(TARGET)/Makefile
+erl.src: $(UXETC)/erl.src.src ../../vsn.mk $(TARGET)/Makefile
$(vsn_verbose)sed -e 's;%EMULATOR%;$(EMULATOR);' \
-e 's;%EMULATOR_NUMBER%;$(EMULATOR_NUMBER);' \
-e 's;%VSN%;$(VSN);' \
- ../unix/erl.src.src > erl.src
+ $(UXETC)/erl.src.src > erl.src
# ----------------------------------------------------
# Release Target
@@ -460,11 +480,9 @@ endif
$(INSTALL_DIR) "$(RELEASE_PATH)/erts-$(VSN)/bin"
ifneq ($(TARGET), win32)
ifneq ($(findstring vxworks,$(TARGET)), vxworks)
-ifneq ($(findstring ose,$(TARGET)), ose)
$(INSTALL_SCRIPT) erl.src "$(RELEASE_PATH)/erts-$(VSN)/bin"
endif
endif
-endif
ifneq ($(INSTALL_PROGS),)
$(INSTALL_PROGRAM) $(INSTALL_PROGS) "$(RELEASE_PATH)/erts-$(VSN)/bin"
endif
@@ -478,17 +496,12 @@ ifneq ($(INSTALL_MISC),)
$(INSTALL_DIR) "$(RELEASE_PATH)/misc"
$(INSTALL_SCRIPT) $(INSTALL_MISC) "$(RELEASE_PATH)/misc"
endif
-ifneq ($(INSTALL_ERL_OSE),)
- $(INSTALL_DIR) "$(RELEASE_PATH)/build_erl_ose"
- cd $(OSEETC) && $(TAR) erl_ose_$(SYSTEM_VSN).tar $(INSTALL_ERL_OSE)
- cd $(OSEETC) && $(INSTALL_SCRIPT) erl_ose_$(SYSTEM_VSN).tar "$(RELEASE_PATH)/build_erl_ose"
-endif
ifneq ($(INSTALL_SRC),)
$(INSTALL_DIR) "$(RELEASE_PATH)/erts-$(VSN)/src"
$(INSTALL_DATA) $(INSTALL_SRC) "$(RELEASE_PATH)/erts-$(VSN)/src"
endif
ifneq ($(INSTALL_EMBEDDED_DATA),)
- $(INSTALL_DATA) $(INSTALL_EMBEDDED_DATA) "$(RELEASE_PATH)/erts-$(VSN)/bin"
+ $(INSTALL_SCRIPT) $(INSTALL_EMBEDDED_DATA) "$(RELEASE_PATH)/erts-$(VSN)/bin"
endif
ifneq ($(INSTALL_LIBS),)
$(INSTALL_DATA) $(INSTALL_LIBS) "$(RELEASE_PATH)/erts-$(VSN)/bin"
diff --git a/erts/etc/common/ct_run.c b/erts/etc/common/ct_run.c
index 5e5b612a12..548514ee6c 100644
--- a/erts/etc/common/ct_run.c
+++ b/erts/etc/common/ct_run.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2010-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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -117,9 +118,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 +135,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]);
@@ -220,7 +240,7 @@ main(int argc, char** argv)
*/
if (ct_mode == VTS_MODE) {
- PUSH4("-s", "webtool", "script_start", "vts");
+ PUSH4("-s", "ct_webtool", "script_start", "vts");
if (browser[0] != '\0') PUSH(browser);
PUSH3("-s", "ct_run", "script_start");
}
@@ -295,48 +315,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 +367,7 @@ int my_spawnvp(char **argv)
siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
- if (!CreateProcess(NULL,
+ if (!CreateProcessW(NULL,
make_commandline(argv),
NULL,
NULL,
@@ -432,16 +454,16 @@ strsave(char* string)
return p;
}
-/* Instead of making sure basename exists, we do our own */
-static char *simple_basename(char *path)
+static int
+file_exists(char *progname)
{
- char *ptr;
- for (ptr = path; *ptr != '\0'; ++ptr) {
- if (*ptr == '/' || *ptr == '\\') {
- path = ptr + 1;
- }
- }
- return path;
+#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*
@@ -457,15 +479,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..c45626606c 100644
--- a/erts/etc/common/dialyzer.c
+++ b/erts/etc/common/dialyzer.c
@@ -1,18 +1,19 @@
/*
* %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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -104,20 +105,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 +146,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 +161,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 +289,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 +343,7 @@ int my_spawnvp(char **argv)
siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
- if (!CreateProcess(NULL,
+ if (!CreateProcessW(NULL,
make_commandline(argv),
NULL,
NULL,
@@ -398,6 +430,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 +455,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..f9d909e01c 100644
--- a/erts/etc/common/erlc.c
+++ b/erts/etc/common/erlc.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1997-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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -60,7 +61,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 +71,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 +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)
- 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 +154,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]);
@@ -191,176 +217,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 +272,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");
+ PUSH(argv[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);
- }
- 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 +351,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 +403,7 @@ int my_spawnvp(char **argv)
siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
- if (!CreateProcess(NULL,
+ if (!CreateProcessW(NULL,
make_commandline(argv),
NULL,
NULL,
@@ -633,53 +466,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 +495,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 +520,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 9d674a7c65..54da59e50d 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -3,16 +3,17 @@
*
* 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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -42,7 +43,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 ";"
@@ -64,7 +65,7 @@
static const char plusM_au_allocs[]= {
'u', /* all alloc_util allocators */
'B', /* binary_alloc */
- 'C', /* sbmbc_alloc */
+ 'I', /* literal_alloc */
'D', /* std_alloc */
'E', /* ets_alloc */
'F', /* fix_alloc */
@@ -73,6 +74,7 @@ static const char plusM_au_allocs[]= {
'R', /* driver_alloc */
'S', /* sl_alloc */
'T', /* temp_alloc */
+ 'Z', /* test_alloc */
'\0'
};
@@ -80,6 +82,7 @@ static const char plusM_au_allocs[]= {
static char *plusM_au_alloc_switches[] = {
"as",
"asbcst",
+ "acul",
"e",
"t",
"lmbcs",
@@ -95,8 +98,6 @@ static char *plusM_au_alloc_switches[] = {
"rsbcst",
"sbct",
"smbcs",
- "sbmbcs",
- "sbmbct",
NULL
};
@@ -105,16 +106,23 @@ static char *plusM_other_switches[] = {
"ea",
"ummc",
"uycs",
+ "usac",
"im",
"is",
"it",
+ "lpm",
"Mamcbf",
"Mrmcbf",
"Mmcs",
+ "Mscs",
+ "Mscrfsd",
+ "Msco",
+ "Mscrpm",
"Ye",
"Ym",
"Ytp",
"Ytt",
+ "Iscs",
NULL
};
@@ -124,17 +132,22 @@ static char *pluss_val_switches[] = {
"bwt",
"cl",
"ct",
+ "ecio",
+ "fwi",
"tbt",
+ "wct",
"wt",
"ws",
"ss",
"pp",
+ "ub",
NULL
};
/* +h arguments with values */
static char *plush_val_switches[] = {
"ms",
"mbs",
+ "pds",
"",
NULL
};
@@ -145,9 +158,17 @@ static char *plusr_val_switches[] = {
NULL
};
+/* +x arguments with values */
+static char *plusx_val_switches[] = {
+ "mqd",
+ NULL
+};
+
/* +z arguments with values */
static char *plusz_val_switches[] = {
"dbbl",
+ "dntgc",
+ "ebwt",
NULL
};
@@ -706,7 +727,7 @@ int main(int argc, char **argv)
* on itself here. We'll avoid doing that.
*/
if (strcmp(argv[i], "-make") == 0) {
- add_args("-noshell", "-noinput", "-s", "make", "all", NULL);
+ add_args("-noshell", "-noinput", "-s", "make", "all_or_nothing", NULL);
add_Eargs("-B");
haltAfterwards = 1;
i = argc; /* Skip rest of command line */
@@ -799,11 +820,12 @@ int main(int argc, char **argv)
case 'a':
case 'A':
case 'b':
+ case 'C':
+ case 'e':
case 'i':
case 'n':
case 'P':
case 'Q':
- case 'S':
case 't':
case 'T':
case 'R':
@@ -818,6 +840,33 @@ int main(int argc, char **argv)
add_Eargs(argv[i+1]);
i++;
break;
+ case 'S':
+ if (argv[i][2] == 'P') {
+ if (argv[i][3] != '\0')
+ goto the_default;
+ }
+#ifdef ERTS_DIRTY_SCHEDULERS
+ else if (argv[i][2] == 'D') {
+ char* type = argv[i]+3;
+ if (strncmp(type, "cpu", 3) != 0 &&
+ strncmp(type, "Pcpu", 4) != 0 &&
+ strncmp(type, "io", 2) != 0)
+ usage(argv[i]);
+ if ((argv[i][3] == 'c' && argv[i][6] != '\0') ||
+ (argv[i][3] == 'P' && argv[i][7] != '\0') ||
+ (argv[i][3] == 'i' && argv[i][5] != '\0'))
+ goto the_default;
+ }
+#endif
+ else if (argv[i][2] != '\0')
+ goto the_default;
+ if (i+1 >= argc)
+ usage(argv[i]);
+ argv[i][0] = '-';
+ add_Eargs(argv[i]);
+ add_Eargs(argv[i+1]);
+ i++;
+ break;
case 'B':
argv[i][0] = '-';
if (argv[i][2] != '\0') {
@@ -845,6 +894,19 @@ int main(int argc, char **argv)
}
add_Eargs(argv[i]);
break;
+ case 'c':
+ argv[i][0] = '-';
+ if (argv[i][2] == '\0' && i+1 < argc) {
+ if (sys_strcmp(argv[i+1], "true") == 0
+ || sys_strcmp(argv[i+1], "false") == 0) {
+ add_Eargs(argv[i]);
+ add_Eargs(argv[i+1]);
+ i++;
+ break;
+ }
+ }
+ add_Eargs(argv[i]);
+ break;
case 'M': {
int x;
for (x = 0; plusM_au_allocs[x]; x++)
@@ -922,6 +984,20 @@ int main(int argc, char **argv)
add_Eargs(argv[i+1]);
i++;
break;
+ case 'x':
+ if (!is_one_of_strings(&argv[i][2], plusx_val_switches)) {
+ goto the_default;
+ } else {
+ if (i+1 >= argc
+ || argv[i+1][0] == '-'
+ || argv[i+1][0] == '+')
+ usage(argv[i]);
+ argv[i][0] = '-';
+ add_Eargs(argv[i]);
+ add_Eargs(argv[i+1]);
+ i++;
+ }
+ break;
case 'z':
if (!is_one_of_strings(&argv[i][2], plusz_val_switches)) {
goto the_default;
@@ -1114,13 +1190,15 @@ usage_aux(void)
#endif
"] "
"[-make] [-man [manopts] MANPAGE] [-x] [-emu_args] "
- "[-args_file FILENAME] [+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] "
- "[+h HEAP_SIZE_OPTION] [+K BOOLEAN] "
+ "[-args_file FILENAME] [+A THREADS] [+a SIZE] [+B[c|d|i]] [+c [BOOLEAN]] "
+ "[+C MODE] [+h HEAP_SIZE_OPTION] [+K BOOLEAN] "
"[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+Q MAX_PORTS] "
"[+R COMPAT_REL] "
"[+r] [+rg READER_GROUPS_LIMIT] [+s SCHEDULER_OPTION] "
- "[+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] [+T LEVEL] [+V] [+v] "
- "[+W<i|w>] [+z MISC_OPTION] [args ...]\n");
+ "[+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] "
+ "[+SP PERCENTAGE_SCHEDULERS:PERCENTAGE_SCHEDULERS_ONLINE] "
+ "[+T LEVEL] [+V] [+v] "
+ "[+W<i|w|e>] [+x DEFAULT_PROC_FLAGS] [+z MISC_OPTION] [args ...]\n");
exit(1);
}
@@ -1174,11 +1252,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;
@@ -1372,53 +1453,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 */
@@ -1429,34 +1506,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 */
@@ -1968,7 +2046,7 @@ initial_argv_massage(int *argc, char ***argv)
vix = 0;
- av = build_args_from_env("ERL_" OTP_SYSTEM_VERSION "_FLAGS");
+ av = build_args_from_env("ERL_OTP" OTP_SYSTEM_VERSION "_FLAGS");
if (av)
avv[vix++].argv = av;
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 118bc6ef90..7fd02ed436 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2007-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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -45,7 +46,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 +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)
- 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 +158,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 +263,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 +284,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 +304,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 +317,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 +395,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 +413,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 +505,8 @@ main(int argc, char** argv)
#endif
erts_snprintf(scriptname, sizeof(scriptname), "%s.escript",
- absname);
+ absname);
efree(absname);
-
}
/*
@@ -483,63 +575,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 +717,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 +742,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..1a826221fb 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -1,18 +1,19 @@
/*
* %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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -109,7 +110,7 @@
# include <sys/time.h>
# include <unistd.h>
# include <signal.h>
-# if defined(CORRECT_USING_TIMES)
+# if defined(OS_MONOTONIC_TIME_USING_TIMES)
# include <sys/times.h>
# include <limits.h>
# endif
@@ -117,11 +118,12 @@
#define HEART_COMMAND_ENV "HEART_COMMAND"
#define ERL_CRASH_DUMP_SECONDS_ENV "ERL_CRASH_DUMP_SECONDS"
+#define HEART_KILL_SIGNAL "HEART_KILL_SIGNAL"
-#define MSG_HDR_SIZE 2
-#define MSG_HDR_PLUS_OP_SIZE 3
-#define MSG_BODY_SIZE 2048
-#define MSG_TOTAL_SIZE 2050
+#define MSG_HDR_SIZE (2)
+#define MSG_HDR_PLUS_OP_SIZE (3)
+#define MSG_BODY_SIZE (2048)
+#define MSG_TOTAL_SIZE (2050)
unsigned char cmd[MSG_BODY_SIZE];
@@ -201,7 +203,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 +240,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
@@ -456,10 +472,6 @@ message_loop(erlin_fd, erlout_fd)
switch (mp->op) {
case HEART_BEAT:
timestamp(&last_received);
-#ifdef USE_WATCHDOG
- /* reset the hardware watchdog timer */
- wd_reset();
-#endif
break;
case SHUT_DOWN:
return R_SHUT_DOWN;
@@ -541,14 +553,22 @@ kill_old_erlang(void){
static void
kill_old_erlang(void){
pid_t pid;
- int i;
- int res;
+ int i, res;
+ int sig = SIGKILL;
+ char *sigenv = NULL;
+
+ sigenv = get_env(HEART_KILL_SIGNAL);
+ if (sigenv && strcmp(sigenv, "SIGABRT") == 0) {
+ print_error("kill signal SIGABRT requested");
+ sig = SIGABRT;
+ }
+
if(heart_beat_kill_pid != 0){
pid = (pid_t) heart_beat_kill_pid;
- res = kill(pid,SIGKILL);
+ res = kill(pid,sig);
for(i=0; i < 5 && res == 0; ++i){
sleep(1);
- res = kill(pid,SIGKILL);
+ res = kill(pid,sig);
}
if(errno != ESRCH){
print_error("Unable to kill old process, "
@@ -564,13 +584,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 +631,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__) */
@@ -676,14 +714,12 @@ do_terminate(int erlin_fd, int reason) {
print_error("Would reboot. Terminating.");
else {
kill_old_erlang();
- /* suppress gcc warning with 'if' */
ret = system(command);
print_error("Executed \"%s\" -> %d. Terminating.",command, ret);
}
free_env_val(command);
} else {
kill_old_erlang();
- /* suppress gcc warning with 'if' */
ret = system((char*)&cmd[0]);
print_error("Executed \"%s\" -> %d. Terminating.",cmd, ret);
}
@@ -966,16 +1002,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 +1019,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) {
@@ -1071,9 +1088,9 @@ time_t timestamp(time_t *res)
return r;
}
-#elif defined(HAVE_GETHRTIME) || defined(GETHRTIME_WITH_CLOCK_GETTIME)
+#elif defined(OS_MONOTONIC_TIME_USING_GETHRTIME) || defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
-#if defined(GETHRTIME_WITH_CLOCK_GETTIME)
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
typedef long long SysHrTime;
SysHrTime sys_gethrtime(void);
@@ -1082,7 +1099,7 @@ SysHrTime sys_gethrtime(void)
{
struct timespec ts;
long long result;
- if (clock_gettime(CLOCK_MONOTONIC,&ts) != 0) {
+ if (clock_gettime(MONOTONIC_CLOCK_ID,&ts) != 0) {
print_error("Fatal, could not get clock_monotonic value, terminating! "
"errno = %d\n", errno);
exit(1);
@@ -1109,7 +1126,7 @@ time_t timestamp(time_t *res)
return r;
}
-#elif defined(CORRECT_USING_TIMES)
+#elif defined(OS_MONOTONIC_TIME_USING_TIMES)
# ifdef NO_SYSCONF
# include <sys/param.h>
diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c
index bef97862a3..e298c5e7f7 100644
--- a/erts/etc/common/inet_gethost.c
+++ b/erts/etc/common/inet_gethost.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 1998-2012. 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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -1209,7 +1210,7 @@ static void start_que_request(Worker *w)
#endif
}
-#ifndef WIN32
+#ifndef WIN32
/* Signal utilities */
static RETSIGTYPE (*sys_sigset(int sig, RETSIGTYPE (*func)(int)))(int)
{
diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c
index c95959d52d..0aa0996808 100644
--- a/erts/etc/common/typer.c
+++ b/erts/etc/common/typer.c
@@ -3,16 +3,17 @@
*
* Copyright Ericsson AB 2006-2011. 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
- * compliance with the License. You should have received a copy of the
- * Erlang Public License along with this software. If not, it can be
- * retrieved online at http://www.erlang.org/.
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* %CopyrightEnd%
*/
@@ -99,14 +100,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 +213,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 +349,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 +374,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;
}
}