diff options
Diffstat (limited to 'erts/etc')
92 files changed, 4421 insertions, 2788 deletions
diff --git a/erts/etc/Makefile b/erts/etc/Makefile index 2b32b8ae50..788dfff132 100644 --- a/erts/etc/Makefile +++ b/erts/etc/Makefile @@ -1,27 +1,29 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1999-2009. All Rights Reserved. +# Copyright Ericsson AB 1999-2016. 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% # include $(ERL_TOP)/make/target.mk - SUB_DIRECTORIES = common ifeq ($(TARGET),win32) SUB_DIRECTORIES += win32 +else +SUB_DIRECTORIES += unix endif include $(ERL_TOP)/make/otp_subdir.mk diff --git a/erts/etc/common/Makefile b/erts/etc/common/Makefile index 73ab79d145..bad1d3ddb0 100644 --- a/erts/etc/common/Makefile +++ b/erts/etc/common/Makefile @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2009. All Rights Reserved. +# Copyright Ericsson AB 1997-2016. 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..cb053a1b7c 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-2016. 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 853785dcd1..acdfa8c8b8 100644 --- a/erts/etc/common/ct_run.c +++ b/erts/etc/common/ct_run.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2010-2013. All Rights Reserved. + * Copyright Ericsson AB 2010-2016. 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% */ @@ -80,13 +81,14 @@ static int eargc; /* Number of arguments in eargv. */ */ static void error(char* format, ...); -static char* emalloc(size_t size); +static void* emalloc(size_t size); static char* strsave(char* string); static void push_words(char* src); static int run_erlang(char* name, char** argv); static char* get_default_emulator(char* progname); #ifdef __WIN32__ static char* possibly_quote(char* arg); +static void* erealloc(void *p, size_t size); #endif /* @@ -117,9 +119,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 +136,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 = emalloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = emalloc(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 +241,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 +316,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 *) erealloc(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 +368,7 @@ int my_spawnvp(char **argv) siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - if (!CreateProcess(NULL, + if (!CreateProcessW(NULL, make_commandline(argv), NULL, NULL, @@ -415,15 +438,26 @@ error(char* format, ...) exit(1); } -static char* +static void* emalloc(size_t size) { - char *p = malloc(size); + void *p = malloc(size); if (p == NULL) error("Insufficient memory"); return p; } +#ifdef __WIN32__ +static void * +erealloc(void *p, size_t size) +{ + void *res = realloc(p, size); + if (res == NULL) + error("Insufficient memory"); + return res; +} +#endif + static char* strsave(char* string) { @@ -432,6 +466,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 +491,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..6ba3605422 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-2016. 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% */ @@ -62,13 +63,14 @@ static int eargc; /* Number of arguments in eargv. */ */ static void error(char* format, ...); -static char* emalloc(size_t size); +static void* emalloc(size_t size); static char* strsave(char* string); static void push_words(char* src); static int run_erlang(char* name, char** argv); static char* get_default_emulator(char* progname); #ifdef __WIN32__ static char* possibly_quote(char* arg); +static void* erealloc(void *p, size_t size); #endif /* @@ -104,20 +106,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 +147,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 +162,18 @@ main(int argc, char** argv) int i; int need_shell = 0; +#ifdef __WIN32__ + int len; + /* Convert argv to utf8 */ + argv = emalloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = emalloc(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 +290,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 *) erealloc(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 +344,7 @@ int my_spawnvp(char **argv) siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - if (!CreateProcess(NULL, + if (!CreateProcessW(NULL, make_commandline(argv), NULL, NULL, @@ -381,15 +414,26 @@ error(char* format, ...) exit(1); } -static char* +static void* emalloc(size_t size) { - char *p = malloc(size); + void *p = malloc(size); if (p == NULL) error("Insufficient memory"); return p; } +#ifdef __WIN32__ +static void * +erealloc(void *p, size_t size) +{ + void *res = realloc(p, size); + if (res == NULL) + error("Insufficient memory"); + return res; +} +#endif + static char* strsave(char* string) { @@ -398,6 +442,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 +467,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..b54cb31bef 100644 --- a/erts/etc/common/erlc.c +++ b/erts/etc/common/erlc.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2013. All Rights Reserved. + * Copyright Ericsson AB 1997-2016. 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,14 +71,14 @@ 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 void* emalloc(size_t size); static char* strsave(char* string); static void push_words(char* src); static int run_erlang(char* name, char** argv); static char* get_default_emulator(char* progname); #ifdef __WIN32__ static char* possibly_quote(char* arg); +static void* erealloc(void *p, size_t size); #endif /* @@ -114,20 +114,31 @@ get_env(char *key) { #ifdef __WIN32__ DWORD size = 32; - char *value = NULL; + char *value=NULL; + wchar_t *wcvalue = NULL; + wchar_t wckey[256]; + int len; + + MultiByteToWideChar(CP_UTF8, 0, key, -1, wckey, 256); + while (1) { DWORD nsz; - if (value) - free(value); - value = emalloc(size); + if (wcvalue) + free(wcvalue); + wcvalue = (wchar_t *) emalloc(size*sizeof(wchar_t)); SetLastError(0); - nsz = GetEnvironmentVariable((LPCTSTR) key, (LPTSTR) value, size); + nsz = GetEnvironmentVariableW(wckey, wcvalue, size); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { - free(value); + free(wcvalue); return NULL; } - if (nsz <= size) + if (nsz <= size) { + len = WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, NULL, 0, NULL, NULL); + value = emalloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wcvalue, -1, value, len, NULL, NULL); + free(wcvalue); return value; + } size = nsz; } #else @@ -144,16 +155,32 @@ free_env_val(char *value) #endif } - -int -main(int argc, char** argv) +#ifdef __WIN32__ +int wmain(int argc, wchar_t **wcargv) { - char 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 = emalloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = emalloc(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 +218,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 +273,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 +352,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 *) erealloc(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 +404,7 @@ int my_spawnvp(char **argv) siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - if (!CreateProcess(NULL, + if (!CreateProcessW(NULL, make_commandline(argv), NULL, NULL, @@ -633,53 +467,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]; @@ -692,15 +479,26 @@ error(char* format, ...) exit(1); } -static char* +static void* emalloc(size_t size) { - char *p = malloc(size); + void *p = malloc(size); if (p == NULL) error("Insufficient memory"); return p; } +#ifdef __WIN32__ +static void * +erealloc(void *p, size_t size) +{ + void *res = realloc(p, size); + if (res == NULL) + error("Insufficient memory"); + return res; +} +#endif + static char* strsave(char* string) { @@ -709,6 +507,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 +532,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 e61ebe15f5..2b2e0e480a 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2016. 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,6 +65,7 @@ static const char plusM_au_allocs[]= { 'u', /* all alloc_util allocators */ 'B', /* binary_alloc */ + 'I', /* literal_alloc */ 'D', /* std_alloc */ 'E', /* ets_alloc */ 'F', /* fix_alloc */ @@ -72,6 +74,8 @@ static const char plusM_au_allocs[]= { 'R', /* driver_alloc */ 'S', /* sl_alloc */ 'T', /* temp_alloc */ + 'X', /* exec_alloc */ + 'Z', /* test_alloc */ '\0' }; @@ -103,16 +107,24 @@ 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", + "Xscs", NULL }; @@ -122,6 +134,7 @@ static char *pluss_val_switches[] = { "bwt", "cl", "ct", + "ecio", "fwi", "tbt", "wct", @@ -129,12 +142,18 @@ static char *pluss_val_switches[] = { "ws", "ss", "pp", + "ub", NULL }; /* +h arguments with values */ static char *plush_val_switches[] = { "ms", "mbs", + "pds", + "max", + "maxk", + "maxel", + "mqd", "", NULL }; @@ -148,6 +167,8 @@ static char *plusr_val_switches[] = { /* +z arguments with values */ static char *plusz_val_switches[] = { "dbbl", + "dntgc", + "ebwt", NULL }; @@ -174,6 +195,7 @@ static char *plusz_val_switches[] = { #endif void usage(const char *switchname); +static void usage_format(char *format, ...); void start_epmd(char *epmd); void error(char* format, ...); @@ -706,7 +728,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 */ @@ -774,6 +796,24 @@ int main(int argc, char **argv) get_start_erl_data((char *) NULL); } #endif + else if (strcmp(argv[i], "-start_epmd") == 0) { + if (i+1 >= argc) + usage("-start_epmd"); + + if (strcmp(argv[i+1], "true") == 0) { + /* The default */ + no_epmd = 0; + } + else if (strcmp(argv[i+1], "false") == 0) { + no_epmd = 1; + } + else + usage_format("Expected boolean argument for \'-start_epmd\'.\n"); + + add_arg(argv[i]); + add_arg(argv[i+1]); + i++; + } else add_arg(argv[i]); @@ -799,11 +839,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 +859,31 @@ 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; + } + 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; + } + 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 +911,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++) @@ -1113,14 +1192,16 @@ 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] " + "[-make] [-man [manopts] MANPAGE] [-x] [-emu_args] [-start_epmd 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>] [+z MISC_OPTION] [args ...]\n"); exit(1); } @@ -1174,11 +1255,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 +1456,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 +1509,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 +2049,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..71c278881c 100644 --- a/erts/etc/common/escript.c +++ b/erts/etc/common/escript.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2013. All Rights Reserved. + * Copyright Ericsson AB 2007-2016. 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 @@ -69,7 +71,7 @@ static int eargc; /* Number of arguments in eargv. */ */ static void error(char* format, ...); -static char* emalloc(size_t size); +static void* emalloc(size_t size); static void efree(void *p); static char* strsave(char* string); static void push_words(char* src); @@ -77,6 +79,7 @@ static int run_erlang(char* name, char** argv); static char* get_default_emulator(char* progname); #ifdef __WIN32__ static char* possibly_quote(char* arg); +static void* erealloc(void *p, size_t size); #endif /* @@ -112,20 +115,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 +159,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 +264,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 +285,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 +305,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 +318,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 +396,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 +414,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 = emalloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = emalloc(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 +506,8 @@ main(int argc, char** argv) #endif erts_snprintf(scriptname, sizeof(scriptname), "%s.escript", - absname); + absname); efree(absname); - } /* @@ -483,63 +576,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 *) erealloc(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); @@ -600,15 +695,26 @@ error(char* format, ...) exit(1); } -static char* +static void* emalloc(size_t size) { - char *p = malloc(size); + void *p = malloc(size); if (p == NULL) error("Insufficient memory"); return p; } +#ifdef __WIN32__ +static void * +erealloc(void *p, size_t size) +{ + void *res = realloc(p, size); + if (res == NULL) + error("Insufficient memory"); + return res; +} +#endif + static void efree(void *p) { @@ -623,6 +729,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 +754,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..d67b997d6d 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-2016. 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,14 @@ #define HEART_COMMAND_ENV "HEART_COMMAND" #define ERL_CRASH_DUMP_SECONDS_ENV "ERL_CRASH_DUMP_SECONDS" +#define HEART_KILL_SIGNAL "HEART_KILL_SIGNAL" +#define HEART_NO_KILL "HEART_NO_KILL" + -#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 +205,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 +242,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 +474,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; @@ -512,6 +526,12 @@ static void kill_old_erlang(void){ HANDLE erlh; DWORD exit_code; + char* envvar = NULL; + + envvar = get_env(HEART_NO_KILL); + if (envvar && strcmp(envvar, "TRUE") == 0) + return; + if(heart_beat_kill_pid != 0){ if((erlh = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE | @@ -541,14 +561,26 @@ kill_old_erlang(void){ static void kill_old_erlang(void){ pid_t pid; - int i; - int res; + int i, res; + int sig = SIGKILL; + char *envvar = NULL; + + envvar = get_env(HEART_NO_KILL); + if (envvar && strcmp(envvar, "TRUE") == 0) + return; + + envvar = get_env(HEART_KILL_SIGNAL); + if (envvar && strcmp(envvar, "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 +596,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 +643,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 +726,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 +1014,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 +1031,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 +1100,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 +1111,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 +1138,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..bc4893b0eb 100644 --- a/erts/etc/common/inet_gethost.c +++ b/erts/etc/common/inet_gethost.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2012. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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) { @@ -2645,7 +2646,7 @@ static void *my_realloc(void *old, size_t size) BOOL create_mesq(MesQ **q) { - MesQ *tmp = malloc(sizeof(MesQ)); + MesQ *tmp = ALLOC(sizeof(MesQ)); tmp->data_present = CreateEvent(NULL, TRUE, FALSE,NULL); if (tmp->data_present == NULL) { free(tmp); diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c index c95959d52d..77a95ccded 100644 --- a/erts/etc/common/typer.c +++ b/erts/etc/common/typer.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2006-2011. All Rights Reserved. + * Copyright Ericsson AB 2006-2016. 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% */ @@ -62,13 +63,14 @@ static int eargc; /* Number of arguments in eargv. */ */ static void error(char* format, ...); -static char* emalloc(size_t size); +static void* emalloc(size_t size); static char* strsave(char* string); static void push_words(char* src); static int run_erlang(char* name, char** argv); static char* get_default_emulator(char* progname); #ifdef __WIN32__ static char* possibly_quote(char* arg); +static void* erealloc(void *p, size_t size); #endif /* @@ -99,14 +101,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 = emalloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); + argv[i] = emalloc(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 +214,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 *) erealloc(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); @@ -313,15 +333,26 @@ error(char* format, ...) exit(1); } -static char* +static void* emalloc(size_t size) { - char *p = malloc(size); + void *p = malloc(size); if (p == NULL) error("Insufficient memory"); return p; } +#ifdef __WIN32__ +static void * +erealloc(void *p, size_t size) +{ + void *res = realloc(p, size); + if (res == NULL) + error("Insufficient memory"); + return res; +} +#endif + static char* strsave(char* string) { @@ -330,6 +361,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 +386,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/unix/Install.src b/erts/etc/unix/Install.src index 0f33258a28..e71308edbe 100644 --- a/erts/etc/unix/Install.src +++ b/erts/etc/unix/Install.src @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2013. All Rights Reserved. +# Copyright Ericsson AB 1996-2016. 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% # @@ -137,9 +138,9 @@ case $start_option in esac cp -p ../releases/%I_SYSTEM_VSN%/start_*.boot . +cp -p ../releases/%I_SYSTEM_VSN%/no_dot_erlang.boot . cp -p $Name.boot start.boot cp -p ../releases/%I_SYSTEM_VSN%/$Name.script start.script - # # Fixing the man pages # diff --git a/erts/etc/unix/Makefile b/erts/etc/unix/Makefile new file mode 100644 index 0000000000..2fa9cd047b --- /dev/null +++ b/erts/etc/unix/Makefile @@ -0,0 +1,47 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2013-2016. All Rights Reserved. +# +# 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% +# + +include $(ERL_TOP)/make/output.mk +include $(ERL_TOP)/make/target.mk + +include $(ERL_TOP)/make/$(TARGET)/otp.mk +include ../../vsn.mk + +opt debug: etc + +.PHONY: etc +etc: etp-commands + +etp-commands: etp-commands.in + $(gen_verbose)sed 's:@ERL_TOP@:${ERL_TOP}:g' etp-commands.in > etp-commands + +.PHONY: docs +docs: + +.PHONY: clean +clean: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +.PHONY: release_spec +release_spec: etc
\ No newline at end of file diff --git a/erts/etc/unix/README b/erts/etc/unix/README index 45b4aec2da..adc6db4300 100644 --- a/erts/etc/unix/README +++ b/erts/etc/unix/README @@ -1,18 +1,19 @@ %CopyrightBegin% - Copyright Ericsson AB 1996-2009. All Rights Reserved. + Copyright Ericsson AB 1996-2016. 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% diff --git a/erts/etc/unix/RELNOTES b/erts/etc/unix/RELNOTES index d1a110fce3..7b4a1746fe 100644 --- a/erts/etc/unix/RELNOTES +++ b/erts/etc/unix/RELNOTES @@ -1,18 +1,19 @@ %CopyrightBegin% - Copyright Ericsson AB 1996-2009. All Rights Reserved. + Copyright Ericsson AB 1996-2016. 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% diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 0d45917e4b..c5422ab2ed 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2013. All Rights Reserved. +# Copyright Ericsson AB 2003-2016. 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% # @@ -33,6 +34,7 @@ # You have to start beam in gdb using "run". # -rgdb Run the debug compiled emulator in gdb. # You have to start beam in gdb using "run". +# -dump Dump the bt of all threads in a core. # -break F Run the debug compiled emulator in emacs and gdb and set break. # The session is started, i.e. "run" is already don for you. # -xxgdb FIXME currently disabled @@ -42,6 +44,7 @@ # -gcov Run emulator compiled for gcov # -valgrind Run emulator compiled for valgrind # -lcnt Run emulator compiled for lock counting +# -icount Run emulator compiled for instruction counting # -nox Unset the DISPLAY variable to disable us of X Windows # # FIXME For GDB you can also set the break point using "-break FUNCTION". @@ -85,6 +88,7 @@ run_valgrind=no # Default rootdir ROOTDIR=%SRC_ROOTDIR% BINDIR="$ROOTDIR/bin/`$ROOTDIR/erts/autoconf/config.guess`" +TARGET=%TARGET% #BINDIR="$ROOTDIR/bin/%TARGET%" PROGNAME=$ROOTDIR/bin/cerl EMU=beam @@ -178,6 +182,17 @@ while [ $# -gt 0 ]; do cargs="$cargs -frmptr" TYPE=.frmptr ;; + "-icount") + shift + cargs="$cargs -icount" + TYPE=.icount + ;; + "-dump") + shift + GDB=dump + core="$1" + shift + ;; "-gdb") shift GDB=egdb @@ -241,6 +256,12 @@ while [ $# -gt 0 ]; do done +if [ ! -f $BINDIR/erlexec -a -f $ROOTDIR/bin/$TARGET/erlexec ]; then + # We are in a strange target (I'm looking at you openbsd) where + # TARGET != config.guess + BINDIR=$ROOTDIR/bin/$TARGET +fi + PATH=$BINDIR:$ROOTDIR/bin:$PATH EXEC=$BINDIR/erlexec @@ -283,6 +304,19 @@ if [ "x$GDB" = "x" ]; then else valgrind_misc_flags="$VALGRIND_MISC_FLAGS" fi + if which taskset > /dev/null && test -e /proc/cpuinfo; then + # We only let valgrind utilize one core with "taskset 1" as it can be very slow + # on multiple cores (especially with async threads). Valgrind only run one pthread + # at a time anyway so there is no point letting it utilize more than one core. + # Use $sched_arg to force all schedulers online to emulate multicore. + taskset1="taskset 1" + ncpu=`cat /proc/cpuinfo | grep -w processor | wc -l` + sched_arg="-S$ncpu:$ncpu" + else + taskset1= + sched_arg= + fi + beam_args=`$EXEC -emu_args_exit ${1+"$@"}` # Time for some argument passing voodoo: @@ -293,7 +327,7 @@ if [ "x$GDB" = "x" ]; then ' set -- $beam_args IFS="$SAVE_IFS" - exec valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $emu_xargs "$@" -pz $PRELOADED + exec $taskset1 valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $sched_arg $emu_xargs "$@" -pz $PRELOADED else exec $EXEC $eeargs $xargs ${1+"$@"} fi @@ -318,7 +352,7 @@ elif [ "x$GDB" = "xgdb" ]; then echo "source $ROOTDIR/erts/etc/unix/etp-commands" > $cmdfile # Fire up gdb in emacs... exec gdb $GDBBP -x $cmdfile $gdbcmd -else +elif [ "x$GDB" = "xegdb" ]; then if [ "x$EMACS" = "x" ]; then EMACS=emacs fi @@ -326,7 +360,7 @@ else case "x$core" in x) # Get emu args to use from erlexec... - beam_args=`$EXEC -emu_args_exit ${1+"$@"}` + beam_args=`$EXEC -emu_args_exit ${1+"$@"} | tr '\n' ' '` gdbcmd="(insert-string \"set args $beam_args\") \ (comint-send-input)" ;; @@ -348,7 +382,9 @@ else # Set annotation level for gdb in emacs 22 and higher. Seems to # be working with level 1 for emacs 22 and level 3 for emacs 23... emacs_major=`$EMACS --version | head -1 | sed 's,^[^0-9]*\([0-9]*\).*,\1,g'` - if [ '!' -z "$emacs_major" -a $emacs_major -gt 22 ]; then + if [ '!' -z "$emacs_major" -a $emacs_major -gt 23 ]; then + GDBARGS="-i=mi " + elif [ '!' -z "$emacs_major" -a $emacs_major -gt 22 ]; then GDBARGS="--annotate=3 " elif [ '!' -z "$emacs_major" -a $emacs_major -gt 21 ]; then GDBARGS="--annotate=1 " @@ -359,4 +395,23 @@ else (comint-send-input)" # Fire up gdb in emacs... exec $EMACS --eval "(progn (gdb \"gdb $GDBARGS$EMU_NAME\") $gdbcmd)" +elif [ "x$GDB" = "xdump" ]; then + cmdfile="/tmp/.cerlgdb.$$" + case "x$core" in + x/*) + gdbcmd="$EMU_NAME ${core}" + ;; + *) + dir=`pwd` + gdbcmd="$EMU_NAME ${dir}/${core}" + ;; + esac + echo "set width 0 +set height 0 +set verbose off + +source $ROOTDIR/erts/etc/unix/etp-commands +thread apply all bt +" > $cmdfile + exec gdb --batch --command=$cmdfile $gdbcmd fi diff --git a/erts/etc/unix/dyn_erl.c b/erts/etc/unix/dyn_erl.c index 984935417e..d6d2201648 100644 --- a/erts/etc/unix/dyn_erl.c +++ b/erts/etc/unix/dyn_erl.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2009. All Rights Reserved. + * Copyright Ericsson AB 2009-2016. 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/unix/erl.src.src b/erts/etc/unix/erl.src.src index ce5d2b5def..959c099e8f 100644 --- a/erts/etc/unix/erl.src.src +++ b/erts/etc/unix/erl.src.src @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2012. All Rights Reserved. +# Copyright Ericsson AB 1996-2016. 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/unix/etp-commands b/erts/etc/unix/etp-commands.in index f059662271..15fb718c47 100644 --- a/erts/etc/unix/etp-commands +++ b/erts/etc/unix/etp-commands.in @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2005-2012. All Rights Reserved. +# Copyright Ericsson AB 2005-2016. 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% # @@ -54,13 +55,23 @@ document etp-help % etp-mfa, etp-cp, % etp-msgq, etpf-msgq, % etp-stacktrace, etp-stackdump, etpf-stackdump, etp-dictdump -% etp-offheapdump, etpf-offheapdump, -% etp-print-procs, etp-search-heaps, etp-search-alloc, +% etp-process-info, etp-process-memory-info +% etp-port-info, etp-port-state, etp-port-sched-flags +% etp-heapdump, etp-offheapdump, etpf-offheapdump, +% etp-search-heaps, etp-search-alloc, % etp-ets-tables, etp-ets-tabledump % % Complex commands that use the Erlang support module. % etp-overlapped-heaps, etp-chart, etp-chart-start, etp-chart-end -% +% +% System inspection +% etp-system-info, etp-schedulers, etp-process, etp-ports, etp-lc-dump, +% etp-migration-info, etp-processes-memory, +% etp-compile-info, etp-config-h-info +% +% Platform specific (when gdb fails you) +% etp-ppc-stacktrace +% % Erlang support module handling commands: % etp-run % @@ -136,14 +147,10 @@ define etp-1 etp-immediate-1 ($arg0) else # (($arg0) & 0x3) == 0 - if (($arg0) == 0x0) + if (($arg0) == etp_the_non_value) printf "<the non-value>" else - if (($arg0) == 0x4) - printf "<the non-value debug>" - else - etp-cp-1 ($arg0) - end + etp-cp-1 ($arg0) end end end @@ -345,7 +352,32 @@ define etp-boxed-1 etp-array-1 ((Eterm*)(($arg0)&~0x3)) ($arg1) ($arg1) \ 1 ((((Eterm*)(($arg0)&~0x3))[0]>>6)+1) '}' else - etp-boxed-immediate-1 ($arg0) + if (((Eterm*)(($arg0) & ~0x3))[0] & 0x3c) == 0x3c + # A map + if (((Eterm*)(($arg0) & ~0x3))[0] & 0xc0) == 0x0 + # Flat map + printf "#{Keys:" + etp-1 ((flatmap_t*)(($arg0)&~0x3))->keys (($arg1)+1) + printf " Values:{" + etp-array-1 ((Eterm*)(($arg0)&~0x3)+3) ($arg1) ($arg1) \ + 0 ((flatmap_t*)(($arg0)&~0x3))->size '}' + printf "}" + else + # Hashmap + printf "#<%x>{", (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff) + if (((Eterm*)(($arg0) & ~0x3))[0] & 0xc0) >= 0x80 + # head bitmap/array + etp-bitmap-array-1 ((Eterm*)(($arg0)&~0x3)+2) ($arg1) ($arg1) \ + 0 (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff) '}' + else + # node bitmap + etp-bitmap-array-1 ((Eterm*)(($arg0)&~0x3)+1) ($arg1) ($arg1) \ + 0 (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff) '}' + end + end + else + etp-boxed-immediate-1 ($arg0) + end end end end @@ -468,6 +500,36 @@ define etp-array-1 end end +define etp-bitmap-array-1 +# Args: Eterm* p, int depth, int width, int pos, int bitmap, int end_char +# +# Reentrant +# +# Same as etp-array-1 with size = bitcount(bitmap) +# + if ($arg4) & 1 != 0 + if (($arg1) < $etp_max_depth) && (($arg2) < $etp_max_depth) + etp-1 (($arg0)[($arg3)]) (($arg1)+1) + if (($arg4) & (($arg4)-1)) != 0 + printf "," + end + etp-bitmap-array-1 ($arg0) ($arg1) (($arg2)+1) (($arg3)+1) (($arg4)>>1) ($arg5) + else + printf "...%c", ($arg5) + end + else + if ($arg4) == 0 + printf "%c", ($arg5) + else + etp-bitmap-array-1 $arg0 $arg1 $arg2 $arg3 (($arg4)>>1) $arg5 + + # WARNING: One might be tempted to optimize the bitcounting here + # by passing the bitmap argument as ($arg4 & ($arg4 - 1)). This is a very + # bad idea as arguments are passed as string substitution. + # The size of $arg4 would thus grow exponentially for each recursion. + end + end +end #define etpa-1 @@ -652,7 +714,7 @@ end define etp-ct-atom-1 # Args: int # -# Determines if integer is a atom first character +# Determines if integer is an atom first character # # Non-reentrant # Returns: $etp_ct_atom @@ -712,9 +774,9 @@ define etp-pid-1 # set $etp_pid_1 = (Eterm)($arg0) if ($etp_pid_1 & 0xF) == 0x3 - if (etp_arch_bits == 64 && etp_halfword == 0) + if (etp_arch_bits == 64) if (etp_big_endian) - set $etp_pid_data = (unsigned) ((((Uint64) $etp_pid_1) >> 36) & 0x0fffffff) + set $etp_pid_data = (unsigned) ((((Uint64) $etp_pid_1) >> 35) & 0x0fffffff) else set $etp_pid_data = (unsigned) ((((Uint64) $etp_pid_1) >> 4) & 0x0fffffff) end @@ -772,7 +834,7 @@ define etp-port-1 # set $etp_port_1 = (Eterm)($arg0) if ($etp_port_1 & 0xF) == 0x7 - if (etp_arch_bits == 64 && etp_halfword == 0) + if (etp_arch_bits == 64) if (etp_big_endian) set $etp_port_data = (unsigned) ((((Uint64) $etp_port_1) >> 36) & 0x0fffffff) else @@ -1055,7 +1117,9 @@ define etp-cp-1 set $etp_cp_mid = $etp_cp_low + ($etp_cp_high-$etp_cp_low)/2 end if $etp_cp_p - set $etp_cp_low = (Eterm**)($etp_cp_p->start + 8) + # 13 = MI_FUNCTIONS + set $etp_cp_low = (Eterm**)($etp_cp_p->start + 13) + # 0 = MI_NUM_FUNCTIONS set $etp_cp_high = $etp_cp_low +$etp_cp_p->start[0] set $etp_cp_p = 0 while $etp_cp_low < $etp_cp_high @@ -1118,6 +1182,39 @@ document etp-cp %--------------------------------------------------------------------------- end +define etp-check-beam-ranges + set $etp_ci = 0 + while $etp_ci < 3 + printf "Checking code index %i...\n", $etp_ci + set $etp_j = 0 + while $etp_j < r[$etp_ci].n + set $etp_p = &r[$etp_ci].modules[$etp_j] + if $etp_j > 0 && $etp_p->start < (Range*)$etp_p[-1].end.counter + printf "r[%i].modules[%i]: ERROR start < previous\n", $etp_ci, $etp_j + end + if $etp_p->start > (Range*)$etp_p->end.counter + printf "r[%i].modules[%i]: ERROR start > end\n", $etp_ci, $etp_j + else + if $etp_p->start == (Range*)$etp_p->end.counter + printf "r[%i].modules[%i]: Purged\n", $etp_ci, $etp_j + end + end + set $etp_j = $etp_j + 1 + end + set $etp_ci = $etp_ci + 1 + end +end + +document etp-check-beam-ranges +%--------------------------------------------------------------------------- +% etp-check-beam-ranges +% +% Do consistency check of beam_ranges data structure +% and print errors and empty slots from purged modules. +%--------------------------------------------------------------------------- +end + + ############################################################################ # Commands for special term bunches. # @@ -1278,10 +1375,254 @@ document etpf-stackdump %--------------------------------------------------------------------------- end +define etp-heapdump +# Args: Process* +# +# Non-reentrant + etp-heapdump-1 ($arg0)->heap ($arg0)->htop +end + +document etp-heapdump +%--------------------------------------------------------------------------- +% etp-heapdump Process* +% +% Take an Process* and print a heapdump for the process heap. +%--------------------------------------------------------------------------- +end + +define etp-heapdump-old +# Args: Process* +# +# Non-reentrant + etp-heapdump-1 ($arg0)->old_heap ($arg0)->old_htop +end + +document etp-heapdump +%--------------------------------------------------------------------------- +% etp-heapdump-old Process* +% +% Take an Process* and print a heapdump for the process old heap (gen-heap). +%--------------------------------------------------------------------------- +end + + +define etp-heapdump-1 +# Args: Eterm* heap, Eterm* htop +# +# Non-reentrant + set $etp_heapdump_heap = (Eterm*)($arg0) + set $etp_heapdump_p = (Eterm*)($arg0) + set $etp_heapdump_end = (Eterm*)($arg1) + set $etp_heapdump_skips = 0 + printf "%% heapdump (%u):\n", $etp_heapdump_end-$etp_heapdump_p + while $etp_heapdump_p < $etp_heapdump_end + set $etp_heapdump_ix = 0 + printf " %p: ", $etp_heapdump_p + while $etp_heapdump_p < $etp_heapdump_end && $etp_heapdump_ix < 8 + if ($etp_heapdump_skips > 0) + printf "| 0x%08x ", ($etp_heapdump_p) + set $etp_heapdump_skips-- + else + etp-term-dump $etp_heapdump_p[0] + end + set $etp_heapdump_p++ + set $etp_heapdump_ix++ + end + printf "\n" + end +end + + +define etp-term-dump +# Args: Eterm + if (($arg0) & 0x3) == 0 + etp-term-dump-header ($arg0) + else + if (($arg0) & 0x3) == 1 + # Cons pointer + set $etp_term_dump_cons_p = ((Eterm*)(($arg0) & ~0x3)) + if $etp_term_dump_cons_p > $etp_heapdump_heap && $etp_term_dump_cons_p < $etp_heapdump_end + printf "| C:0x%08x ", $etp_term_dump_cons_p + #printf "| C: --> %5d ", $etp_heapdump_p - $etp_term_dump_cons_p - 1 + else + printf "| C:0x%08x ", $etp_term_dump_cons_p + end + else + if (($arg0) & 0x3) == 2 + # Box pointer + printf "| B:0x%08x ", ($arg0) + else + if (($arg0) & 0x3) == 3 + # immediate + etp-term-dump-immediate ($arg0) + else + printf "| U:0x%08x ", ($arg0) + end + end + end + end +end + +define etp-term-dump-immediate +# Args: immediate term + if (($arg0) & 0xF) == 0xf + # Fixnum + etp-ct-printable-1 ((long)((Sint)($arg0)>>4)) + if $etp_ct_printable + if $etp_ct_printable < 0 + printf "| I: %c (%3ld) ", (long)((Sint)($arg0)>>4), (long)((Sint)($arg0)>>4) + else + printf "| I: \\%c (%3ld) ", (long)((Sint)($arg0)>>4), (long)((Sint)($arg0)>>4) + end + else + printf "| I:%10ld ", (long)((Sint)($arg0)>>4) + end + else + if (($arg0) & 0xF) == 0x3 + etp-term-dump-pid ($arg0) + else + if (($arg0) & 0xF) == 0x7 + printf "| port:0x%05x ", ($arg0) + else + # Immediate2 - 0xB + if (($arg0) & 0x3f) == 0x0b + etp-term-dump-atom ($arg0) + else + if (($arg0) & 0x3f) == 0x1b + printf "| #Catch<%06d> ", ($arg0)>>6 + else + if (($arg0) == $etp_nil) + printf "| [] (NIL) " + else + printf "| I:0x%08x ", ($arg0) + end + end + end + end + end + end +end + +define etp-term-dump-atom +# Args: atom term + set $etp_atom_1_ap = (Atom*)erts_atom_table.seg_table[(Eterm)($arg0)>>16][((Eterm)($arg0)>>6)&0x3FF] + set $etp_atom_1_i = ($etp_atom_1_ap)->len + set $etp_atom_1_p = ($etp_atom_1_ap)->name + set $etp_atom_1_quote = 1 + set $etp_atom_indent = 13 + + if ($etp_atom_1_i < 11) + if ($etp_atom_1_i > 0) + etp-ct-atom-1 (*$etp_atom_1_p) + if $etp_ct_atom + set $etp_atom_indent = 13 + else + set $etp_atom_indent = 11 + end + end + # perform indentation + printf "|" + while ($etp_atom_1_i < $etp_atom_indent) + printf " " + set $etp_atom_1_i++ + end + set $etp_atom_1_i = ($etp_atom_1_ap)->len + # Check if atom has to be quoted + if ($etp_atom_1_i > 0) + etp-ct-atom-1 (*$etp_atom_1_p) + if $etp_ct_atom + # Atom start character + set $etp_atom_1_p++ + set $etp_atom_1_i-- + set $etp_atom_1_quote = 0 + else + set $etp_atom_1_i = 0 + end + end + while $etp_atom_1_i > 0 + etp-ct-name-1 (*$etp_atom_1_p) + if $etp_ct_name + # Name character + set $etp_atom_1_p++ + set $etp_atom_1_i-- + else + set $etp_atom_1_quote = 1 + set $etp_atom_1_i = 0 + end + end + # Print the atom + if $etp_atom_1_quote + printf "'" + end + set $etp_atom_1_i = ($etp_atom_1_ap)->len + set $etp_atom_1_p = ($etp_atom_1_ap)->name + while $etp_atom_1_i > 0 + etp-char-1 (*$etp_atom_1_p) '\'' + set $etp_atom_1_p++ + set $etp_atom_1_i-- + end + if $etp_atom_1_quote + printf "'" + end + printf " " + else + printf "| A:0x%08x ", ($arg0) + end +end + +define etp-term-dump-pid +# Args: Eterm pid +# +# Non-reentrant +# + set $etp_pid_1 = (Eterm)($arg0) + if ($etp_pid_1 & 0xF) == 0x3 + if (etp_arch_bits == 64) + if (etp_big_endian) + set $etp_pid_data = (unsigned) ((((Uint64) $etp_pid_1) >> 36) & 0x0fffffff) + else + set $etp_pid_data = (unsigned) ((((Uint64) $etp_pid_1) >> 4) & 0x0fffffff) + end + else + set $etp_pid_data = (unsigned) (((((Uint32) $etp_pid_1) >> 4) & ~erts_proc.r.o.pix_mask) | ((((Uint32) $etp_pid_1) >> (erts_proc.r.o.pix_cl_shift + 4)) & erts_proc.r.o.pix_cl_mask) | (((((Uint32) $etp_pid_1) >> 4) & erts_proc.r.o.pix_cli_mask) << erts_proc.r.o.pix_cli_shift)) + end + # Internal pid + printf "| <0.%04u.%03u> ", $etp_pid_data & 0x7fff, ($etp_pid_data >> 15) & 0x1fff + else + printf "| #NotPid<%#x> ", ($arg0) + end +end + +define etp-term-dump-header +# Args: Header term + if (($arg0) & 0x3f) == 0 + printf "| H:%4d-tuple ", ($arg0) >> 6 + else + set $etp_heapdump_skips = ($arg0) >> 6 + if ((($arg0) & 0x3f) == 0x18) + printf "| H: float %3d ", ($arg0) >> 6 + else + if ((($arg0) & 0x3f) == 0x28) + # sub-binary + printf "| H: sub-bin " + else + if ((($arg0) & 0x3f) == 0x8) + # pos-bignum + printf "| H:bignum %3u ", ($arg0) >> 6 + else + printf "| header %5d ", ($arg0) >> 6 + end + end + end + end +end + + + define etp-pid2pix-1 # Args: Eterm # - if (etp_arch_bits == 64 && etp_halfword == 0) + if (etp_arch_bits == 64) if (etp_big_endian) set $etp_pix = (int) (((Uint64) $arg0) & 0x0fffffff) else @@ -1316,49 +1657,123 @@ end define etp-proc-state-int # Args: int # - if ($arg0 & 0xfffff000) - printf "GARBAGE | " + if ($arg0 & 0x80000000) + printf "GARBAGE<0x80000000> | " end - if ($arg0 & 0x800) + if ($arg0 & 0x40000000) + printf "dirty-running-sys | " + end + if ($arg0 & 0x20000000) + printf "dirty-running | " + end + if ($arg0 & 0x10000000) + printf "dirty-active-sys | " + end + if ($arg0 & 0x8000000) + printf "dirty-io-proc | " + end + if ($arg0 & 0x4000000) + printf "dirty-cpu-proc | " + end + if ($arg0 & 0x2000000) + printf "on-heap-msgq | " + end + if ($arg0 & 0x1000000) + printf "off-heap-msgq | " + end + if ($arg0 & 0x800000) + printf "delayed-sys | " + end + if ($arg0 & 0x400000) + printf "proxy | " + set $proxy_process = 1 + else + set $proxy_process = 0 + end + if ($arg0 & 0x200000) + printf "running-sys | " + end + if ($arg0 & 0x100000) + printf "active-sys | " + end + if ($arg0 & 0x80000) printf "trapping-exit | " end - if ($arg0 & 0x400) + if ($arg0 & 0x40000) printf "bound | " end - if ($arg0 & 0x200) + if ($arg0 & 0x20000) printf "garbage-collecting | " end - if ($arg0 & 0x100) + if ($arg0 & 0x10000) printf "suspended | " end - if ($arg0 & 0x80) + if ($arg0 & 0x8000) printf "running | " end - if ($arg0 & 0x40) + if ($arg0 & 0x4000) printf "in-run-queue | " end - if ($arg0 & 0x20) + if ($arg0 & 0x2000) printf "active | " end - if ($arg0 & 0x10) + if ($arg0 & 0x1000) printf "pending-exit | " end - if ($arg0 & 0x8) + if ($arg0 & 0x800) printf "exiting | " end - if ($arg0 & 0x4) + if ($arg0 & 0x400) printf "free | " end - if ($arg0 & 0x3) == 0 - printf "prio-max\n" + if ($arg0 & 0x200) + printf "in-prq-low | " + end + if ($arg0 & 0x100) + printf "in-prq-normal | " + end + if ($arg0 & 0x80) + printf "in-prq-high | " + end + if ($arg0 & 0x40) + printf "in-prq-max | " + end + if ($arg0 & 0x30) == 0x0 + printf "prq-prio-max | " else - if ($arg0 & 0x3) == 1 - printf "prio-high\n" + if ($arg0 & 0x30) == 0x10 + printf "prq-prio-high | " else - if ($arg0 & 0x3) == 2 - printf "prio-normal\n" + if ($arg0 & 0x30) == 0x20 + printf "prq-prio-normal | " else - printf "prio-low\n" + printf "prq-prio-low | " + end + end + end + if ($arg0 & 0xc) == 0x0 + printf "usr-prio-max | " + else + if ($arg0 & 0xc) == 0x4 + printf "usr-prio-high | " + else + if ($arg0 & 0xc) == 0x8 + printf "usr-prio-normal | " + else + printf "usr-prio-low | " + end + end + end + if ($arg0 & 0x3) == 0x0 + printf "act-prio-max\n" + else + if ($arg0 & 0x3) == 0x1 + printf "act-prio-high\n" + else + if ($arg0 & 0x3) == 0x2 + printf "act-prio-normal\n" + else + printf "act-prio-low\n" end end end @@ -1392,46 +1807,54 @@ define etp-process-info # Args: Process* # printf " Pid: " - etp-1 $arg0->common.id + set $etp_proc = ((Process*)$arg0) + etp-1 $etp_proc->common.id printf "\n State: " - etp-proc-state $arg0 - if (*(((Uint32 *) &(((Process *) $arg0)->state))) & 0x4) == 0 - if ($arg0->common.u.alive.reg) + etp-proc-state $etp_proc + if $proxy_process != 0 + printf " Pointer: (Process *) %p\n", $etp_proc + printf " *** PROXY process struct *** refer to: \n" + etp-pid2proc-1 $etp_proc->common.id + etp-process-info $proc + else + if (*(((Uint32 *) &($etp_proc->state))) & 0x4) == 0 + if ($etp_proc->common.u.alive.reg) printf " Registered name: " - etp-1 $arg0->common.u.alive.reg->name + etp-1 $etp_proc->common.u.alive.reg->name printf "\n" end end - if ($arg0->current) + if ($etp_proc->current) printf " Current function: " - etp-1 $arg0->current[0] + etp-1 $etp_proc->current[0] printf ":" - etp-1 $arg0->current[1] - printf "/%d\n", $arg0->current[2] + etp-1 $etp_proc->current[1] + printf "/%d\n", $etp_proc->current[2] end - if ($arg0->cp) + if ($etp_proc->cp) printf " CP: " - etp-cp-1 $arg0->cp + etp-cp-1 $etp_proc->cp printf "\n" end - if ($arg0->i) + if ($etp_proc->i) printf " I: " - etp-cp-1 $arg0->i + etp-cp-1 $etp_proc->i printf "\n" end - printf " Heap size: %ld\n", $arg0->heap_sz - if ($arg0->old_heap) - printf " Old-heap size: %ld\n", $arg0->old_hend - $arg0->old_heap + printf " Heap size: %ld\n", $etp_proc->heap_sz + if ($etp_proc->old_heap) + printf " Old-heap size: %ld\n", $etp_proc->old_hend - $etp_proc->old_heap end - printf " Mbuf size: %ld\n", $arg0->mbuf_sz + printf " Mbuf size: %ld\n", $etp_proc->mbuf_sz if (etp_smp_compiled) - printf " Msgq len: %ld (inner=%ld, outer=%ld)\n", ($arg0->msg.len + $arg0->msg_inq.len), $arg0->msg.len, $arg0->msg_inq.len + printf " Msgq len: %ld (inner=%ld, outer=%ld)\n", ($etp_proc->msg.len + $etp_proc->msg_inq.len), $etp_proc->msg.len, $etp_proc->msg_inq.len else - printf " Msgq len: %d\n", $arg0->msg.len + printf " Msgq len: %d\n", $etp_proc->msg.len end printf " Parent: " - etp-1 $arg0->parent - printf "\n Pointer: (Process *) %p\n", $arg0 + etp-1 $etp_proc->parent + printf "\n Pointer: (Process *) %p\n", $etp_proc + end end document etp-process-info @@ -1463,15 +1886,109 @@ end document etp-processes %--------------------------------------------------------------------------- % etp-processes -% +% % Print misc info about all processes %--------------------------------------------------------------------------- end +define etp-processes-memory + if (!erts_initialized) + printf "No processes, since system isn't initialized!\n" + else + set $proc_ix = 0 + printf "--- (%ld processes in wheel)\n", erts_proc.r.o.max + while $proc_ix < erts_proc.r.o.max + set $proc = (Process *) *((UWord *) &erts_proc.r.o.tab[$proc_ix]) + if ($proc != ((Process *) 0) && $proc != &erts_invalid_process) + etp-process-memory-info $proc + end + set $proc_ix++ + end + printf "---\n", + end +end + +document etp-processes-memory +%--------------------------------------------------------------------------- +% etp-processes-memory +% +% Print memory info about all processes +%--------------------------------------------------------------------------- +end + +define etp-process-memory-info +# Args: Process* +# + set $etp_pmem_proc = ((Process *) $arg0) + if ((*(((Uint32 *) &($etp_pmem_proc->state)))) & 0x400000) + set $proxy_process = 1 + else + set $proxy_process = 0 + end + printf " " + etp-1 $etp_pmem_proc->common.id + printf ": (Process *) %p ", $etp_pmem_proc + if $proxy_process != 0 + printf "(Process *) %p ", $etp_pmem_proc + printf " *** PROXY process struct *** refer to next: \n" + etp-pid2proc-1 $etp_pmem_proc->common.id + printf " -" + etp-process-memory-info $proc + else + printf " [Heap: %5ld", $etp_pmem_proc->heap_sz + if ($etp_pmem_proc->old_heap) + printf " | %5ld", $etp_pmem_proc->old_hend - $etp_pmem_proc->old_heap + else + printf " | none " + end + printf "] [Mbuf: %5ld", $etp_pmem_proc->mbuf_sz + if (etp_smp_compiled) + printf " | %3ld (%3ld | %3ld)", ($etp_pmem_proc->msg.len + $etp_pmem_proc->msg_inq.len), $etp_pmem_proc->msg.len, $etp_pmem_proc->msg_inq.len + else + printf " | %3ld", $etp_pmem_proc->msg.len + end + printf "] " + if ($etp_pmem_proc->i) + printf " I: " + etp-cp-1 $etp_pmem_proc->i + printf " " + end + + if ($etp_pmem_proc->current) + etp-1 $etp_pmem_proc->current[0] + printf ":" + etp-1 $etp_pmem_proc->current[1] + printf "/%d ", $etp_pmem_proc->current[2] + end + + if (*(((Uint32 *) &(((Process *) $etp_pmem_proc)->state))) & 0x4) == 0 + if ($etp_pmem_proc->common.u.alive.reg) + etp-1 $etp_pmem_proc->common.u.alive.reg->name + printf " " + end + end + + if ($etp_pmem_proc->cp) + printf " CP: " + etp-cp-1 $etp_pmem_proc->cp + printf " " + end + printf "\n" + end +end + +document etp-process-memory-info +%--------------------------------------------------------------------------- +% etp-process-memory-info Process* +% +% Print memory info about process +%--------------------------------------------------------------------------- +end + define etp-port-id2pix-1 # Args: Eterm # - if (etp_arch_bits == 64 && etp_halfword == 0) + if (etp_arch_bits == 64) if (etp_big_endian) set $etp_pix = (int) (((Uint64) $arg0) & 0x0fffffff) elser @@ -1651,23 +2168,24 @@ define etp-port-info # Args: Port* # printf " Port: " - etp-1 $arg0->common.id - printf "\n Name: %s\n", $arg0->name + set $etp_pinfo_port = ((Port*)$arg0) + etp-1 $etp_pinfo_port->common.id + printf "\n Name: %s\n", $etp_pinfo_port->name printf " State:" - etp-port-state $arg0 + etp-port-state $etp_pinfo_port printf " Scheduler flags:" - etp-port-sched-flags $arg0 - if (*(((Uint32 *) &(((Port *) $arg0)->state))) & 0x5C00) == 0 - if ($arg0->common.u.alive.reg) + etp-port-sched-flags $etp_pinfo_port + if (*(((Uint32 *) &($etp_pinfo_port->state))) & 0x5C00) == 0 + if ($etp_pinfo_port->common.u.alive.reg) printf " Registered name: " - etp-1 $arg0->common.u.alive.reg->name + etp-1 $etp_pinfo_port->common.u.alive.reg->name printf "\n" end end printf " Connected: " - set $connected = *(((Eterm *) &(((Port *) $arg0)->connected))) + set $connected = *(((Eterm *) &(((Port *) $etp_pinfo_port)->connected))) etp-1 $connected - printf "\n Pointer: (Port *) %p\n", $arg0 + printf "\n Pointer: (Port *) %p\n", $etp_pinfo_port end document etp-port-info @@ -1992,19 +2510,13 @@ define etp-system-info printf "ERTS version: %s\n", etp_erts_version printf "Compile date: %s\n", etp_compile_date printf "Arch: %s\n", etp_arch - printf "Endianess: " + printf "Endianness: " if (etp_big_endian) printf "Big\n" else printf "Little\n" end printf "Word size: %d-bit\n", etp_arch_bits - printf "Halfword: " - if (etp_halfword) - printf "yes\n" - else - printf "no\n" - end printf "HiPE support: " if (etp_hipe) printf "yes\n" @@ -2075,6 +2587,33 @@ document etp-system-info %--------------------------------------------------------------------------- end +define etp-compile-info + printf "--------------- Compile Information ---------------\n" + printf "CFLAGS: %s\n", erts_build_flags_CFLAGS + printf "LDFLAGS: %s\n", erts_build_flags_LDFLAGS + printf "Use etp-config-h-info to dump config.h\n" +end + +document etp-compile-info +%--------------------------------------------------------------------------- +% etp-compile-info +% +% Print information about how the system was compiled +%--------------------------------------------------------------------------- +end + +define etp-config-h-info + printf "%s", erts_build_flags_CONFIG_H +end + +document etp-config-h-info +%--------------------------------------------------------------------------- +% etp-config-h-info +% +% Dump the contents of config.h when the system was compiled +%--------------------------------------------------------------------------- +end + define etp-dictdump # Args: ProcDict* # @@ -2406,6 +2945,152 @@ document etp-search-alloc end +define etp-alloc-stats + printf "\nIx Name Inst. Blocks Bytes Carriers Crr.bytes Util\n" + set $etp_tot_block_no = 0 + set $etp_tot_block_sz = 0 + set $etp_tot_crr_no = 0 + set $etp_tot_crr_sz = 0 + set $etp_ERTS_ALC_A_MIN = 1 + set $etp_ERTS_ALC_A_MAX = (sizeof(erts_allctrs) / sizeof(*erts_allctrs)) - 1 + + set $etp_ix = $etp_ERTS_ALC_A_MIN + while $etp_ix <= $etp_ERTS_ALC_A_MAX + set $etp_allctr = 0 + set $etp_alloc = erts_allctrs[$etp_ix].alloc + if $etp_alloc != erts_sys_alloc + if $etp_alloc == erts_alcu_alloc_thr_spec || \ + $etp_alloc == erts_alcu_alloc_thr_pref + set $etp_instance = 0 + set $etp_block_no = 0 + set $etp_block_sz = 0 + set $etp_crr_no = 0 + set $etp_crr_sz = 0 + set $etp_tspec = (ErtsAllocatorThrSpec_t *) erts_allctrs[$etp_ix].extra + if $etp_tspec->enabled + while $etp_instance < $etp_tspec->size + set $etp_allctr = $etp_tspec->allctr[$etp_instance] + set $etp_block_no = $etp_block_no + $etp_allctr->mbcs.blocks.curr.no \ + + $etp_allctr->sbcs.blocks.curr.no + set $etp_block_sz = $etp_block_sz + $etp_allctr->mbcs.blocks.curr.size \ + + $etp_allctr->sbcs.blocks.curr.size + set $etp_crr_no = $etp_crr_no + $etp_allctr->mbcs.curr.norm.mseg.no \ + + $etp_allctr->sbcs.curr.norm.mseg.no \ + + $etp_allctr->mbcs.curr.norm.sys_alloc.no \ + + $etp_allctr->sbcs.curr.norm.sys_alloc.no + set $etp_crr_sz = $etp_crr_sz + $etp_allctr->mbcs.curr.norm.mseg.size \ + + $etp_allctr->sbcs.curr.norm.mseg.size \ + + $etp_allctr->mbcs.curr.norm.sys_alloc.size \ + + $etp_allctr->sbcs.curr.norm.sys_alloc.size + set $etp_instance = $etp_instance + 1 + end + else + printf "erts_allctr[%d]: Disabled (thread specific)\n", $etp_ix + end + else + if $etp_alloc == erts_alcu_alloc_ts || $etp_alloc == erts_alcu_alloc + set $etp_allctr = (Allctr_t*) erts_allctrs[$etp_ix].extra + set $etp_block_no = $etp_allctr->mbcs.blocks.curr.no \ + + $etp_allctr->sbcs.blocks.curr.no + set $etp_block_sz = $etp_allctr->mbcs.blocks.curr.size \ + + $etp_allctr->sbcs.blocks.curr.size + set $etp_crr_no = $etp_allctr->mbcs.curr.norm.mseg.no \ + + $etp_allctr->sbcs.curr.norm.mseg.no \ + + $etp_allctr->mbcs.curr.norm.sys_alloc.no \ + + $etp_allctr->sbcs.curr.norm.sys_alloc.no + set $etp_crr_sz = $etp_allctr->mbcs.curr.norm.mseg.size \ + + $etp_allctr->sbcs.curr.norm.mseg.size \ + + $etp_allctr->mbcs.curr.norm.sys_alloc.size \ + + $etp_allctr->sbcs.curr.norm.sys_alloc.size + set $etp_instance = 1 + else + printf "erts_allctr[%d]: Unknown allocation function: ", $etp_ix + p $etp_alloc + end + end + end + if $etp_allctr != 0 + printf "%2d %-8s%2d%12lu%13lu%12lu%13lu", $etp_ix, $etp_allctr->name_prefix, \ + $etp_instance, \ + $etp_block_no, $etp_block_sz, $etp_crr_no, $etp_crr_sz + if $etp_crr_sz != 0 + printf "%5lu%%", ($etp_block_sz * 100) / $etp_crr_sz + end + printf "\n" + set $etp_tot_block_no = $etp_tot_block_no + $etp_block_no + set $etp_tot_block_sz = $etp_tot_block_sz + $etp_block_sz + set $etp_tot_crr_no = $etp_tot_crr_no + $etp_crr_no + set $etp_tot_crr_sz = $etp_tot_crr_sz + $etp_crr_sz + end + set $etp_ix = $etp_ix + 1 + end + printf "\nTotal: %12lu%13lu%12lu%13lu", $etp_tot_block_no, $etp_tot_block_sz, \ + $etp_tot_crr_no, $etp_tot_crr_sz + if $etp_tot_crr_sz != 0 + printf "%5lu%%", ($etp_tot_block_sz * 100) / $etp_tot_crr_sz + end + printf "\n" +end + +document etp-alloc-stats +%--------------------------------------------------------------------------- +% etp-alloc-stats +% +% Combine and print allocator statistics +%--------------------------------------------------------------------------- +end + + +define etp-alloc-instances + set $etp_ERTS_ALC_A_MIN = 1 + set $etp_ERTS_ALC_A_MAX = (sizeof(erts_allctrs) / sizeof(*erts_allctrs)) - 1 + + set $etp_ix = $arg0 + if $etp_ix >= $etp_ERTS_ALC_A_MIN && $etp_ix <= $etp_ERTS_ALC_A_MAX + set $etp_allctr = 0 + set $etp_alloc = erts_allctrs[$etp_ix].alloc + if $etp_alloc == erts_sys_alloc + printf "Allocator %d is sys_alloc\n", $etp_ix + else + if $etp_alloc == erts_alcu_alloc_thr_spec || \ + $etp_alloc == erts_alcu_alloc_thr_pref + set $etp_instance = 0 + set $etp_tspec = (ErtsAllocatorThrSpec_t *) erts_allctrs[$etp_ix].extra + if $etp_tspec->enabled + printf "All instances for allocator '%s'\n", $etp_tspec->allctr[0]->name_prefix + while $etp_instance < $etp_tspec->size + p $etp_tspec->allctr[$etp_instance] + set $etp_instance = $etp_instance + 1 + end + else + printf "erts_allctr[%d]: Disabled (thread specific)\n", $etp_ix + end + else + if $etp_alloc == erts_alcu_alloc_ts || $etp_alloc == erts_alcu_alloc + set $etp_allctr = (Allctr_t*) erts_allctrs[$etp_ix].extra + printf "Single instances for allocator '%s'\n", $etp_allctr->name_prefix + p $etp_allctr + else + printf "erts_allctr[%d]: Unknown allocation function: ", $etp_ix + p $etp_alloc + end + end + end + else + printf "Allocator type not between %d and %d\n", $etp_ERTS_ALC_A_MIN, $etp_ERTS_ALC_A_MAX + end +end + +document etp-alloc-instances +%--------------------------------------------------------------------------- +% etp-alloc-instances +% +% Print pointers to all allocator instances for a specific type (Ix) +%--------------------------------------------------------------------------- +end + + + define etp-overlapped-heaps # Args: @@ -2709,6 +3394,95 @@ document etp-ets-tabledump %--------------------------------------------------------------------------- end +define etp-lc-dump +# Non-reentrant + set $etp_lc_dump_thread = erts_locked_locks + while $etp_lc_dump_thread + printf "Thread %s\n", $etp_lc_dump_thread->thread_name + set $etp_lc_dump_thread_locked = $etp_lc_dump_thread->locked.first + while $etp_lc_dump_thread_locked + if 0 <= $etp_lc_dump_thread_locked->id && $etp_lc_dump_thread_locked->id < sizeof(erts_lock_order)/sizeof(erts_lc_lock_order_t) + printf " %s:", erts_lock_order[$etp_lc_dump_thread_locked->id].name + else + printf " unkown:" + end + if ($etp_lc_dump_thread_locked->extra & 0x3) == 0x3 + etp-1 $etp_lc_dump_thread_locked->extra + else + printf "%p", $etp_lc_dump_thread_locked->extra + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 0) + printf "[spinlock]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 1) + printf "[rw(spin)lock]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 2) + printf "[mutex]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 3) + printf "[rwmutex]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 4) + printf "[proclock]" + end + printf "(%s:%d)", $etp_lc_dump_thread_locked->file, $etp_lc_dump_thread_locked->line + if ($etp_lc_dump_thread_locked->flags & (0x60)) == (1 << 5) + printf "(r)" + end + if ($etp_lc_dump_thread_locked->flags & (0x60)) == ((1 << 5) | (1 << 6)) + printf "(rw)" + end + printf "\n" + set $etp_lc_dump_thread_locked = $etp_lc_dump_thread_locked->next + end + set $etp_lc_dump_thread = $etp_lc_dump_thread->next + end +end + +document etp-lc-dump +%--------------------------------------------------------------------------- +% etp-lc-dump +% +% Dump all info about locks in the lock checker +%--------------------------------------------------------------------------- +end + +define etp-ppc-stacktrace +# Args: R1 +# Non-reentrant + set $etp_ppc_st_fp = ($arg0) + while $etp_ppc_st_fp + info symbol ((void**)$etp_ppc_st_fp)[1] + set $etp_ppc_st_fp = ((void**)$etp_ppc_st_fp)[0] + end +end + +document etp-ppc-stacktrace +%--------------------------------------------------------------------------- +% etp-ppc-stacktrace R1 +% +% Dump stacktrace from given $r1 frame pointer +%--------------------------------------------------------------------------- +end + +############################################################################ +# OSE support +# +define etp-ose-attach + target ose $arg0:21768 + attach block start_beam start_beam +end + +document etp-ose-attach +%--------------------------------------------------------------------------- +% etp-ose-attach Host +% +% Connect and attach to erlang vm at Host. +%--------------------------------------------------------------------------- +end + + ############################################################################ # Erlang support module handling # @@ -2730,6 +3504,220 @@ document etp-run %--------------------------------------------------------------------------- end +define etp-thr + source @ERL_TOP@/erts/etc/unix/etp-thr.py +end + +############################################################################ +# erl_alloc_util (blocks and carriers) +# + +define etp-block-size-1 +# +# In: (Block_t*) in $arg0 +# Out: Byte size in $etp_blk_sz +# + if ($arg0)->bhdr & 1 + # Free block + set $etp_blk_sz = ($arg0)->bhdr & ~7 + else + # Allocated block + if !$etp_MBC_ABLK_SZ_MASK + if etp_arch_bits == 64 + set $etp_MBC_ABLK_OFFSET_SHIFT = (64 - 24) + else + set $etp_MBC_ABLK_OFFSET_SHIFT = (32 - 9) + end + set $etp_MBC_ABLK_SZ_MASK = ((UWord)1 << $etp_MBC_ABLK_OFFSET_SHIFT) - 1 - 7 + end + set $etp_blk_sz = ($arg0)->bhdr & $etp_MBC_ABLK_SZ_MASK + end +end + +define etp-block2mbc-1 +# +# In: (Block_t*) in $arg0 +# Out: (Carrier_t*) in $etp-mbc +# + if (($arg0)->bhdr) & 1 + # Free block + set $etp_mbc = ($arg0)->u.carrier + else + # Allocated block + if !$etp_MBC_ABLK_OFFSET_SHIFT + if etp_arch_bits == 64 + set $etp_MBC_ABLK_OFFSET_SHIFT = (64 - 24) + else + set $etp_MBC_ABLK_OFFSET_SHIFT = (32 - 9) + end + end + set $etp_mbc = (Carrier_t*) ((((UWord)($arg0) >> 18) - (($arg0)->bhdr >> $etp_MBC_ABLK_OFFSET_SHIFT)) << 18) + end +end + +define etp-block2mbc + etp-block2mbc-1 ((Block_t*)$arg0) + print $etp_mbc +end + +document etp-block2mbc +%--------------------------------------------------------------------------- +% Print pointer to multiblock carrier containing the argument (Block_t*) +%--------------------------------------------------------------------------- +end + +define etp-block + etp-block-size-1 ((Block_t*)$arg0) + if ((Block_t*)$arg0)->bhdr & 1 + printf "%#lx: FREE sz=%#x\n", ($arg0), $etp_blk_sz + else + printf "%#lx: ALLOCATED sz=%#x\n", ($arg0), $etp_blk_sz + end +end + +document etp-block +%--------------------------------------------------------------------------- +% Print memory block (Block_t*) +%--------------------------------------------------------------------------- +end + +define etp-carrier-blocks + set $etp_crr = (Carrier_t*) $arg0 + set $etp_alc = (Allctr_t*)($etp_crr->allctr.counter & ~7) + set $etp_crr_end = ((char*)$etp_crr + ($etp_crr->chdr & ~7) - (sizeof(void*) & ~8)) + set $etp_blk = (Block_t*) ((char*)$etp_crr + $etp_alc->mbc_header_size) + set $etp_prev_blk = 0 + set $etp_error_cnt = 0 + set $etp_ablk_cnt = 0 + set $etp_fblk_cnt = 0 + set $etp_aborted = 0 + + if $argc == 2 + set $etp_be_silent = $arg1 + else + set $etp_be_silent = 0 + end + + while 1 + if !$etp_be_silent + etp-block $etp_blk + else + etp-block-size-1 $etp_blk + end + etp-block2mbc-1 $etp_blk + if $etp_mbc != $etp_crr + printf "ERROR: Invalid carrier pointer %#lx in block at %#lx\n", $etp_mbc, $etp_blk + set $etp_error_cnt = $etp_error_cnt + 1 + end + if $etp_prev_blk + if ($etp_prev_blk->bhdr & 1) + # Prev is FREE + if ($etp_blk->bhdr & 1) + printf "ERROR: Adjacent FREE blocks at %#lx and %#lx\n", $etp_prev_blk, $etp_blk + set $etp_error_cnt = $etp_error_cnt + 1 + end + if !($etp_blk->bhdr & 2) + printf "ERROR: Missing PREV_FREE_BLK_HDR_FLG (2) in block at %#lx\n", $etp_blk + set $etp_error_cnt = $etp_error_cnt + 1 + end + end + end + if $etp_blk->bhdr & 1 + set $etp_fblk_cnt = $etp_fblk_cnt + 1 + else + set $etp_ablk_cnt = $etp_ablk_cnt + 1 + end + if $etp_blk->bhdr & 4 + # Last block + loop_break + end + # All free blocks except the last have a footer + if ($etp_blk->bhdr & 1) && ((UWord*)((char*)$etp_blk + $etp_blk_sz))[-1] != $etp_blk_sz + printf "ERROR: Invalid footer of free block at %#lx\n", $etp_blk + end + set $etp_prev_blk = $etp_blk + set $etp_blk = (Block_t*) ((char*)$etp_blk + $etp_blk_sz) + if $etp_blk < (Block_t*) ((char*)$etp_prev_blk + $etp_alc->min_block_size) || $etp_blk >= $etp_crr_end + printf "ERROR: Invalid size of block at %#lx. ABORTING\n", $etp_prev_blk + set $etp_aborted = 1 + loop_break + end + end + + if !$etp_aborted + if ((char*)$etp_blk + $etp_blk_sz) != $etp_crr_end + printf "ERROR: Last block not at end of carrier\n" + set $etp_error_cnt = $etp_error_cnt + 1 + end + printf "Allocated blocks: %u\n", $etp_ablk_cnt + printf "Free blocks: %u\n", $etp_fblk_cnt + end + if $etp_error_cnt + printf "%u ERRORs reported above\n", $etp_error_cnt + end +end + +document etp-carrier-blocks +%--------------------------------------------------------------------------- +% Check and (maybe) print all memory blocks in carrier +% Args: (Carrier_t*) [1=be_silent] +%--------------------------------------------------------------------------- +end + +define etp-address-to-beam-opcode + set $etp_i = 0 + set $etp_min_diff = ((UWord)1 << (sizeof(UWord)*8 - 1)) + set $etp_min_opcode = -1 + set $etp_addr = (UWord) ($arg0) + + while $etp_i < num_instructions && $etp_min_diff > 0 + if ($etp_addr - (UWord)beam_ops[$etp_i]) < $etp_min_diff + set $etp_min_diff = $etp_addr - (UWord)beam_ops[$etp_i] + set $etp_min_opcode = $etp_i + end + set $etp_i = $etp_i + 1 + end + if $etp_min_diff == 0 + printf "Address %p is start of '%s'\n", $etp_addr, opc[$etp_min_opcode].name + else + if $etp_min_opcode >= 0 + printf "Address is %ld bytes into opcode '%s' at %p\n", $etp_min_diff, opc[$etp_min_opcode].name, beam_ops[$etp_min_opcode] + else + printf "Invalid opcode address\n" + end + end +end + +document etp-address-to-beam-opcode +%--------------------------------------------------------------------------- +% Get beam opcode from a native instruction address (within process_main()) +% Arg: Instructon pointer value +% +% Does not work with NO_JUMP_TABLE +%--------------------------------------------------------------------------- +end + +define etp-compile-debug + shell (cd $ERL_TOP && make emulator FLAVOR=smp TYPE=debug) +end + +document etp-compile-debug +%--------------------------------------------------------------------------- +% Re-compile the debug erlang emulator +%--------------------------------------------------------------------------- +end + +define etp-compile + shell (cd $ERL_TOP && make emulator) +end + +document etp-compile +%--------------------------------------------------------------------------- +% Re-compile the erlang emulator +%--------------------------------------------------------------------------- +end + + ############################################################################ # Toolbox parameter handling # diff --git a/erts/etc/unix/etp-thr.py b/erts/etc/unix/etp-thr.py new file mode 100644 index 0000000000..fb82dcaf1f --- /dev/null +++ b/erts/etc/unix/etp-thr.py @@ -0,0 +1,56 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2013-2016. All Rights Reserved. +# +# 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% +# + +def get_thread_name(t): + f = gdb.newest_frame(); + while f: + if f.name() == "async_main": + return "async"; + elif f.name() == "erts_sys_main_thread": + return "main"; + elif f.name() == "signal_dispatcher_thread_func": + return "signal_dispatcher"; + elif f.name() == "sys_msg_dispatcher_func": + return "sys_msg_dispatcher"; + elif f.name() == "child_waiter": + return "child_waiter"; + elif f.name() == "sched_thread_func": + return "scheduler"; + elif f.name() == "aux_thread": + return "aux"; + f = f.older(); + return "unknown"; + + +curr_thread = gdb.selected_thread(); + +for i in gdb.inferiors(): + gdb.write(" Id Thread Name Frame\n"); + for t in i.threads(): + t.switch(); + if curr_thread == t: + gdb.write("*"); + else: + gdb.write(" "); + gdb.write("{0:<3} {1:20} {2}\n".format( + t.num,get_thread_name(t), + gdb.newest_frame().name())); + +curr_thread.switch(); diff --git a/erts/etc/unix/etp_commands.erl b/erts/etc/unix/etp_commands.erl index 66cb76edbc..fe8f2dd556 100644 --- a/erts/etc/unix/etp_commands.erl +++ b/erts/etc/unix/etp_commands.erl @@ -1,18 +1,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. +%% Copyright Ericsson AB 2005-2016. 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/unix/etp_commands.mk b/erts/etc/unix/etp_commands.mk index 1d9a269b68..983ee9f919 100644 --- a/erts/etc/unix/etp_commands.mk +++ b/erts/etc/unix/etp_commands.mk @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2005-2009. All Rights Reserved. +# Copyright Ericsson AB 2005-2016. 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/unix/format_man_pages b/erts/etc/unix/format_man_pages index 93dcdcd8fa..54f2d90c28 100644 --- a/erts/etc/unix/format_man_pages +++ b/erts/etc/unix/format_man_pages @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2010. All Rights Reserved. +# Copyright Ericsson AB 1996-2016. 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/unix/run_erl.c b/erts/etc/unix/run_erl.c index 53c779b1be..30210ac172 100644 --- a/erts/etc/unix/run_erl.c +++ b/erts/etc/unix/run_erl.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2015. 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% */ @@ -41,7 +42,14 @@ # include "config.h" #endif #ifdef HAVE_WORKING_POSIX_OPENPT -#define _XOPEN_SOURCE 600 +# ifndef _XOPEN_SOURCE + /* On OS X and BSD, we must leave _XOPEN_SOURCE undefined in order for + * the prototype of vsyslog() to be included. + */ +# if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)) +# define _XOPEN_SOURCE 600 +# endif +# endif #endif #include <sys/types.h> #include <sys/wait.h> @@ -60,7 +68,8 @@ #include <dirent.h> #include <termios.h> #include <time.h> -#ifndef NO_SYSLOG + +#ifdef HAVE_SYSLOG_H # include <syslog.h> #endif #ifdef HAVE_PTY_H @@ -69,6 +78,9 @@ #ifdef HAVE_UTMP_H # include <utmp.h> #endif +#ifdef HAVE_LIBUTIL_H +# include <libutil.h> +#endif #ifdef HAVE_UTIL_H # include <util.h> #endif @@ -197,8 +209,9 @@ static char* outbuf_in; #endif -#ifdef NO_SYSLOG +#ifndef HAVE_SYSLOG_H # define OPEN_SYSLOG() ((void) 0) +# define LOG_ERR NULL #else # define OPEN_SYSLOG() openlog(simple_basename(program_name), \ LOG_PID|LOG_CONS|LOG_NOWAIT,LOG_USER) @@ -415,7 +428,7 @@ int main(int argc, char **argv) } #endif -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H /* Before fiddling with file descriptors we make sure syslog is turned off or "closed". In the single case where we might want it again, we will open it again instead. Would not want syslog to @@ -1142,6 +1155,14 @@ static void daemon_init(void) sf_close(i); } + /* Necessary on some platforms */ + + open("/dev/null", O_RDONLY); /* Order is important! */ + open("/dev/null", O_WRONLY); + open("/dev/null", O_WRONLY); + + errno = 0; /* if set by open */ + OPEN_SYSLOG(); run_daemon = 1; } @@ -1155,7 +1176,7 @@ static void error_logf(int priority, int line, const char *format, ...) va_list args; va_start(args, format); -#ifndef NO_SYSLOG +#ifdef HAVE_SYSLOG_H if (run_daemon) { vsyslog(priority,format,args); } diff --git a/erts/etc/unix/run_erl.h b/erts/etc/unix/run_erl.h index 843cda680c..83bdfdfb19 100644 --- a/erts/etc/unix/run_erl.h +++ b/erts/etc/unix/run_erl.h @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-2016. 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/unix/safe_string.c b/erts/etc/unix/safe_string.c index a77d9c5456..666022dc61 100644 --- a/erts/etc/unix/safe_string.c +++ b/erts/etc/unix/safe_string.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-2016. 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/unix/safe_string.h b/erts/etc/unix/safe_string.h index c70e528814..cafd3fc71a 100644 --- a/erts/etc/unix/safe_string.h +++ b/erts/etc/unix/safe_string.h @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-2016. 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/unix/setuid_socket_wrap.c b/erts/etc/unix/setuid_socket_wrap.c index 3f0657770c..461c69ee3e 100644 --- a/erts/etc/unix/setuid_socket_wrap.c +++ b/erts/etc/unix/setuid_socket_wrap.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1999-2009. All Rights Reserved. + * Copyright Ericsson AB 1999-2016. 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/unix/start.src b/erts/etc/unix/start.src index 8479be0987..bdd146951f 100644 --- a/erts/etc/unix/start.src +++ b/erts/etc/unix/start.src @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2009. All Rights Reserved. +# Copyright Ericsson AB 1996-2016. 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/unix/start_erl.src b/erts/etc/unix/start_erl.src index ea8022c449..34e0369710 100644 --- a/erts/etc/unix/start_erl.src +++ b/erts/etc/unix/start_erl.src @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2009. All Rights Reserved. +# Copyright Ericsson AB 1997-2016. 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/unix/to_erl.c b/erts/etc/unix/to_erl.c index 0f27b64811..0bd469727c 100644 --- a/erts/etc/unix/to_erl.c +++ b/erts/etc/unix/to_erl.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2015. 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% */ @@ -339,13 +340,13 @@ int main(int argc, char **argv) tty_smode.c_cc[VTIME] =0;/* Note that VTIME is the same as VEOL! */ tty_smode.c_cc[VINTR] =3; - tcsetattr(0, TCSANOW, &tty_smode); + tcsetattr(0, TCSADRAIN, &tty_smode); #ifdef DEBUG show_terminal_settings(&tty_smode); #endif /* - * "Write a ^R to the FIFO which causes the other end to redisplay + * "Write a ^L to the FIFO which causes the other end to redisplay * the input line." * This does not seem to work as was intended in old comment above. * However, this control character is now (R12B-3) used by run_erl @@ -354,7 +355,7 @@ int main(int argc, char **argv) */ if (write(wfd, "\014", 1) < 0) { - fprintf(stderr, "Error in writing ^R to FIFO.\n"); + fprintf(stderr, "Error in writing ^L to FIFO.\n"); } /* @@ -484,7 +485,7 @@ int main(int argc, char **argv) * Reset terminal characterstics * XXX */ - tcsetattr(0, TCSANOW, &tty_rmode); + tcsetattr(0, TCSADRAIN, &tty_rmode); return 0; } @@ -526,7 +527,7 @@ static int window_size_seq(char* buf, size_t bufsz) /* to_erl run_erl * | | - * |---------- '\022' -------->| (session start) + * |---------- '\014' -------->| (session start) * | | * |<---- "[run_erl v1-0]" ----| (version interval) * | | diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c index dd02a9c111..43930ff284 100644 --- a/erts/etc/win32/Install.c +++ b/erts/etc/win32/Install.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2013. All Rights Reserved. + * Copyright Ericsson AB 2003-2016. 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% */ @@ -21,80 +22,83 @@ * Dead simple installation program to set up init files etc after erlang is * copied to its destination. Also to be used after a patch is applied. */ + #include <windows.h> #include <stdio.h> #include <stdlib.h> #include "init_file.h" -int main(int argc, char **argv) +int wmain(int argc, wchar_t **argv) { int silent = 0; int start_sasl = 0; - char *root = NULL; + wchar_t *root = NULL; int i; - char buffer[MAX_PATH]; - char erts_dir[MAX_PATH]; - char release_dir[MAX_PATH]; - char bin_dir[MAX_PATH]; + wchar_t buffer[MAX_PATH]; + wchar_t erts_dir[MAX_PATH]; + wchar_t release_dir[MAX_PATH]; + wchar_t bin_dir[MAX_PATH]; char *tmp; - char my_ini_filename[MAX_PATH]; + char tmp_utf8[MAX_PATH*4]; + wchar_t my_ini_filename[MAX_PATH]; InitFile *my_ini_file; InitSection *my_ini_section; - char version_string[MAX_PATH]; + char erts_version[MAX_PATH]; InitFile *ini_file; InitSection *ini_section; HANDLE module = GetModuleHandle(NULL); - char *binaries[] = { "erl.exe", "werl.exe", "erlc.exe", - "dialyzer.exe", "typer.exe", - "escript.exe", "ct_run.exe", NULL }; - char *scripts[] = { "start_clean.boot", "start_sasl.boot", NULL }; - char fromname[MAX_PATH]; - char toname[MAX_PATH]; - + wchar_t *binaries[] = { L"erl.exe", L"werl.exe", L"erlc.exe", + L"dialyzer.exe", L"typer.exe", + L"escript.exe", L"ct_run.exe", NULL }; + wchar_t *scripts[] = { L"start_clean.boot", L"start_sasl.boot", L"no_dot_erlang.boot", NULL }; + wchar_t fromname[MAX_PATH]; + wchar_t toname[MAX_PATH]; + size_t converted; for (i = 1; i < argc; ++i) { switch(argv[i][0]) { - case '-' : + case L'-' : switch(argv[i][1]) { - case 's' : + case L's' : silent = 1; break; default: - fprintf(stderr, "Unknown command switch %s\n", + fprintf(stderr, "Unknown command switch %S\n", argv[i]); exit(1); } break; - default: + default: { if (root != NULL) { fprintf(stderr, "Only one root directory can be specified, " - "parameter %s is illegal\n", + "parameter %S is illegal\n", argv[i]); exit(1); - } + } root = argv[i]; + } break; } } if (root == NULL) { - if (module = NULL) { + if (module == NULL) { fprintf(stderr, "Cannot GetModuleHandle()\n"); exit(1); } - if (GetModuleFileName(module,buffer,MAX_PATH) == 0) { + if (GetModuleFileNameW(module,buffer,MAX_PATH) == 0) { fprintf(stderr,"Could not GetModuleFileName()\n"); exit(1); } - i = strlen(buffer) - 1; - while ( i >= 0 && buffer[i] != '\\') { + i = wcslen(buffer) - 1; + while ( i >= 0 && buffer[i] != L'\\') { --i; } if (i < 0) { fprintf(stderr,"GetModuleFileName returned broken path\n"); exit(1); } - buffer[i] = '\0'; + buffer[i] = L'\0'; root = buffer; } @@ -122,79 +126,78 @@ int main(int argc, char **argv) start_sasl = 0; } } - sprintf(my_ini_filename,"%s\\Install.ini",root); + swprintf(my_ini_filename, MAX_PATH, L"%s\\Install.ini", root); my_ini_file = load_init_file(my_ini_filename); if (my_ini_file == NULL) { - fprintf(stderr,"Cannot open init file %s\n",my_ini_filename); + fprintf(stderr,"Cannot open init file %S\n",my_ini_filename); exit(1); } if ((my_ini_section = lookup_init_section(my_ini_file,"Install")) == NULL) { - fprintf(stderr,"No [Install] section in init file %s\n", + fprintf(stderr,"No [Install] section in init file %S\n", my_ini_filename); exit(1); } if ((tmp = lookup_init_entry(my_ini_section, "VSN")) == NULL) { - fprintf(stderr,"No key VSN in init file %s\n", + fprintf(stderr,"No key VSN in init file %S\n", my_ini_filename); exit(1); } - - strcpy(version_string,tmp); + strcpy(erts_version,tmp); - sprintf(erts_dir,"%s\\erts-%s\\bin",root,tmp); + swprintf(erts_dir,MAX_PATH,L"%s\\erts-%S\\bin",root,erts_version); if ((tmp = lookup_init_entry(my_ini_section, "SYSTEM_VSN")) == NULL) { - fprintf(stderr,"No key SYSTEM_VSN in init file %s\n", - my_ini_filename); + fprintf(stderr,"No key SYSTEM_VSN in init file %S\n", + my_ini_filename); exit(1); } - sprintf(release_dir,"%s\\releases\\%s",root,tmp); + swprintf(release_dir,MAX_PATH,L"%s\\releases\\%S",root,tmp); - sprintf(bin_dir,"%s\\bin",root); - CreateDirectory(bin_dir,NULL); + swprintf(bin_dir,MAX_PATH,L"%s\\bin",root); + CreateDirectoryW(bin_dir,NULL); free_init_file(my_ini_file); for (i = 0; binaries[i] != NULL; ++i) { - sprintf(fromname,"%s\\%s",erts_dir,binaries[i]); - sprintf(toname,"%s\\%s",bin_dir,binaries[i]); - if (GetFileAttributes(fromname) == 0xFFFFFFFF) { - fprintf(stderr,"Could not find file %s\n", + swprintf(fromname,MAX_PATH,L"%s\\%s",erts_dir,binaries[i]); + swprintf(toname,MAX_PATH,L"%s\\%s",bin_dir,binaries[i]); + if (GetFileAttributesW(fromname) == 0xFFFFFFFF) { + fprintf(stderr,"Could not find file %S\n", fromname); exit(1); } - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", fromname,toname); fprintf(stderr,"Continuing installation anyway...\n"); } } for (i = 0; scripts[i] != NULL; ++i) { - sprintf(fromname,"%s\\%s",release_dir,scripts[i]); - sprintf(toname,"%s\\%s",bin_dir,scripts[i]); - if (GetFileAttributes(fromname) == 0xFFFFFFFF) { - fprintf(stderr,"Could not find file %s\n", + swprintf(fromname,MAX_PATH,L"%s\\%s",release_dir,scripts[i]); + swprintf(toname,MAX_PATH,L"%s\\%s",bin_dir,scripts[i]); + if (GetFileAttributesW(fromname) == 0xFFFFFFFF) { + fprintf(stderr,"Could not find file %S\n", fromname); exit(1); } - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", fromname,toname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); } } if (start_sasl) { - sprintf(fromname,"%s\\start_sasl.boot",bin_dir); + swprintf(fromname,MAX_PATH,L"%s\\start_sasl.boot",bin_dir); } else { - sprintf(fromname,"%s\\start_clean.boot",bin_dir); + swprintf(fromname,MAX_PATH,L"%s\\start_clean.boot",bin_dir); } - sprintf(toname,"%s\\start.boot",bin_dir); - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", + swprintf(toname,MAX_PATH,L"%s\\start.boot",bin_dir); + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", fromname,toname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); @@ -205,25 +208,27 @@ int main(int argc, char **argv) ini_file = create_init_file(); ini_section = create_init_section("erlang"); add_init_section(ini_file,ini_section); - add_init_entry(ini_section,"Bindir",erts_dir); + WideCharToMultiByte(CP_UTF8,0,erts_dir,-1,tmp_utf8,MAX_PATH*4,NULL,NULL); + add_init_entry(ini_section,"Bindir",tmp_utf8); add_init_entry(ini_section,"Progname","erl"); - add_init_entry(ini_section,"Rootdir",root); - sprintf(fromname,"%s\\erl.ini",erts_dir); - sprintf(toname,"%s\\erl.ini",bin_dir); + WideCharToMultiByte(CP_UTF8,0,root,-1,tmp_utf8,MAX_PATH*4,NULL,NULL); + add_init_entry(ini_section,"Rootdir",tmp_utf8); + swprintf(fromname,MAX_PATH,L"%s\\erl.ini",erts_dir); + swprintf(toname,MAX_PATH,L"%s\\erl.ini",bin_dir); if (store_init_file(ini_file,fromname) != 0) { - fprintf(stderr,"Could not create file %s\n", + fprintf(stderr,"Could not create file %S\n", fromname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); } - if (!CopyFile(fromname,toname,FALSE)) { - fprintf(stderr,"Could not copy file %s to %s\n", - fromname,toname); + if (!CopyFileW(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %S to %S\n", + fromname,toname); fprintf(stderr,"Cannot continue installation, bailing out.\n"); exit(1); } if (!silent) { - printf("Erlang %s installed successfully\n", version_string); + printf("Erlang %s installed successfully\n", erts_version); } return 0; } diff --git a/erts/etc/win32/Makefile b/erts/etc/win32/Makefile index cc9021da70..c6376ebe74 100644 --- a/erts/etc/win32/Makefile +++ b/erts/etc/win32/Makefile @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2012. All Rights Reserved. +# Copyright Ericsson AB 1996-2016. 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/win32/Nmakefile.start_erl b/erts/etc/win32/Nmakefile.start_erl index 5bf9fd78d5..00d22461fb 100644 --- a/erts/etc/win32/Nmakefile.start_erl +++ b/erts/etc/win32/Nmakefile.start_erl @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1998-2009. All Rights Reserved. +# Copyright Ericsson AB 1998-2016. 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/win32/beam.rc b/erts/etc/win32/beam.rc index cd7db67d4d..0aaabf1097 100644 --- a/erts/etc/win32/beam.rc +++ b/erts/etc/win32/beam.rc @@ -1,18 +1,19 @@ // // %CopyrightBegin% // -// Copyright Ericsson AB 1997-2009. All Rights Reserved. +// Copyright Ericsson AB 1997-2016. 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/win32/cygwin_tools/erl b/erts/etc/win32/cygwin_tools/erl index 576825c4be..897bbfac87 100755 --- a/erts/etc/win32/cygwin_tools/erl +++ b/erts/etc/win32/cygwin_tools/erl @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/cygwin_tools/erlc b/erts/etc/win32/cygwin_tools/erlc index a18ec27bf4..eda9fdb7fc 100755 --- a/erts/etc/win32/cygwin_tools/erlc +++ b/erts/etc/win32/cygwin_tools/erlc @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/cygwin_tools/javac.sh b/erts/etc/win32/cygwin_tools/javac.sh index f9ee24593f..f53e5a3cc6 100755 --- a/erts/etc/win32/cygwin_tools/javac.sh +++ b/erts/etc/win32/cygwin_tools/javac.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/cygwin_tools/make_bootstrap_ini.sh b/erts/etc/win32/cygwin_tools/make_bootstrap_ini.sh index 20fe143890..377c0dda6c 100755 --- a/erts/etc/win32/cygwin_tools/make_bootstrap_ini.sh +++ b/erts/etc/win32/cygwin_tools/make_bootstrap_ini.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# Copyright Ericsson AB 2003-2016. 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/win32/cygwin_tools/make_local_ini.sh b/erts/etc/win32/cygwin_tools/make_local_ini.sh index 8e29573dc4..e5db98468b 100755 --- a/erts/etc/win32/cygwin_tools/make_local_ini.sh +++ b/erts/etc/win32/cygwin_tools/make_local_ini.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2009. All Rights Reserved. +# Copyright Ericsson AB 2003-2016. 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/win32/cygwin_tools/mingw/ar.sh b/erts/etc/win32/cygwin_tools/mingw/ar.sh index 5b8f58e5de..de166284d8 100755 --- a/erts/etc/win32/cygwin_tools/mingw/ar.sh +++ b/erts/etc/win32/cygwin_tools/mingw/ar.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2006-2009. All Rights Reserved. +# Copyright Ericsson AB 2006-2016. 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/win32/cygwin_tools/mingw/cc.sh b/erts/etc/win32/cygwin_tools/mingw/cc.sh index ae284893fa..0b321a5099 100755 --- a/erts/etc/win32/cygwin_tools/mingw/cc.sh +++ b/erts/etc/win32/cygwin_tools/mingw/cc.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2006-2009. All Rights Reserved. +# Copyright Ericsson AB 2006-2016. 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/win32/cygwin_tools/mingw/coffix.c b/erts/etc/win32/cygwin_tools/mingw/coffix.c index 5dff030a69..ff3f3de3d1 100644 --- a/erts/etc/win32/cygwin_tools/mingw/coffix.c +++ b/erts/etc/win32/cygwin_tools/mingw/coffix.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2006-2009. All Rights Reserved. + * Copyright Ericsson AB 2006-2016. 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/win32/cygwin_tools/mingw/emu_cc.sh b/erts/etc/win32/cygwin_tools/mingw/emu_cc.sh index f3865c8cae..5f510467fe 100755 --- a/erts/etc/win32/cygwin_tools/mingw/emu_cc.sh +++ b/erts/etc/win32/cygwin_tools/mingw/emu_cc.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2006-2009. All Rights Reserved. +# Copyright Ericsson AB 2006-2016. 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/win32/cygwin_tools/mingw/ld.sh b/erts/etc/win32/cygwin_tools/mingw/ld.sh index 145bd2fad9..8b7e1a54c4 100755 --- a/erts/etc/win32/cygwin_tools/mingw/ld.sh +++ b/erts/etc/win32/cygwin_tools/mingw/ld.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2006-2009. All Rights Reserved. +# Copyright Ericsson AB 2006-2016. 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/win32/cygwin_tools/mingw/mc.sh b/erts/etc/win32/cygwin_tools/mingw/mc.sh index 873149172a..8228f8699e 100755 --- a/erts/etc/win32/cygwin_tools/mingw/mc.sh +++ b/erts/etc/win32/cygwin_tools/mingw/mc.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2006-2009. All Rights Reserved. +# Copyright Ericsson AB 2006-2016. 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/win32/cygwin_tools/mingw/rc.sh b/erts/etc/win32/cygwin_tools/mingw/rc.sh index 37296f9e9f..de1b15a432 100755 --- a/erts/etc/win32/cygwin_tools/mingw/rc.sh +++ b/erts/etc/win32/cygwin_tools/mingw/rc.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2006-2009. All Rights Reserved. +# Copyright Ericsson AB 2006-2016. 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/win32/cygwin_tools/vc/ar.sh b/erts/etc/win32/cygwin_tools/vc/ar.sh index 24d275b01a..0989cc878b 100755 --- a/erts/etc/win32/cygwin_tools/vc/ar.sh +++ b/erts/etc/win32/cygwin_tools/vc/ar.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/cygwin_tools/vc/cc.sh b/erts/etc/win32/cygwin_tools/vc/cc.sh index 4939465d08..9eeb004f0e 100755 --- a/erts/etc/win32/cygwin_tools/vc/cc.sh +++ b/erts/etc/win32/cygwin_tools/vc/cc.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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% # @@ -266,7 +267,7 @@ for x in $SOURCES; do echo echo after_sed=`date '+%s'` - echo Made dependencises for $x':' `expr $after_sed '-' $start_time` 's' >&2 + echo Made dependencies for $x':' `expr $after_sed '-' $start_time` 's' >&2 fi else cat $MSG_FILE diff --git a/erts/etc/win32/cygwin_tools/vc/cc_wrap.c b/erts/etc/win32/cygwin_tools/vc/cc_wrap.c index 18ecc31c17..198f3b5649 100644 --- a/erts/etc/win32/cygwin_tools/vc/cc_wrap.c +++ b/erts/etc/win32/cygwin_tools/vc/cc_wrap.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-2016. 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/win32/cygwin_tools/vc/coffix.c b/erts/etc/win32/cygwin_tools/vc/coffix.c index dee0132a61..bf1096c425 100644 --- a/erts/etc/win32/cygwin_tools/vc/coffix.c +++ b/erts/etc/win32/cygwin_tools/vc/coffix.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1999-2009. All Rights Reserved. + * Copyright Ericsson AB 1999-2016. 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/win32/cygwin_tools/vc/emu_cc.sh b/erts/etc/win32/cygwin_tools/vc/emu_cc.sh index 6c179aed00..343cd366a6 100755 --- a/erts/etc/win32/cygwin_tools/vc/emu_cc.sh +++ b/erts/etc/win32/cygwin_tools/vc/emu_cc.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/cygwin_tools/vc/ld.sh b/erts/etc/win32/cygwin_tools/vc/ld.sh index 406c63ffee..2b7d7c6694 100755 --- a/erts/etc/win32/cygwin_tools/vc/ld.sh +++ b/erts/etc/win32/cygwin_tools/vc/ld.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2010. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/cygwin_tools/vc/ld_wrap.c b/erts/etc/win32/cygwin_tools/vc/ld_wrap.c index 7fb3c145ee..94b5c38751 100644 --- a/erts/etc/win32/cygwin_tools/vc/ld_wrap.c +++ b/erts/etc/win32/cygwin_tools/vc/ld_wrap.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-2016. 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/win32/cygwin_tools/vc/mc.sh b/erts/etc/win32/cygwin_tools/vc/mc.sh index 676b072655..c88f2ff1a7 100755 --- a/erts/etc/win32/cygwin_tools/vc/mc.sh +++ b/erts/etc/win32/cygwin_tools/vc/mc.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2009. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/cygwin_tools/vc/rc.sh b/erts/etc/win32/cygwin_tools/vc/rc.sh index 054c672e64..286ebb03f0 100755 --- a/erts/etc/win32/cygwin_tools/vc/rc.sh +++ b/erts/etc/win32/cygwin_tools/vc/rc.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2010. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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% # diff --git a/erts/etc/win32/erl.c b/erts/etc/win32/erl.c index d341153966..b230aa6a40 100644 --- a/erts/etc/win32/erl.c +++ b/erts/etc/win32/erl.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2016. 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% */ @@ -27,96 +28,126 @@ typedef int ErlexecFunction(int, char **, HANDLE, int); -#define INI_FILENAME "erl.ini" +#define INI_FILENAME L"erl.ini" #define INI_SECTION "erlang" -#define ERLEXEC_BASENAME "erlexec.dll" +#define ERLEXEC_BASENAME L"erlexec.dll" static void get_parameters(void); static void error(char* format, ...); -static char *erlexec_name; -static char *erlexec_dir; +static wchar_t *erlexec_name; +static wchar_t *erlexec_dir; #ifdef WIN32_WERL #define WERL 1 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - PSTR szCmdLine, int iCmdShow) +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + PWSTR szCmdLine, int iCmdShow) { int argc = __argc; - char **argv = __argv; + wchar_t **argv = __wargv; #else #define WERL 0 -int main(int argc, char **argv) +int wmain(int argc, wchar_t **argv) { #endif HANDLE erlexec_handle; /* Instance */ ErlexecFunction *win_erlexec; - char *path = malloc(100); - char *npath; + wchar_t *path = malloc(100*sizeof(wchar_t)); + wchar_t *npath; int pathlen; + char ** utf8argv; + int i, len; get_parameters(); - if ((pathlen = GetEnvironmentVariable("PATH",path,100)) == 0) { + if ((pathlen = GetEnvironmentVariableW(L"PATH",path,100)) == 0) { error("No PATH variable (!)"); } else if (pathlen > 100) { - path = realloc(path,pathlen); - GetEnvironmentVariable("PATH",path,pathlen); + path = realloc(path,pathlen*sizeof(wchar_t)); + GetEnvironmentVariableW(L"PATH",path,pathlen); } - npath = malloc(strlen(path) + strlen(erlexec_dir) + 2); - sprintf(npath,"%s;%s",erlexec_dir,path); - SetEnvironmentVariable("PATH",npath); + pathlen = (wcslen(path) + wcslen(erlexec_dir) + 2); + npath = (wchar_t *) malloc(pathlen*sizeof(wchar_t)); + swprintf(npath,pathlen,L"%s;%s",erlexec_dir,path); + SetEnvironmentVariableW(L"PATH",npath); - if ((erlexec_handle = LoadLibrary(erlexec_name)) == NULL) { - error("Could not load module %s.",erlexec_name); + if ((erlexec_handle = LoadLibraryW(erlexec_name)) == NULL) { + error("Could not load module %S.",erlexec_name); } if ((win_erlexec = (ErlexecFunction *) GetProcAddress(erlexec_handle,"win_erlexec")) == NULL) { - error("Could not find entry point \"win_erlexec\" in %s.", erlexec_name); + error("Could not find entry point \"win_erlexec\" in %S.", erlexec_name); + } + + /* Convert argv to utf8 */ + utf8argv = malloc((argc+1) * sizeof(char*)); + for (i=0; i<argc; i++) { + len = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL); + utf8argv[i] = malloc(len*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, utf8argv[i], len, NULL, NULL); } + utf8argv[argc] = NULL; + +#ifdef HARDDEBUG + { + wchar_t tempbuf[2048] = L""; + wchar_t *sbuf; + int i; + sbuf=tempbuf; + sbuf += swprintf(sbuf, 2048, L"utf16: %d\n", argc); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%s|", argv[i]); + }; + sbuf += swprintf(sbuf, 2048, L"\nutf8: \n"); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%S|", utf8argv[i]); + }; + MessageBoxW(NULL, tempbuf, L"erl_exec args", MB_OK|MB_ICONERROR); + } +#endif - return (*win_erlexec)(argc,argv,erlexec_handle,WERL); + return (*win_erlexec)(argc,utf8argv,erlexec_handle,WERL); } -static char *replace_filename(char *path, char *new_base) +static wchar_t *replace_filename(wchar_t *path, wchar_t *new_base) { - int plen = strlen(path); - char *res = malloc((plen+strlen(new_base)+1)*sizeof(char)); - char *p; + int plen = wcslen(path); + wchar_t *res = malloc((plen+wcslen(new_base)+1)*sizeof(wchar_t)); + wchar_t *p; - strcpy(res,path); - for (p = res+plen-1 ;p >= res && *p != '\\'; --p) + wcscpy(res,path); + for (p = res+plen-1 ;p >= res && *p != L'\\'; --p) ; - *(p+1) ='\0'; - strcat(res,new_base); + *(p+1) =L'\0'; + wcscat(res,new_base); return res; } static char *do_lookup_in_section(InitSection *inis, char *name, - char *section, char *filename) + char *section, wchar_t *filename) { char *p = lookup_init_entry(inis, name); if (p == NULL) { - error("Could not find key %s in section %s of file %s", + error("Could not find key %s in section %s of file %S", name,section,filename); } - return _strdup(p); + return p; } -static void copy_latest_vsn(char *latest_vsn, char *next_vsn) +static void copy_latest_vsn(wchar_t *latest_vsn, wchar_t *next_vsn) { /* Copy */ - char *lp; - char *np; + wchar_t *lp; + wchar_t *np; /* Find vsn */ - for (lp = next_vsn+strlen(next_vsn)-1 ;lp >= next_vsn && *lp != '\\'; --lp) + for (lp = next_vsn+wcslen(next_vsn)-1 ;lp >= next_vsn && *lp != L'\\'; --lp) ; /* lp =+ length("erts-"); */ - for (np = next_vsn+strlen(next_vsn)-1 ;np >= next_vsn && *np != '\\'; --np) + for (np = next_vsn+wcslen(next_vsn)-1 ;np >= next_vsn && *np != L'\\'; --np) ; /* np =+ length("erts-"); */ @@ -124,95 +155,95 @@ static void copy_latest_vsn(char *latest_vsn, char *next_vsn) if (*lp == *np) { continue; } - if (*np == '.' || *np == '\0' || *np <= *lp) { + if (*np == L'.' || *np == L'\0' || *np <= *lp) { /* */ return; } - if (*lp == '.' || *lp == '\0') { - strcpy(latest_vsn, next_vsn); + if (*lp == L'.' || *lp == L'\0') { + wcscpy(latest_vsn, next_vsn); return; } } return; } -static char *find_erlexec_dir2(char *install_dir) +static wchar_t *find_erlexec_dir2(wchar_t *install_dir) { /* List install dir and look for latest erts-vsn */ HANDLE dir_handle; /* Handle to directory. */ - char wildcard[MAX_PATH]; /* Wildcard to search for. */ - WIN32_FIND_DATA find_data; /* Data found by FindFirstFile() or FindNext(). */ - char latest_vsn[MAX_PATH]; + wchar_t wildcard[MAX_PATH]; /* Wildcard to search for. */ + WIN32_FIND_DATAW find_data; /* Data found by FindFirstFile() or FindNext(). */ + wchar_t latest_vsn[MAX_PATH]; /* Setup wildcard */ - int length = strlen(install_dir); - char *p; + int length = wcslen(install_dir); + wchar_t *p; if (length+3 >= MAX_PATH) { error("Cannot find erlexec.exe"); } - strcpy(wildcard, install_dir); + wcscpy(wildcard, install_dir); p = wildcard+length-1; - if (*p != '/' && *p != '\\') - *++p = '\\'; - strcpy(++p, "erts-*"); + if (*p != L'/' && *p != L'\\') + *++p = L'\\'; + wcscpy(++p, L"erts-*"); /* Find first dir */ - dir_handle = FindFirstFile(wildcard, &find_data); + dir_handle = FindFirstFileW(wildcard, &find_data); if (dir_handle == INVALID_HANDLE_VALUE) { /* No erts-vsn found*/ return NULL; } - strcpy(latest_vsn, find_data.cFileName); + wcscpy(latest_vsn, find_data.cFileName); /* Find the rest */ - while(FindNextFile(dir_handle, &find_data)) { + while(FindNextFileW(dir_handle, &find_data)) { copy_latest_vsn(latest_vsn, find_data.cFileName); } FindClose(dir_handle); - p = malloc((strlen(install_dir)+1+strlen(latest_vsn)+4+1)*sizeof(char)); + p = (wchar_t *) malloc((wcslen(install_dir)+1+wcslen(latest_vsn)+4+1)*sizeof(wchar_t)); - strcpy(p,install_dir); - strcat(p,"\\"); - strcat(p,latest_vsn); - strcat(p,"\\bin"); + wcscpy(p,install_dir); + wcscat(p,L"\\"); + wcscat(p,latest_vsn); + wcscat(p,L"\\bin"); return p; } -static char *find_erlexec_dir(char *erlpath) +static wchar_t *find_erlexec_dir(wchar_t *erlpath) { /* Assume that the path to erl is absolute and * that it is not a symbolic link*/ - char *dir =_strdup(erlpath); - char *p; - char *p2; + wchar_t *dir =_wcsdup(erlpath); + wchar_t *p; + wchar_t *p2; /* Chop of base name*/ - for (p = dir+strlen(dir)-1 ;p >= dir && *p != '\\'; --p) + for (p = dir+wcslen(dir)-1 ;p >= dir && *p != L'\\'; --p) ; - *p ='\0'; + *p =L'\0'; p--; /* Check if dir path is like ...\install_dir\erts-vsn\bin */ - for (;p >= dir && *p != '\\'; --p) + for (;p >= dir && *p != L'\\'; --p) ; p--; for (p2 = p;p2 >= dir && *p2 != '\\'; --p2) ; p2++; - if (strncmp(p2, "erts-", strlen("erts-")) == 0) { - p = _strdup(dir); + if (wcsncmp(p2, L"erts-", wcslen(L"erts-")) == 0) { + p = _wcsdup(dir); free(dir); return p; } /* Assume that dir path is like ...\install_dir\bin */ - *++p ='\0'; /* chop off bin dir */ + *++p =L'\0'; /* chop off bin dir */ p = find_erlexec_dir2(dir); free(dir); @@ -225,18 +256,20 @@ static char *find_erlexec_dir(char *erlpath) static void get_parameters(void) { - char buffer[MAX_PATH]; - char *ini_filename; + wchar_t buffer[MAX_PATH]; + wchar_t *ini_filename; HANDLE module = GetModuleHandle(NULL); InitFile *inif; InitSection *inis; - char *bindir; + char *utf8dir; + int len; - if (module = NULL) { + + if (module == NULL) { error("Cannot GetModuleHandle()"); } - if (GetModuleFileName(module,buffer,MAX_PATH) == 0) { + if (GetModuleFileNameW(module,buffer,MAX_PATH) == 0) { error("Could not GetModuleFileName"); } @@ -244,21 +277,28 @@ static void get_parameters(void) if ((inif = load_init_file(ini_filename)) == NULL) { erlexec_dir = find_erlexec_dir(ini_filename); - SetEnvironmentVariable("ERLEXEC_DIR", erlexec_dir); + SetEnvironmentVariableW(L"ERLEXEC_DIR", erlexec_dir); } else { if ((inis = lookup_init_section(inif,INI_SECTION)) == NULL) { - error("Could not find section %s in init file %s", + error("Could not find section %s in init file %S", INI_SECTION, ini_filename); } - erlexec_dir = do_lookup_in_section(inis, "Bindir", INI_SECTION, ini_filename); - free_init_file(inif); + utf8dir = do_lookup_in_section(inis, "Bindir", INI_SECTION, ini_filename); + len = MultiByteToWideChar(CP_UTF8, 0, utf8dir, -1, NULL, 0); + erlexec_dir = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8dir, -1, erlexec_dir, len); + if(len == 0) { + error("Bindir is not a valid utf8 '%s' in init file %S", + utf8dir, ini_filename); + } + free_init_file(inif); } - erlexec_name = malloc(strlen(erlexec_dir) + strlen(ERLEXEC_BASENAME) + 2); - strcpy(erlexec_name,erlexec_dir); - strcat(erlexec_name, "\\" ERLEXEC_BASENAME); + erlexec_name = malloc((wcslen(erlexec_dir) + wcslen(ERLEXEC_BASENAME) + 2)*sizeof(wchar_t)); + wcscpy(erlexec_name,erlexec_dir); + wcscat(erlexec_name, L"\\" ERLEXEC_BASENAME); free(ini_filename); } diff --git a/erts/etc/win32/erl.rc b/erts/etc/win32/erl.rc index 88213d48f2..772213ac86 100644 --- a/erts/etc/win32/erl.rc +++ b/erts/etc/win32/erl.rc @@ -1,18 +1,19 @@ // // %CopyrightBegin% // -// Copyright Ericsson AB 1998-2009. All Rights Reserved. +// Copyright Ericsson AB 1998-2016. 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/win32/erl_log.c b/erts/etc/win32/erl_log.c index 85cc49e0e3..de0d8e39f0 100644 --- a/erts/etc/win32/erl_log.c +++ b/erts/etc/win32/erl_log.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * Copyright Ericsson AB 1996-2016. 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/win32/erlang.ico b/erts/etc/win32/erlang.ico Binary files differindex cee8b58af9..7b62d31aa9 100644 --- a/erts/etc/win32/erlang.ico +++ b/erts/etc/win32/erlang.ico diff --git a/erts/etc/win32/erlsrv/erlsrv_global.h b/erts/etc/win32/erlsrv/erlsrv_global.h index d3922dc1e3..fc6166fc7c 100644 --- a/erts/etc/win32/erlsrv/erlsrv_global.h +++ b/erts/etc/win32/erlsrv/erlsrv_global.h @@ -1,31 +1,32 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ #ifndef _ERLSRV_GLOBAL_H #define _ERLSRV_GLOBAL_H -#define APP_NAME "ErlSrv" +#define APP_NAME L"ErlSrv" -#define ERLANG_MACHINE "erl.exe" +#define ERLANG_MACHINE L"erl.exe" -#define SERVICE_ENV "ERLSRV_SERVICE_NAME" -#define EXECUTABLE_ENV "ERLSRV_EXECUTABLE" -#define DEBUG_ENV "ERLSRV_DEBUG" +#define SERVICE_ENV L"ERLSRV_SERVICE_NAME" +#define EXECUTABLE_ENV L"ERLSRV_EXECUTABLE" +#define DEBUG_ENV L"ERLSRV_DEBUG" #ifdef _DEBUG #define HARDDEBUG 1 diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.c b/erts/etc/win32/erlsrv/erlsrv_interactive.c index e8d73ae047..c616ef86e3 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.c +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2013. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -27,54 +28,60 @@ #include "erlsrv_interactive.h" #include "erlsrv_util.h" /* service_name */ -#define DBG fprintf(stderr,"argv[0]:%s line %d\n",argv[0],__LINE__) +#define DBG fwprintf(stderr,L"argv[0]:%s line %d\n",argv[0],__LINE__) +/* #define HARDDEBUG 1 */ + +#include <fcntl.h> /* Really HAS to correcpond to the enum in erlsrv_registry.h */ -static char *arg_tab[] = { - "stopaction", "st", - "onfail", "on", - "machine", "m", - "env", "e", - "workdir", "w", - "priority", "p", - "sname", "sn", - "name", "n", - "args", "ar", - "debugtype", "d", - "internalservicename","i", - "comment","c", +static wchar_t *arg_tab[] = { + L"stopaction", L"st", + L"onfail", L"on", + L"machine", L"m", + L"env", L"e", + L"workdir", L"w", + L"priority", L"p", + L"sname", L"sn", + L"name", L"n", + L"args", L"ar", + L"debugtype", L"d", + L"internalservicename",L"i", + L"comment",L"c", NULL, NULL }; -static char *generate_real_service_name(char *display_name){ +static wchar_t *generate_real_service_name(wchar_t *display_name){ SYSTEMTIME systime; FILETIME ftime; - char *buff = malloc(strlen(display_name)+ - (8*2)+1); - char *tmp = _strdup(display_name); + int len=(wcslen(display_name)+(8*2)+1); + wchar_t *buff; + wchar_t *tmp = _wcsdup(display_name); int i; + buff = (wchar_t*) malloc(len*sizeof(wchar_t)); + /* 2 Hex chars for each byte in a DWORD */ GetSystemTime(&systime); SystemTimeToFileTime(&systime,&ftime); /* Remove trailing version info to avoid user confusion */ - for(i = (strlen(tmp)-1);i > 0; --i) - if(tmp[i] == '_'){ - tmp[i] = '\0'; + for(i = (wcslen(tmp)-1);i > 0; --i) + if(tmp[i] == L'_'){ + tmp[i] = L'\0'; break; } - sprintf(buff,"%s%08x%08x",tmp,ftime.dwHighDateTime, - ftime.dwLowDateTime); + swprintf(buff,len,L"%s%08x%08x",tmp, + ftime.dwHighDateTime, + ftime.dwLowDateTime); free(tmp); return buff; } -static int lookup_arg(char *arg){ +static int lookup_arg(wchar_t *arg){ int i; - if(*arg != '-' && *arg != '/') + if(*arg != L'-' && *arg != L'/') return -1; for(i=0; arg_tab[i] != NULL; i += 2){ - if(!_strnicmp(arg_tab[i],arg+1,strlen(arg+1)) && - !_strnicmp(arg_tab[i+1],arg+1,strlen(arg_tab[i+1]))) + if(!_wcsnicmp(arg_tab[i],arg+1,wcslen(arg+1)) && + !_wcsnicmp(arg_tab[i+1],arg+1,wcslen(arg_tab[i+1]))) return (i / 2); } return -1; @@ -82,29 +89,29 @@ static int lookup_arg(char *arg){ -char *edit_env(char *edit, char *oldenv){ - char **arg; - char *value; - char *name = strdup(edit); +wchar_t *edit_env(wchar_t *edit, wchar_t *oldenv){ + wchar_t **arg; + wchar_t *value; + wchar_t *name = wcsdup(edit); int i; - char *tmp; + wchar_t *tmp; arg = env_to_arg(oldenv); - value = strchr(name,'='); + value = wcschr(name,L'='); if(value){ - *(value++) = '\0'; - if(*value == '\0') + *(value++) = L'\0'; + if(*value == L'\0') value = NULL; } for(i=0;arg[i] != NULL; ++i){ - tmp = strchr(arg[i],'='); - if(((int) strlen(name)) == (tmp - arg[i]) && - !_strnicmp(name,arg[i], tmp - arg[i])) + tmp = wcschr(arg[i],L'='); + if(((int) wcslen(name)) == (tmp - arg[i]) && + !_wcsnicmp(name,arg[i], tmp - arg[i])) break; } if(arg[i] != NULL){ free(arg[i]); if(value){ - arg[i] = strdup(edit); + arg[i] = wcsdup(edit); } else { do { arg[i] = arg[i+1]; @@ -113,7 +120,7 @@ char *edit_env(char *edit, char *oldenv){ } } else if(value){ /* add to arg, which is always allocated to hold one extra environment variable*/ - arg[i] = strdup(edit); + arg[i] = wcsdup(edit); arg[i+1] = NULL; } free(name); @@ -132,8 +139,8 @@ void print_last_error(void){ (LPTSTR) &mes, 0, NULL ); - fprintf(stderr,"Error: %s",mes); - LocalFree(mes); + fwprintf(stderr,L"Error: %S",mes); + LocalFree(mes); } static int get_last_error(void) @@ -144,19 +151,19 @@ static int get_last_error(void) static BOOL install_service(void){ SC_HANDLE scm; SC_HANDLE service; - char filename[MAX_PATH + 3]; + wchar_t filename[MAX_PATH + 3]; DWORD fnsiz=MAX_PATH; - char dependant[] = { 'L','a','n','m','a','n', - 'W','o','r','k','s','t', - 'a','t','i','o','n','\0','\0'}; + wchar_t dependant[] = { L'L',L'a',L'n',L'm',L'a',L'n', + L'W',L'o',L'r',L'k',L's',L't', + L'a',L't',L'i',L'o',L'n',L'\0',L'\0'}; - if(!(fnsiz = GetModuleFileName(NULL, filename, fnsiz))) + if(!(fnsiz = GetModuleFileNameW(NULL, filename, fnsiz))) return FALSE; - if(strchr(filename,' ')){ - memmove(filename+1,filename,fnsiz); - filename[0] ='\"'; /* " */ - filename[fnsiz+1] = '\"'; /* " */ - filename[fnsiz+2] = '\0'; + if(wcschr(filename,L' ')){ + memmove(filename+1,filename,fnsiz*sizeof(wchar_t)); + filename[0] = L'\"'; /* " */ + filename[fnsiz+1] = L'\"'; /* " */ + filename[fnsiz+2] = L'\0'; } if((scm = OpenSCManager(NULL, NULL, @@ -166,20 +173,20 @@ static BOOL install_service(void){ last_error = GetLastError(); return FALSE; } - service = CreateService(scm, - real_service_name, - service_name, - SERVICE_ALL_ACCESS & - ~(SERVICE_PAUSE_CONTINUE), - SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - filename, - NULL, - NULL, - dependant, - NULL, - NULL); + service = CreateServiceW(scm, + real_service_name, + service_name, + SERVICE_ALL_ACCESS & + ~(SERVICE_PAUSE_CONTINUE), + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + filename, + NULL, + NULL, + dependant, + NULL, + NULL); if(service == NULL){ CloseServiceHandle(scm); last_error = GetLastError(); @@ -198,9 +205,9 @@ static BOOL remove_service(void){ GENERIC_WRITE)) == NULL) return FALSE; - service = OpenService(scm, - real_service_name, - SERVICE_ALL_ACCESS); + service = OpenServiceW(scm, + real_service_name, + SERVICE_ALL_ACCESS); if(service == NULL){ CloseServiceHandle(scm); return FALSE; @@ -220,9 +227,9 @@ static BOOL open_service_control(SC_HANDLE *scm, SC_HANDLE *service){ SC_MANAGER_ALL_ACCESS)) == NULL) return FALSE; - *service = OpenService(*scm, - real_service_name, - SERVICE_ALL_ACCESS); + *service = OpenServiceW(*scm, + real_service_name, + SERVICE_ALL_ACCESS); if(service == NULL){ CloseServiceHandle(*scm); return FALSE; @@ -239,10 +246,10 @@ static BOOL open_service_config(SC_HANDLE *scm, SC_HANDLE *service){ last_error = GetLastError(); return FALSE; } - *service = OpenService(*scm, - real_service_name, - /*GENERIC_WRITE*/ - SERVICE_ALL_ACCESS); + *service = OpenServiceW(*scm, + real_service_name, + /*GENERIC_WRITE*/ + SERVICE_ALL_ACCESS); if(service == NULL){ last_error = GetLastError(); CloseServiceHandle(*scm); @@ -251,16 +258,16 @@ static BOOL open_service_config(SC_HANDLE *scm, SC_HANDLE *service){ return TRUE; } -static BOOL set_service_comment(char *comment) { +static BOOL set_service_comment(wchar_t *comment) { SC_HANDLE scm; SC_HANDLE service; - SERVICE_DESCRIPTION sd; + SERVICE_DESCRIPTIONW sd; BOOL ret = TRUE; sd.lpDescription = comment; if (!open_service_config(&scm,&service)) { return FALSE; } - if (!ChangeServiceConfig2(service,SERVICE_CONFIG_DESCRIPTION,&sd)) { + if (!ChangeServiceConfig2W(service,SERVICE_CONFIG_DESCRIPTION,&sd)) { last_error = GetLastError(); ret = FALSE; } @@ -325,7 +332,7 @@ static BOOL stop_service(void){ if(!open_service_control(&scm,&service)){ #ifdef HARDDEBUG - fprintf(stderr,"Failed to open service.\n"); + fwprintf(stderr,L"Failed to open service.\n"); #endif return FALSE; } @@ -338,7 +345,7 @@ static BOOL stop_service(void){ #ifdef HARDDEBUG if(!ret) { - fprintf(stderr,"Failed to control service.\n"); + fwprintf(stderr,L"Failed to control service.\n"); print_last_error(); } #endif @@ -466,115 +473,114 @@ void cleanup_old(){ } BOOL fill_in_defaults(RegEntry *new){ - char filename[MAX_PATH]; - char *ptr; + wchar_t filename[MAX_PATH]; + wchar_t *ptr; - if(!GetModuleFileName(NULL, filename, MAX_PATH)) + if(!GetModuleFileNameW(NULL, filename, MAX_PATH)) return FALSE; - for(ptr = filename + strlen(filename) - 1; - ptr > filename && *ptr != '\\'; + for(ptr = filename + wcslen(filename) - 1; + ptr > filename && *ptr != L'\\'; --ptr) ; - if(*ptr == '\\') + if(*ptr == L'\\') ++ptr; - *ptr = '\0'; + *ptr = L'\0'; - ptr = malloc(strlen(filename)+strlen(ERLANG_MACHINE)+1); - strcpy(ptr,filename); - strcat(ptr,ERLANG_MACHINE); + ptr = (wchar_t*) malloc((wcslen(filename)+wcslen(ERLANG_MACHINE)+1)*sizeof(wchar_t)); + wcscpy(ptr,filename); + wcscat(ptr,ERLANG_MACHINE); - new[StopAction].data.bytes = ""; + new[StopAction].data.string = L""; new[OnFail].data.value = ON_FAIL_IGNORE; - new[Machine].data.bytes = ptr; - new[Machine].data.expand.unexpanded = ptr; - new[Env].data.bytes = "\0"; - new[WorkDir].data.bytes = new[WorkDir].data.expand.unexpanded = - ""; + new[Machine].data.string = ptr; + new[Machine].data.expand.unexpanded = ptr; + new[Env].data.string = L"\0"; + new[WorkDir].data.string = new[WorkDir].data.expand.unexpanded = L""; new[Priority].data.value = NORMAL_PRIORITY_CLASS; - new[SName].data.bytes = service_name; - new[Name].data.bytes = ""; - new[Args].data.bytes = new[Args].data.expand.unexpanded = ""; + new[SName].data.string = service_name; + new[Name].data.string = L""; + new[Args].data.string = new[Args].data.expand.unexpanded = L""; new[DebugType].data.value = DEBUG_TYPE_NO_DEBUG; - new[InternalServiceName].data.bytes = real_service_name; - new[Comment].data.bytes = ""; + new[InternalServiceName].data.string = real_service_name; + new[Comment].data.string = L""; return TRUE; } -int do_usage(char *arg0){ - printf("Usage:\n"); - printf("%s {set | add} <servicename>\n" - "\t[-st[opaction] [<erlang shell command>]]\n" - "\t[-on[fail] [{reboot | restart | restart_always}]]\n" - "\t[-m[achine] [<erl-command>]]\n" - "\t[-e[nv] [<variable>[=<value>]]]\n" - "\t[-w[orkdir] [<directory>]]\n" - "\t[-p[riority] [{low|high|realtime}]]\n" - "\t[{-sn[ame] | -n[ame]} [<nodename>]]\n" - "\t[-d[ebugtype] [{new|reuse|console}]]\n" - "\t[-ar[gs] [<limited erl arguments>]]\n\n" - "%s {start | start_disabled | stop | disable | enable} <servicename>\n\n" - "%s remove <servicename>\n\n" - "%s rename <servicename> <servicename>\n\n" - "%s list [<servicename>]\n\n" - "%s help\n\n", +int do_usage(wchar_t *arg0){ + wprintf(L"Usage:\n"); + wprintf(L"%s {set | add} <servicename>\n" + L"\t[-st[opaction] [<erlang shell command>]]\n" + L"\t[-on[fail] [{reboot | restart | restart_always}]]\n" + L"\t[-m[achine] [<erl-command>]]\n" + L"\t[-e[nv] [<variable>[=<value>]]]\n" + L"\t[-w[orkdir] [<directory>]]\n" + L"\t[-p[riority] [{low|high|realtime}]]\n" + L"\t[{-sn[ame] | -n[ame]} [<nodename>]]\n" + L"\t[-d[ebugtype] [{new|reuse|console}]]\n" + L"\t[-ar[gs] [<limited erl arguments>]]\n\n" + L"%s {start | start_disabled | stop | disable | enable} <servicename>\n\n" + L"%s remove <servicename>\n\n" + L"%s rename <servicename> <servicename>\n\n" + L"%s list [<servicename>]\n\n" + L"%s help\n\n", arg0,arg0,arg0,arg0,arg0,arg0); - printf("Manipulates Erlang system services on Windows NT.\n\n"); - printf("When no parameter to an option is specified, the option\n" - "is reset to it's default value. To set an empty argument\n" - "list, give option -args as last option on command line " - "with\n" - "no arguments.\n\n"); - printf("See Erlang documentation for full description.\n"); + wprintf(L"Manipulates Erlang system services on Windows NT.\n\n"); + wprintf(L"When no parameter to an option is specified, the option\n" + L"is reset to it's default value. To set an empty argument\n" + L"list, give option -args as last option on command line " + L"with\n" + L"no arguments.\n\n"); + wprintf(L"See Erlang documentation for full description.\n"); return 0; } -int do_manage(int argc,char **argv){ - char *action = argv[1]; +int do_manage(int argc, wchar_t **argv){ + wchar_t *action = argv[1]; RegEntry *current = empty_reg_tab(); if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; if(!fetch_current(current)){ - fprintf(stderr,"%s: The service %s is not an erlsrv controlled service.\n", + fwprintf(stderr,L"%s: The service %s is not an erlsrv controlled service.\n", argv[0],service_name); return 1; } - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); free_keys(current); - if(!_stricmp(action,"start")){ + if(!_wcsicmp(action,L"start")){ if(!start_service()){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_RUNNING, 60)){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s started.\n", + wprintf(L"%s: Service %s started.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"start_disabled")){ + if(!_wcsicmp(action,L"start_disabled")){ if(!enable_service()){ - fprintf(stderr,"%s: Failed to enable service %s.\n", + fwprintf(stderr,L"%s: Failed to enable service %s.\n", argv[0],service_name); print_last_error(); return 1; } if(!start_service() && get_last_error() != ERROR_SERVICE_ALREADY_RUNNING){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); goto failure_starting; @@ -582,84 +588,84 @@ int do_manage(int argc,char **argv){ if(!wait_service_trans(SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_RUNNING, 60)){ - fprintf(stderr,"%s: Failed to start service %s.\n", + fwprintf(stderr,L"%s: Failed to start service %s.\n", argv[0],service_name); print_last_error(); goto failure_starting; } if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s started.\n", + wprintf(L"%s: Service %s started.\n", argv[0],service_name); return 0; failure_starting: if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); } return 1; } - if(!_stricmp(action,"stop")){ + if(!_wcsicmp(action,L"stop")){ if(!stop_service()){ - fprintf(stderr,"%s: Failed to stop service %s.\n", + fwprintf(stderr,L"%s: Failed to stop service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { if(!wait_service_trans(SERVICE_RUNNING, SERVICE_STOP_PENDING, SERVICE_STOPPED, 60)){ - fprintf(stderr,"%s: Failed to stop service %s.\n", + fwprintf(stderr,L"%s: Failed to stop service %s.\n", argv[0],service_name); print_last_error(); return 1; } - printf("%s: Service %s stopped.\n", + wprintf(L"%s: Service %s stopped.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"disable")){ + if(!_wcsicmp(action,L"disable")){ #if 0 if(stop_service()){ - printf("%s: Service %s stopped.\n", + wprintf(L"%s: Service %s stopped.\n", argv[0],service_name); } #endif if(!disable_service()){ - fprintf(stderr,"%s: Failed to disable service %s.\n", + fwprintf(stderr,L"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { - printf("%s: Service %s disabled.\n", + wprintf(L"%s: Service %s disabled.\n", argv[0],service_name); return 0; } } - if(!_stricmp(action,"enable")){ + if(!_wcsicmp(action,L"enable")){ if(!enable_service()){ - fprintf(stderr,"%s: Failed to enable service %s.\n", + fwprintf(stderr,L"%s: Failed to enable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { - printf("%s: Service %s enabled.\n", + wprintf(L"%s: Service %s enabled.\n", argv[0],service_name); return 0; } } - fprintf(stderr,"%s: Unrecignized argument %s.\n", + fwprintf(stderr,L"%s: Unrecignized argument %s.\n", argv[0],action); return 1; } -int do_add_or_set(int argc, char **argv){ +int do_add_or_set(int argc, wchar_t **argv){ RegEntry *new_entries; RegEntry *default_entries; int add = 0; @@ -669,40 +675,40 @@ int do_add_or_set(int argc, char **argv){ new_entries = empty_reg_tab(); default_entries = empty_reg_tab(); if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; - if(!_stricmp(argv[1],"add")){ + if(!_wcsicmp(argv[1],L"add")){ if(fetch_current(default_entries)){ - fprintf(stderr,"%s: A service with the name %s already " - "exists.\n", + fwprintf(stderr,L"%s: A service with the name %s already " + L"exists.\n", argv[0],service_name); return 1; } real_service_name = generate_real_service_name(service_name); if(!fill_in_defaults(new_entries)){ - fprintf(stderr,"%s: Internal error.\n", argv[0]); + fwprintf(stderr,L"%s: Internal error.\n", argv[0]); return 1; } add = 1; } else { if(!fetch_current(new_entries)){ - fprintf(stderr,"%s: No service with the name %s exists.\n", + fwprintf(stderr,L"%s: No service with the name %s exists.\n", argv[0], service_name); return 1; } - real_service_name = new_entries[InternalServiceName].data.bytes; + real_service_name = new_entries[InternalServiceName].data.string; } if(!fill_in_defaults(default_entries)){ - fprintf(stderr,"%s: Internal error.\n", argv[0]); + fwprintf(stderr,L"%s: Internal error.\n", argv[0]); return 1; } /* make sure env is malloced... */ - new_entries[Env].data.bytes = envdup(new_entries[Env].data.bytes); + new_entries[Env].data.string = envdup(new_entries[Env].data.string); for(i = 3; i < argc; ++i){ switch((current = lookup_arg(argv[i]))){ @@ -712,43 +718,43 @@ int do_add_or_set(int argc, char **argv){ case WorkDir: case Args: if(i+1 >= argc){ - new_entries[current].data.bytes = - default_entries[current].data.bytes; + new_entries[current].data.string = + default_entries[current].data.string; new_entries[current].data.expand.unexpanded = default_entries[current].data.expand.unexpanded; } else { new_entries[current].data.expand.unexpanded = - new_entries[current].data.bytes = argv[i+1]; + new_entries[current].data.string = argv[i+1]; ++i; } break; case SName: - new_entries[Name].data.bytes = ""; + new_entries[Name].data.string = L""; case StopAction: case Name: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ - new_entries[current].data.bytes = - default_entries[current].data.bytes; + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ + new_entries[current].data.string = + default_entries[current].data.string; } else { - new_entries[current].data.bytes = argv[i+1]; + new_entries[current].data.string = argv[i+1]; ++i; } break; case OnFail: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"reboot")) + if(!_wcsicmp(argv[i+1],L"reboot")) new_entries[current].data.value = ON_FAIL_REBOOT; - else if(!_stricmp(argv[i+1],"restart")) + else if(!_wcsicmp(argv[i+1],L"restart")) new_entries[current].data.value = ON_FAIL_RESTART; - else if(!_stricmp(argv[i+1],"restart_always")) + else if(!_wcsicmp(argv[i+1],L"restart_always")) new_entries[current].data.value = ON_FAIL_RESTART_ALWAYS; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -757,18 +763,18 @@ int do_add_or_set(int argc, char **argv){ break; case DebugType: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"new")) + if(!_wcsicmp(argv[i+1],L"new")) new_entries[current].data.value = DEBUG_TYPE_NEW; - else if(!_stricmp(argv[i+1],"reuse")) + else if(!_wcsicmp(argv[i+1],L"reuse")) new_entries[current].data.value = DEBUG_TYPE_REUSE; - else if(!_stricmp(argv[i+1],"console")) + else if(!_wcsicmp(argv[i+1],L"console")) new_entries[current].data.value = DEBUG_TYPE_CONSOLE; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -777,18 +783,18 @@ int do_add_or_set(int argc, char **argv){ break; case Priority: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ new_entries[current].data.value = default_entries[current].data.value; } else { - if(!_stricmp(argv[i+1],"high")) + if(!_wcsicmp(argv[i+1],L"high")) new_entries[current].data.value = HIGH_PRIORITY_CLASS; - else if(!_stricmp(argv[i+1],"low")) + else if(!_wcsicmp(argv[i+1],L"low")) new_entries[current].data.value = IDLE_PRIORITY_CLASS; - else if(!_stricmp(argv[i+1],"realtime")) + else if(!_wcsicmp(argv[i+1],L"realtime")) new_entries[current].data.value = REALTIME_PRIORITY_CLASS; else { - fprintf(stderr,"%s: Unrecognized keyword value %s.\n", + fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } @@ -798,64 +804,64 @@ int do_add_or_set(int argc, char **argv){ case Env: if(i+1 >= argc || - *argv[i+1] == '-' || *argv[i+1] == '/'){ - fprintf(stderr,"%s: %s requires a parameter.\n", + *argv[i+1] == L'-' || *argv[i+1] == L'/'){ + fwprintf(stderr,L"%s: %s requires a parameter.\n", argv[0],argv[i]); return 1; } - new_entries[current].data.bytes = - edit_env(argv[i+1], - new_entries[current].data.bytes); + new_entries[current].data.string = + edit_env(argv[i+1], new_entries[current].data.string); ++i; break; case InternalServiceName: if (!add) { - fprintf(stderr,"%s: %s only allowed when adding a new service.\n", + fwprintf(stderr,L"%s: %s only allowed when adding a new service.\n", argv[0],argv[i]); return 1; } if(i+1 >= argc){ - fprintf(stderr,"%s: %s requires a parameter.\n", + fwprintf(stderr,L"%s: %s requires a parameter.\n", argv[0],argv[i]); return 1; } new_entries[InternalServiceName].data.expand.unexpanded = - new_entries[InternalServiceName].data.bytes = argv[i+1]; + new_entries[InternalServiceName].data.string = argv[i+1]; ++i; /* Discard old, should maybe be fred' but we'll exit anyway */ - real_service_name = new_entries[InternalServiceName].data.bytes; + real_service_name = new_entries[InternalServiceName].data.string; break; default: - fprintf(stderr,"%s: Unrecognized option %s.\n", argv[0], + fwprintf(stderr,L"%s: Unrecognized option %s.\n", argv[0], argv[i]); return 1; } } - if(*new_entries[SName].data.bytes && - *new_entries[Name].data.bytes){ + if(*new_entries[SName].data.string && + *new_entries[Name].data.string){ #if 0 - fprintf(stderr,"%s: Both -sname and -name specified.\n", + fwprintf(stderr,L"%s: Both -sname and -name specified.\n", argv[0]); return 1; #else - new_entries[SName].data.bytes = ""; + new_entries[SName].data.string = L""; #endif } - if(add && !(*new_entries[SName].data.bytes) && - !(*new_entries[Name].data.bytes)){ - fprintf(stderr,"%s: Neither -sname nor -name specified.\n", + if(add && !(*new_entries[SName].data.string) && + !(*new_entries[Name].data.string)){ + fwprintf(stderr,L"%s: Neither -sname nor -name specified.\n", argv[0]); return 1; } + if(add && !install_service()){ - fprintf(stderr,"%s: Unable to register service with service manager.\n", + fwprintf(stderr,L"%s: Unable to register %s service with service manager.\n", argv[0], service_name); print_last_error(); return 1; } if(!set_interactive(new_entries[DebugType].data.value == DEBUG_TYPE_CONSOLE)){ - fprintf(stderr,"%s: Warning, could not set correct interactive mode.\n", + fwprintf(stderr,L"%s: Warning, could not set correct interactive mode. %s\n", argv[0], service_name); print_last_error(); /* Not severe or??? */ @@ -865,9 +871,9 @@ int do_add_or_set(int argc, char **argv){ set_keys(service_name, new_entries); /* Update service comment if needed */ if(set_comment) { - if (!set_service_comment(new_entries[Comment].data.bytes)) { - fprintf(stderr,"%s: Warning, could not set correct " - "service description (comment)", + if (!set_service_comment(new_entries[Comment].data.string)) { + fwprintf(stderr,L"%s: Warning, could not set correct " + L"service description (comment) %s", argv[0], service_name); print_last_error(); } @@ -878,64 +884,64 @@ int do_add_or_set(int argc, char **argv){ malloced, but we'll exit anyway, so... */ cleanup_old(); if(add) - printf("%s: Service %s added to system.\n", + wprintf(L"%s: Service %s added to system.\n", argv[0], service_name); else - printf("%s: Service %s updated.\n", + wprintf(L"%s: Service %s updated.\n", argv[0], service_name); return 0; } -int do_rename(int argc, char **argv){ +int do_rename(int argc, wchar_t **argv){ RegEntry *current = empty_reg_tab(); RegEntry *dummy = empty_reg_tab(); SC_HANDLE scm; SC_HANDLE service; if(argc < 3){ - fprintf(stderr,"%s: No old servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No old servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } if(argc < 4){ - fprintf(stderr,"%s: No new servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No new servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[3]; if(fetch_current(dummy)){ - fprintf(stderr,"%s: A service with the name %s already " - "exists.\n", + fwprintf(stderr,L"%s: A service with the name %s already " + L"exists.\n", argv[0],service_name); return 1; } service_name = argv[2]; if(!fetch_current(current)){ - fprintf(stderr,"%s: Error, old service name %s does not exist.\n", + fwprintf(stderr,L"%s: Error, old service name %s does not exist.\n", argv[0],service_name); return 1; } - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); if(!open_service_config(&scm,&service)){ - fprintf(stderr,"%s: Error, unable to communicate with service control" - " manager.\n", + fwprintf(stderr,L"%s: Error, unable to communicate with service control" + L" manager.\n", argv[0]); print_last_error(); return 1; } - if(!ChangeServiceConfig(service, - SERVICE_NO_CHANGE, - SERVICE_NO_CHANGE, - SERVICE_NO_CHANGE, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - argv[3])){ - fprintf(stderr,"%s: Error, unable to communicate with service control" - " manager.\n", + if(!ChangeServiceConfigW(service, + SERVICE_NO_CHANGE, + SERVICE_NO_CHANGE, + SERVICE_NO_CHANGE, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + argv[3])){ + fwprintf(stderr,L"%s: Error, unable to communicate with service control" + L" manager.\n", argv[0]); print_last_error(); CloseServiceHandle(scm); @@ -946,154 +952,154 @@ int do_rename(int argc, char **argv){ CloseServiceHandle(service); if(remove_keys(service_name) != 0) - fprintf(stderr,"%s: Warning, old service parameter keys could not " - "be removed, continuing.\n", argv[0]); + fwprintf(stderr,L"%s: Warning, old service parameter keys could not " + L"be removed, continuing.\n", argv[0]); /* Update registry */ register_logkeys(); set_keys(argv[3], current); - printf("%s: Service %s renamed to %s.\n", + wprintf(L"%s: Service %s renamed to %s.\n", argv[0], service_name, argv[3]); return 0; } -int do_remove(int argc, char **argv){ +int do_remove(int argc, wchar_t **argv){ RegEntry *current = empty_reg_tab(); int rem_res; BOOL found; if(argc < 3){ - fprintf(stderr,"%s: No servicename given!\n",argv[0]); + fwprintf(stderr,L"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; found = fetch_current(current); if(found){ - real_service_name = _strdup(current[InternalServiceName].data.bytes); + real_service_name = _wcsdup(current[InternalServiceName].data.string); } else { - real_service_name = _strdup(service_name); + real_service_name = _wcsdup(service_name); } if(found) free_keys(current); if(stop_service() && !wait_service_trans(SERVICE_RUNNING, SERVICE_STOP_PENDING, SERVICE_STOPPED, 60)){ - fprintf(stderr,"%s: Failed to stop running service %s.\n", + fwprintf(stderr,L"%s: Failed to stop running service %s.\n", argv[0],service_name); print_last_error(); return 1; } if(!remove_service()){ - fprintf(stderr,"%s: Unable to remove service (not enough " - "privileges?)\n",argv[0]); + fwprintf(stderr,L"%s: Unable to remove service (not enough " + L"privileges?)\n",argv[0]); print_last_error(); return 1; } if((rem_res = remove_keys(service_name)) > 0){ - fprintf(stderr,"%s: Warning, service parameter keys belonged to old " - "erlsrv version.\n", argv[0]); + fwprintf(stderr,L"%s: Warning, service parameter keys belonged to old " + L"erlsrv version.\n", argv[0]); /* Backward compatibility... */ } else if(rem_res < 0) { - fprintf(stderr,"%s: Error, service parameter keys nonexistent.\n", + fwprintf(stderr,L"%s: Error, service parameter keys nonexistent.\n", argv[0]); return 1; } - printf("%s: Service %s removed from system.\n", + wprintf(L"%s: Service %s removed from system.\n", argv[0], service_name); return 0; } -BOOL list_one(char *servicename, RegEntry *keys, BOOL longlist){ - char *onfail; - char *prio; - char *debugtype; +BOOL list_one(wchar_t *servicename, RegEntry *keys, BOOL longlist){ + wchar_t *onfail; + wchar_t *prio; + wchar_t *debugtype; switch(keys[OnFail].data.value){ case ON_FAIL_RESTART: - onfail = "restart"; + onfail = L"restart"; break; case ON_FAIL_RESTART_ALWAYS: - onfail = "restart_always"; + onfail = L"restart_always"; break; case ON_FAIL_REBOOT: - onfail = "reboot"; + onfail = L"reboot"; break; default: - onfail = "ignore"; + onfail = L"ignore"; } switch(keys[DebugType].data.value){ case DEBUG_TYPE_NEW: - debugtype = "new"; + debugtype = L"new"; break; case DEBUG_TYPE_REUSE: - debugtype = "reuse"; + debugtype = L"reuse"; break; case DEBUG_TYPE_CONSOLE: - debugtype = "console"; + debugtype = L"console"; break; default: - debugtype = "none"; + debugtype = L"none"; } switch(keys[Priority].data.value){ case HIGH_PRIORITY_CLASS: - prio = "high"; + prio = L"high"; break; case IDLE_PRIORITY_CLASS: - prio = "low"; + prio = L"low"; break; case REALTIME_PRIORITY_CLASS: - prio = "realtime"; + prio = L"realtime"; break; case NORMAL_PRIORITY_CLASS: - prio = "default"; + prio = L"default"; break; default: - prio = "unknown/faulty"; + prio = L"unknown/faulty"; } if(longlist){ - char *env = envdup(keys[Env].data.bytes); - char **arg = env_to_arg(env); - char **pek = arg; - printf("Service name: %s\n", + wchar_t *env = envdup(keys[Env].data.string); + wchar_t **arg = env_to_arg(env); + wchar_t **pek = arg; + wprintf(L"Service name: %s\n", servicename); - printf("StopAction: %s\n", - keys[StopAction].data.bytes); - printf("OnFail: %s\n",onfail); - printf("Machine: %s\n", + wprintf(L"StopAction: %s\n", + keys[StopAction].data.string); + wprintf(L"OnFail: %s\n",onfail); + wprintf(L"Machine: %s\n", keys[Machine].data.expand.unexpanded); - printf("WorkDir: %s\n", + wprintf(L"WorkDir: %s\n", keys[WorkDir].data.expand.unexpanded); - if(*keys[SName].data.bytes) - printf("SName: %s\n", - keys[SName].data.bytes); + if(*keys[SName].data.string) + wprintf(L"SName: %s\n", + keys[SName].data.string); else - printf("Name: %s\n", - keys[Name].data.bytes); - printf("Priority: %s\n",prio); - printf("DebugType: %s\n",debugtype); - printf("Args: %s\n", + wprintf(L"Name: %s\n", + keys[Name].data.string); + wprintf(L"Priority: %s\n",prio); + wprintf(L"DebugType: %s\n",debugtype); + wprintf(L"Args: %s\n", keys[Args].data.expand.unexpanded); - printf("InternalServiceName: %s\n", - keys[InternalServiceName].data.bytes); - printf("Comment: %s\n", - keys[Comment].data.bytes); - printf("Env:\n"); + wprintf(L"InternalServiceName: %s\n", + keys[InternalServiceName].data.string); + wprintf(L"Comment: %s\n", + keys[Comment].data.string); + wprintf(L"Env:\n"); while(*pek){ - printf("\t%s\n",*pek); + wprintf(L"\t%s\n",*pek); ++pek; } /* env is easier to free...*/ env = arg_to_env(arg); free(env); } else { - printf("%s\t%s\t%s\t%s\t%s\n", + wprintf(L"%s\t%s\t%s\t%s\t%s\n", servicename, - (*keys[Name].data.bytes) ? - keys[Name].data.bytes : - keys[SName].data.bytes, + (*keys[Name].data.string) ? + keys[Name].data.string : + keys[SName].data.string, prio, onfail, keys[Args].data.expand.unexpanded); @@ -1102,15 +1108,15 @@ BOOL list_one(char *servicename, RegEntry *keys, BOOL longlist){ } -int do_list(int argc, char **argv){ +int do_list(int argc, wchar_t **argv){ if(argc < 3){ RegEntryDesc *all_keys = get_all_keys(); if(!all_keys){ - fprintf(stderr,"%s: No services found in registry.\n", + fwprintf(stderr,L"%s: No services found in registry.\n", argv[0]); return 0; } - printf("Service\t(S)Name\tPrio\tOnFail\tArgs\n"); + wprintf(L"Service\t(S)Name\tPrio\tOnFail\tArgs\n"); while(all_keys->servicename){ list_one(all_keys->servicename,all_keys->entries,FALSE); ++all_keys; @@ -1121,8 +1127,8 @@ int do_list(int argc, char **argv){ service_name = argv[2]; keys = get_keys(service_name); if(!keys){ - fprintf(stderr,"%s: Could not retrieve any " - "registered data for %s.\n",argv[0],service_name); + fwprintf(stderr,L"%s: Could not retrieve any " + L"registered data for %s.\n",argv[0],service_name); return 1; } list_one(service_name, keys, TRUE); @@ -1133,15 +1139,15 @@ int do_list(int argc, char **argv){ #define READ_CHUNK 100 #define ARGV_CHUNK 20 -char *safe_get_line(void){ +wchar_t *safe_get_line(void){ int lsize = READ_CHUNK; - char *line = malloc(READ_CHUNK); + wchar_t *line = malloc(READ_CHUNK*sizeof(wchar_t)); int pos = 0; int ch; - while((ch = getchar()) != EOF && ch != '\n'){ + while((ch = getwchar()) != EOF && ch != L'\n'){ if(pos + 1 >= lsize){ - line = realloc(line,(lsize += READ_CHUNK)); + line = realloc(line,(lsize += READ_CHUNK)*sizeof(wchar_t)); assert(line); } line[pos++] = ch; @@ -1150,22 +1156,22 @@ char *safe_get_line(void){ free(line); return NULL; } - line[pos] = '\0'; + line[pos] = L'\0'; return line; } -void read_arguments(int *pargc, char ***pargv){ +void read_arguments(int *pargc, wchar_t ***pargv){ int argc = 0; int asize = ARGV_CHUNK; - char **argv = malloc(ARGV_CHUNK*sizeof(char *)); - char *tmp; + wchar_t **argv = malloc(ARGV_CHUNK*sizeof(wchar_t *)); + wchar_t *tmp; argv[0] = (*pargv)[0]; argc = 1; while((tmp = safe_get_line()) != NULL){ if(argc + 1 >= asize){ - argv = realloc(argv,(asize += ARGV_CHUNK)*sizeof(char *)); + argv = realloc(argv,(asize += ARGV_CHUNK)*sizeof(wchar_t *)); assert(argv); } argv[argc++] = tmp; @@ -1258,40 +1264,54 @@ void release_lock(void) { -int interactive_main(int argc, char **argv){ - char *action = argv[1]; +int interactive_main(int argc, wchar_t **argv){ + wchar_t *action = argv[1]; int res; - + + _setmode(_fileno(stdin), _O_U8TEXT); /* set stdin to UTF8 */ + _setmode(_fileno(stdout), _O_U8TEXT); /* set stdout to UTF8 */ + _setmode(_fileno(stderr), _O_U8TEXT); /* set stderr to UTF8 */ + if (take_lock() != 0) { - fprintf(stderr,"%s: unable to acquire global lock (%s).\n",argv[0], + fwprintf(stderr,L"%s: unable to acquire global lock (%s).\n",argv[0], ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE); return 1; } - if(!_stricmp(action,"readargs")){ + if(!_wcsicmp(action,L"readargs")){ read_arguments(&argc,&argv); action = argv[1]; } - if(!_stricmp(action,"set") || !_stricmp(action,"add")) + +#ifdef HARDDEBUG + {int i; + for(i=0; i < argc; i++) { + fwprintf(stderr, L"%s ", argv[i]); + } + fwprintf(stderr, L"\n"); + } +#endif + + if(!_wcsicmp(action,L"set") || !_wcsicmp(action,L"add")) res = do_add_or_set(argc,argv); - else if(!_stricmp(action,"rename")) + else if(!_wcsicmp(action,L"rename")) res = do_rename(argc,argv); - else if(!_stricmp(action,"remove")) + else if(!_wcsicmp(action,L"remove")) res = do_remove(argc,argv); - else if(!_stricmp(action,"list")) + else if(!_wcsicmp(action,L"list")) res = do_list(argc,argv); - else if(!_stricmp(action,"start") || - !_stricmp(action,"start_disabled") || - !_stricmp(action,"stop") || - !_stricmp(action,"enable") || - !_stricmp(action,"disable")) + else if(!_wcsicmp(action,L"start") || + !_wcsicmp(action,L"start_disabled") || + !_wcsicmp(action,L"stop") || + !_wcsicmp(action,L"enable") || + !_wcsicmp(action,L"disable")) res = do_manage(argc,argv); - else if(_stricmp(action,"?") && - _stricmp(action,"/?") && - _stricmp(action,"-?") && - *action != 'h' && - *action != 'H') { - fprintf(stderr,"%s: action %s not implemented.\n",argv[0],action); + else if(_wcsicmp(action,L"?") && + _wcsicmp(action,L"/?") && + _wcsicmp(action,L"-?") && + *action != L'h' && + *action != L'H') { + fwprintf(stderr,L"%s: action %s not implemented.\n",argv[0],action); do_usage(argv[0]); res = 1; } else { diff --git a/erts/etc/win32/erlsrv/erlsrv_interactive.h b/erts/etc/win32/erlsrv/erlsrv_interactive.h index 23e69e508d..03cf4b3339 100644 --- a/erts/etc/win32/erlsrv/erlsrv_interactive.h +++ b/erts/etc/win32/erlsrv/erlsrv_interactive.h @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2011. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -21,6 +22,6 @@ #define ERLSRV_INTERACTIVE_GLOBAL_SEMAPHORE "{468d6954-e355-415f-968f-d257cb0feef4}" -int interactive_main(int argc, char **argv); +int interactive_main(int argc, wchar_t **argv); #endif /* _ERLSRV_INTERACTIVE_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_main.c b/erts/etc/win32/erlsrv/erlsrv_main.c index 920a4a1827..521e7687f4 100644 --- a/erts/etc/win32/erlsrv/erlsrv_main.c +++ b/erts/etc/win32/erlsrv/erlsrv_main.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -25,7 +26,7 @@ #include "erlsrv_interactive.h" #include "erlsrv_service.h" -int main(int argc, char **argv){ +int wmain(int argc, wchar_t **argv){ if(argc > 1) return interactive_main(argc,argv); else diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.c b/erts/etc/win32/erlsrv/erlsrv_registry.c index c1aa9f2b67..eb2a8c567c 100644 --- a/erts/etc/win32/erlsrv/erlsrv_registry.c +++ b/erts/etc/win32/erlsrv/erlsrv_registry.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -24,38 +25,37 @@ #include "erlsrv_global.h" #include "erlsrv_registry.h" -#define LOG_TYPE "System" -#define LOG_ROOT \ -"SYSTEM\\CurrentControlSet\\Services\\EventLog\\" LOG_TYPE "\\" +#define LOG_TYPE L"System" +#define LOG_ROOT L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\" LOG_TYPE L"\\" #define LOG_APP_KEY APP_NAME #define BASE_KEY HKEY_LOCAL_MACHINE #define PRODUCT_NAME APP_NAME -#define OLD_PRODUCT_VERSION "1.0" -#define PRODUCT_VERSION "1.1" -#define PROG_KEY "SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME "\\" PRODUCT_VERSION -#define OLD_PROG_KEY "SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME "\\" OLD_PRODUCT_VERSION +#define OLD_PRODUCT_VERSION L"1.0" +#define PRODUCT_VERSION L"1.1" +#define PROG_KEY L"SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME L"\\" PRODUCT_VERSION +#define OLD_PROG_KEY L"SOFTWARE\\Ericsson\\Erlang\\" PRODUCT_NAME L"\\" OLD_PRODUCT_VERSION #define MAX_KEY_LEN MAX_PATH -static const char * const noString = "\0"; +static const wchar_t * const noString = L"\0"; #define MAX_MANDATORY_REG_ENTRY 10 /* InternalServiceName == reg_entries[10] */ static RegEntry reg_entries[] = { - {"StopAction",REG_SZ,NULL}, - {"OnFail",REG_DWORD,NULL}, - {"Machine",REG_EXPAND_SZ,NULL}, - {"Env", REG_MULTI_SZ,NULL}, - {"WorkDir", REG_EXPAND_SZ,NULL}, - {"Priority",REG_DWORD,NULL}, - {"SName",REG_SZ,NULL}, - {"Name",REG_SZ,NULL}, - {"Args",REG_EXPAND_SZ,NULL}, - {"DebugType",REG_DWORD,NULL}, - {"InternalServiceName",REG_SZ,NULL}, + {L"StopAction",REG_SZ,NULL}, + {L"OnFail",REG_DWORD,NULL}, + {L"Machine",REG_EXPAND_SZ,NULL}, + {L"Env", REG_MULTI_SZ,NULL}, + {L"WorkDir", REG_EXPAND_SZ,NULL}, + {L"Priority",REG_DWORD,NULL}, + {L"SName",REG_SZ,NULL}, + {L"Name",REG_SZ,NULL}, + {L"Args",REG_EXPAND_SZ,NULL}, + {L"DebugType",REG_DWORD,NULL}, + {L"InternalServiceName",REG_SZ,NULL}, /* Non mandatory follows */ - {"Comment",REG_SZ,NULL} + {L"Comment",REG_SZ,NULL} }; @@ -73,8 +73,8 @@ void free_keys(RegEntry *keys){ for(i=0;i<num_reg_entries && keys[i].name != NULL;++i){ if((keys[i].type == REG_SZ || keys[i].type == REG_EXPAND_SZ || keys[i].type == REG_MULTI_SZ) && - keys[i].data.bytes != noString){ - free(keys[i].data.bytes); + keys[i].data.string != noString){ + free(keys[i].data.string); if(keys[i].type == REG_EXPAND_SZ && keys[i].data.expand.unexpanded != noString) free(keys[i].data.expand.unexpanded); @@ -92,32 +92,32 @@ void free_all_keys(RegEntryDesc *descs){ free(descs); } -RegEntry *get_keys(char *servicename){ +RegEntry *get_keys(wchar_t *servicename){ RegEntry *res = NULL; HKEY prog_key; int key_opened = 0; int i; DWORD ret; - char *copy; - char *tmpbuf; + wchar_t *copy; + wchar_t *tmpbuf; DWORD tmpbuflen; - char key_to_open[MAX_KEY_LEN]; + wchar_t key_to_open[MAX_KEY_LEN]; DWORD val_type; - char *val_data = malloc(MAX_KEY_LEN); + wchar_t *val_data = (wchar_t *)malloc(MAX_KEY_LEN * sizeof(wchar_t)); DWORD val_datalen; DWORD val_datasiz = MAX_KEY_LEN; - if(strlen(PROG_KEY) + strlen(servicename) + 2 > MAX_KEY_LEN) + if(wcslen(PROG_KEY) + wcslen(servicename) + 2 > MAX_KEY_LEN) goto error; - sprintf(key_to_open,"%s\\%s",PROG_KEY,servicename); + swprintf(key_to_open,MAX_KEY_LEN,L"%s\\%s",PROG_KEY,servicename); - if(RegOpenKeyEx(BASE_KEY, - key_to_open, - 0, - KEY_QUERY_VALUE, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, + key_to_open, + 0, + KEY_QUERY_VALUE, + &prog_key) != ERROR_SUCCESS) goto error; key_opened = 1; @@ -128,12 +128,12 @@ RegEntry *get_keys(char *servicename){ for(i=0;i<num_reg_entries;++i){ for(;;){ val_datalen = val_datasiz; - ret = RegQueryValueEx(prog_key, - reg_entries[i].name, - NULL, - &val_type, - (BYTE *) val_data, - &val_datalen); + ret = RegQueryValueExW(prog_key, + reg_entries[i].name, + NULL, + &val_type, + (BYTE *) val_data, + &val_datalen); if(ret == ERROR_SUCCESS){ if(reg_entries[i].type == val_type) break; @@ -167,41 +167,41 @@ RegEntry *get_keys(char *servicename){ copy = NULL; switch(reg_entries[i].type){ case REG_EXPAND_SZ: - if(!val_datalen || val_data[0] == '\0'){ - copy = (char *) noString; - res[i].data.expand.unexpanded = (char *) noString; + if(!val_datalen || val_data[0] == L'\0'){ + copy = (wchar_t *) noString; + res[i].data.expand.unexpanded = (wchar_t *) noString; } else { - tmpbuf = malloc(MAX_KEY_LEN); + tmpbuf = (wchar_t *) malloc(MAX_KEY_LEN * sizeof(wchar_t)); tmpbuflen = (DWORD) MAX_KEY_LEN; for(;;){ - ret = ExpandEnvironmentStrings(val_data,tmpbuf,tmpbuflen); + ret = ExpandEnvironmentStringsW(val_data,tmpbuf,tmpbuflen); if(!ret){ free(tmpbuf); goto error; }else if(ret > tmpbuflen){ - tmpbuf=realloc(tmpbuf,tmpbuflen=ret); + tmpbuf=realloc(tmpbuf,(tmpbuflen=ret)*sizeof(wchar_t)); } else { - copy = strdup(tmpbuf); + copy = wcsdup(tmpbuf); free(tmpbuf); break; } } - res[i].data.expand.unexpanded = strdup(val_data); + res[i].data.expand.unexpanded = wcsdup(val_data); } case REG_MULTI_SZ: case REG_SZ: if(!copy){ if(!val_datalen || - ((val_datalen == 1 && val_data[0] == '\0') || - (val_datalen == 2 && val_data[0] == '\0' && - val_data[1] == '\0'))){ - copy = (char *) noString; + ((val_datalen == 2 && val_data[0] == L'\0') || + (val_datalen == 4 && val_data[0] == L'\0' && + val_data[1] == L'\0'))){ + copy = (wchar_t *) noString; } else { - copy = malloc(val_datalen); - memcpy(copy,val_data,val_datalen); + copy = malloc(val_datalen); /* val_datalen in bytes */ + memcpy(copy,val_data,val_datalen); } } - res[i].data.bytes = copy; + res[i].data.string = copy; break; case REG_DWORD: memcpy(&res[i].data.value,val_data,sizeof(DWORD)); @@ -222,32 +222,32 @@ error: return NULL; } -int set_keys(char *servicename, RegEntry *keys){ +int set_keys(wchar_t *servicename, RegEntry *keys){ HKEY prog_key; int key_opened = 0; int i; - char key_to_open[MAX_KEY_LEN]; + wchar_t key_to_open[MAX_KEY_LEN]; DWORD disposition; - if(strlen(PROG_KEY) + strlen(servicename) + 2 > MAX_KEY_LEN) + if(wcslen(PROG_KEY) + wcslen(servicename) + 2 > MAX_KEY_LEN) goto error; - sprintf(key_to_open,"%s\\%s",PROG_KEY,servicename); + swprintf(key_to_open,MAX_KEY_LEN,L"%s\\%s",PROG_KEY,servicename); - if(RegOpenKeyEx(BASE_KEY, - key_to_open, - 0, - KEY_SET_VALUE, - &prog_key) != ERROR_SUCCESS){ - if(RegCreateKeyEx(BASE_KEY, - key_to_open, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_SET_VALUE, - NULL, - &prog_key, - &disposition) != ERROR_SUCCESS) - goto error; + if(RegOpenKeyExW(BASE_KEY, + key_to_open, + 0, + KEY_SET_VALUE, + &prog_key) != ERROR_SUCCESS){ + if(RegCreateKeyExW(BASE_KEY, + key_to_open, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, + NULL, + &prog_key, + &disposition) != ERROR_SUCCESS) + goto error; } key_opened = 1; @@ -258,19 +258,19 @@ int set_keys(char *servicename, RegEntry *keys){ int j; switch(keys[i].type){ case REG_SZ: - ptr = keys[i].data.bytes; - siz = strlen(ptr)+1; + ptr = keys[i].data.string; + siz = (wcslen(ptr)+1)*sizeof(wchar_t); break; case REG_EXPAND_SZ: ptr = keys[i].data.expand.unexpanded; - siz = strlen(ptr)+1; + siz = (wcslen(ptr)+1)*sizeof(wchar_t); break; case REG_MULTI_SZ: - ptr = keys[i].data.bytes; - for(j=0;!(((char *)ptr)[j] == '\0' && - ((char *)ptr)[j+1] == '\0');++j) + ptr = keys[i].data.string; + for(j=0;!(((wchar_t *)ptr)[j] == L'\0' && + ((wchar_t *)ptr)[j+1] == L'\0');++j) ; - siz=(DWORD)j+2; + siz=(j+2)*sizeof(wchar_t); break; case REG_DWORD: ptr = &keys[i].data.value; @@ -280,15 +280,15 @@ int set_keys(char *servicename, RegEntry *keys){ goto error; } #ifdef HARDDEBUG - fprintf(stderr,"%s %s:%d\n",keys[i].name, - (keys[i].type == REG_DWORD) ? "(dword)" : ptr,siz); + fprintf(stderr,"%S %S:%d\n",keys[i].name, + (keys[i].type == REG_DWORD) ? L"(dword)" : ptr,siz); #endif - if(RegSetValueEx(prog_key, - keys[i].name, - 0, - keys[i].type, - ptr, - siz) != ERROR_SUCCESS) + if(RegSetValueExW(prog_key, + keys[i].name, + 0, + keys[i].type, + ptr, + siz) != ERROR_SUCCESS) goto error; } RegCloseKey(prog_key); @@ -299,15 +299,15 @@ error: return 1; } -static int do_remove_keys(char *servicename, const char *prog_key_name){ +static int do_remove_keys(wchar_t *servicename, const wchar_t *prog_key_name){ HKEY prog_key; - if(RegOpenKeyEx(BASE_KEY, - prog_key_name, - 0, - KEY_ALL_ACCESS, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, + prog_key_name, + 0, + KEY_ALL_ACCESS, + &prog_key) != ERROR_SUCCESS) return -1; - if(RegDeleteKey(prog_key,servicename) != ERROR_SUCCESS){ + if(RegDeleteKeyW(prog_key,servicename) != ERROR_SUCCESS){ RegCloseKey(prog_key); return -1; } @@ -315,7 +315,7 @@ static int do_remove_keys(char *servicename, const char *prog_key_name){ return 0; } -int remove_keys(char *servicename){ +int remove_keys(wchar_t *servicename){ int ret; if((ret = do_remove_keys(servicename, PROG_KEY)) < 0){ @@ -335,33 +335,33 @@ RegEntryDesc *get_all_keys(void){ HKEY prog_key; int key_opened = 0; DWORD enum_index; - char name[MAX_KEY_LEN]; + wchar_t name[MAX_KEY_LEN]; DWORD namelen; - char class[MAX_KEY_LEN]; + wchar_t class[MAX_KEY_LEN]; DWORD classlen; FILETIME ft; res[ndx].servicename = NULL; - if(RegOpenKeyEx(BASE_KEY, PROG_KEY, 0, - KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, - &prog_key) != ERROR_SUCCESS) + if(RegOpenKeyExW(BASE_KEY, PROG_KEY, 0, + KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, + &prog_key) != ERROR_SUCCESS) goto error; key_opened = 1; for(enum_index = 0, namelen = MAX_KEY_LEN, classlen = MAX_KEY_LEN; - ERROR_SUCCESS == RegEnumKeyEx(prog_key, - enum_index, - name, - &namelen, - NULL, - class, - &classlen, - &ft); + ERROR_SUCCESS == RegEnumKeyExW(prog_key, + enum_index, + name, + &namelen, + NULL, + class, + &classlen, + &ft); ++enum_index, namelen = MAX_KEY_LEN, classlen = MAX_KEY_LEN){ if(ndx >= res_siz - 1) res = realloc(res, (res_siz += 10)*sizeof(RegEntryDesc)); if(!(res[ndx].entries = get_keys(name))) - goto error; - res[ndx].servicename = strdup(name); + goto error; + res[ndx].servicename = wcsdup(name); res[++ndx].servicename = NULL; } RegCloseKey(prog_key); @@ -380,24 +380,24 @@ int register_logkeys(void){ EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; DWORD catcount=1; - char filename[2048]; + wchar_t filename[2048]; DWORD fnsiz=2048; - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, - LOG_ROOT LOG_APP_KEY, 0, - NULL, REG_OPTION_NON_VOLATILE, - KEY_SET_VALUE, NULL, - &key, &disposition) != ERROR_SUCCESS) + if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, + LOG_ROOT LOG_APP_KEY, 0, + NULL, REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, NULL, + &key, &disposition) != ERROR_SUCCESS) return -1; - if(!GetModuleFileName(NULL, filename, fnsiz)) + if(!GetModuleFileNameW(NULL, filename, fnsiz)) return -1; - if(RegSetValueEx(key, "EventMessageFile", - 0, REG_EXPAND_SZ, (LPBYTE) filename, - strlen(filename)+1) != ERROR_SUCCESS) + if(RegSetValueExW(key, L"EventMessageFile", + 0, REG_EXPAND_SZ, (LPBYTE) filename, + (wcslen(filename)+1)*sizeof(wchar_t)) != ERROR_SUCCESS) return -1; - if(RegSetValueEx(key, "TypesSupported", - 0, REG_DWORD, (LPBYTE) &types, - sizeof(DWORD)) != ERROR_SUCCESS) + if(RegSetValueExW(key, L"TypesSupported", + 0, REG_DWORD, (LPBYTE) &types, + sizeof(DWORD)) != ERROR_SUCCESS) return -1; return 0; } diff --git a/erts/etc/win32/erlsrv/erlsrv_registry.h b/erts/etc/win32/erlsrv/erlsrv_registry.h index fbccc5416a..885d021497 100644 --- a/erts/etc/win32/erlsrv/erlsrv_registry.h +++ b/erts/etc/win32/erlsrv/erlsrv_registry.h @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -20,20 +21,20 @@ #define _ERLSRV_REGISTRY_H typedef struct _reg_entry { - char *name; + wchar_t *name; DWORD type; union { - char *bytes; + wchar_t *string; DWORD value; struct { - char *bytes; - char *unexpanded; + wchar_t *string; + wchar_t *unexpanded; } expand; } data; } RegEntry; typedef struct _reg_entry_desc { - char *servicename; + wchar_t *servicename; RegEntry *entries; } RegEntryDesc; @@ -67,10 +68,10 @@ extern int num_reg_entries; RegEntry *empty_reg_tab(void); void free_keys(RegEntry *keys); void free_all_keys(RegEntryDesc *descs); -RegEntry *get_keys(char *servicename); -int set_keys(char *servicename, RegEntry *keys); +RegEntry *get_keys(wchar_t *servicename); +int set_keys(wchar_t *servicename, RegEntry *keys); RegEntryDesc *get_all_keys(void); -int remove_keys(char *servicename); +int remove_keys(wchar_t *servicename); int register_logkeys(void); #endif /* _ERLSRV_REGISTRY_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_service.c b/erts/etc/win32/erlsrv/erlsrv_service.c index 58738ee445..f5d5c0b174 100644 --- a/erts/etc/win32/erlsrv/erlsrv_service.c +++ b/erts/etc/win32/erlsrv/erlsrv_service.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2012. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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,8 +100,8 @@ static BOOL reset_current(){ } static VOID WINAPI handler(DWORD control){ - char buffer[1024]; - sprintf(buffer,"handler called with control = %d.",(int) control); + wchar_t buffer[1024]; + swprintf(buffer,1024,L"handler called with control = %d.",(int) control); log_debug(buffer); switch(control){ case SERVICE_CONTROL_STOP: @@ -119,7 +120,7 @@ typedef struct _server_info { RegEntry *keys; PROCESS_INFORMATION info; HANDLE erl_stdin; - char *event_name; + wchar_t *event_name; } ServerInfo; @@ -138,7 +139,7 @@ static BOOL reset_acl(SaveAclStruct *save_acl){ return FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ - log_warning("Failed to open access token."); + log_warning(L"Failed to open access token."); return FALSE; } save_acl->initialized = FALSE; @@ -146,7 +147,7 @@ static BOOL reset_acl(SaveAclStruct *save_acl){ TokenDefaultDacl, save_acl->defdacl, sizeof(TOKEN_DEFAULT_DACL))){ - log_warning("Failed to get default ACL from token."); + log_warning(L"Failed to get default ACL from token."); CloseHandle(tokenh); LocalFree(save_acl->defdacl); LocalFree(save_acl->newacl); @@ -177,7 +178,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ save_acl->initialized = FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ - log_warning("Failed to open access token."); + log_warning(L"Failed to open access token."); return FALSE; } save_acl->defdacl = &dummy; @@ -188,7 +189,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ sizeof(TOKEN_DEFAULT_DACL), &required); if(required == 0){ - log_warning("Failed to get any ACL info from token."); + log_warning(L"Failed to get any ACL info from token."); CloseHandle(tokenh); return FALSE; } @@ -200,7 +201,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ &required)){ #ifdef HARDDEBUG { - char *mes; + wchar_t *mes; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, @@ -213,7 +214,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ LocalFree(mes); } #endif - log_warning("Failed to get default ACL from token."); + log_warning(L"Failed to get default ACL from token."); CloseHandle(tokenh); return FALSE; } @@ -221,7 +222,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ oldacl = save_acl->defdacl->DefaultDacl; if(!GetAclInformation(oldacl, &si, sizeof(si), AclSizeInformation)){ - log_warning("Failed to get size information for ACL"); + log_warning(L"Failed to get size information for ACL"); CloseHandle(tokenh); return FALSE; } @@ -237,7 +238,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ 0, 0, &extra_sid)){ - log_warning("Failed to initialize administrator SID."); + log_warning(L"Failed to initialize administrator SID."); CloseHandle(tokenh); return FALSE; } @@ -248,7 +249,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ newacl = LocalAlloc(LPTR,newsize); if(!InitializeAcl(newacl, newsize, ACL_REVISION)){ - log_warning("Failed to initialize new ACL."); + log_warning(L"Failed to initialize new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -258,7 +259,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ for(i=0;i<((int)si.AceCount);++i){ ACE_HEADER *ace_header; if (!GetAce (oldacl, i, &ace_header)){ - log_warning("Failed to get ACE from old ACL."); + log_warning(L"Failed to get ACE from old ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -266,7 +267,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ } if(!AddAce(newacl,ACL_REVISION,0xffffffff,ace_header, ace_header->AceSize)){ - log_warning("Failed to set ACE in new ACL."); + log_warning(L"Failed to set ACE in new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -277,7 +278,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ ACL_REVISION2, PROCESS_ALL_ACCESS, extra_sid)){ - log_warning("Failed to add system ACE to new ACL."); + log_warning(L"Failed to add system ACE to new ACL."); LocalFree(newacl); FreeSid(extra_sid); return FALSE; @@ -288,7 +289,7 @@ static BOOL new_acl(SaveAclStruct *save_acl){ TokenDefaultDacl, &newdacl, sizeof(newdacl))){ - log_warning("Failed to set token information"); + log_warning(L"Failed to set token information"); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); @@ -302,18 +303,18 @@ static BOOL new_acl(SaveAclStruct *save_acl){ return TRUE; } -static char **find_arg(char **arg, char *str){ - char *tmp; +static wchar_t **find_arg(wchar_t **arg, wchar_t *str){ + wchar_t *tmp; int len; - str = strdup(str); - if((tmp = strchr(str,'=')) == NULL) + str = wcsdup(str); + if((tmp = wcschr(str,L'=')) == NULL) goto fail; tmp++; - *tmp = '\0'; + *tmp = L'\0'; len = tmp - str; while(*arg != NULL){ - if(!_strnicmp(*arg,str,len)){ + if(!_wcsnicmp(*arg,str,len)){ free(str); return arg; } @@ -324,11 +325,11 @@ fail: return NULL; } -static char **merge_environment(char *current, char *add){ - char **c_arg = env_to_arg(envdup(current)); - char **a_arg = env_to_arg(envdup(add)); - char **new; - char **tmp; +static wchar_t **merge_environment(wchar_t *current, wchar_t *add){ + wchar_t **c_arg = env_to_arg(envdup(current)); + wchar_t **a_arg = env_to_arg(envdup(add)); + wchar_t **new; + wchar_t **tmp; int i,j; for(i=0;c_arg[i] != NULL;++i) @@ -336,19 +337,19 @@ static char **merge_environment(char *current, char *add){ for(j=0;a_arg[j] != NULL;++j) ; - new = malloc(sizeof(char *)*(i + j + 3)); + new = malloc(sizeof(wchar_t *)*(i + j + 3)); for(i = 0; c_arg[i] != NULL; ++i) - new[i] = strdup(c_arg[i]); + new[i] = wcsdup(c_arg[i]); new[i] = NULL; for(j = 0; a_arg[j] != NULL; ++j){ if((tmp = find_arg(new,a_arg[j])) != NULL){ free(*tmp); - *tmp = strdup(a_arg[j]); + *tmp = wcsdup(a_arg[j]); } else { - new[i++] = strdup(a_arg[j]); + new[i++] = wcsdup(a_arg[j]); new[i] = NULL; } } @@ -358,12 +359,12 @@ static char **merge_environment(char *current, char *add){ } -static char *get_next_debug_file(char *prefix){ - char *buffer = malloc(strlen(prefix)+12); +static wchar_t *get_next_debug_file(wchar_t *prefix){ + wchar_t *buffer = malloc((wcslen(prefix)+12)*sizeof(wchar_t)); int i; for(i=1;i<100;++i){ - sprintf(buffer,"%s.%d",prefix,i); - if(GetFileAttributes(buffer) == 0xFFFFFFFF) + swprintf(buffer,wcslen(prefix)+12,L"%s.%d",prefix,i); + if(GetFileAttributesW(buffer) == 0xFFFFFFFF) return buffer; } return NULL; @@ -372,56 +373,66 @@ static char *get_next_debug_file(char *prefix){ static BOOL start_a_service(ServerInfo *srvi){ - STARTUPINFO start; - char execbuff[MAX_PATH*4]; /* FIXME: Can get overflow! */ - char namebuff[MAX_PATH]; - char errbuff[MAX_PATH*4]; /* hmmm.... */ + STARTUPINFOW start; + wchar_t namebuff[MAX_PATH]; + wchar_t *execbuff; + wchar_t *errbuff; HANDLE write_pipe = NULL, read_pipe = NULL; SECURITY_ATTRIBUTES pipe_security; SECURITY_ATTRIBUTES attr; HANDLE nul; SaveAclStruct save_acl; - char *my_environ; + wchar_t *my_environ; BOOL console_allocated = FALSE; + int bufflen=0; - if(!(*(srvi->keys[Env].data.bytes))){ + if(!(*(srvi->keys[Env].data.string))){ my_environ = NULL; } else { - char *tmp; - char **merged = merge_environment((tmp = GetEnvironmentStrings()), - srvi->keys[Env].data.bytes); - FreeEnvironmentStrings(tmp); + wchar_t *tmp; + wchar_t **merged = merge_environment((tmp = GetEnvironmentStringsW()), + srvi->keys[Env].data.string); + FreeEnvironmentStringsW(tmp); my_environ = arg_to_env(merged); } - if(!*(srvi->keys[Machine].data.bytes) || - (!*(srvi->keys[SName].data.bytes) && - !*(srvi->keys[Name].data.bytes))){ - log_error("Not enough parameters for erlang service."); + if(!*(srvi->keys[Machine].data.string) || + (!*(srvi->keys[SName].data.string) && + !*(srvi->keys[Name].data.string))){ + log_error(L"Not enough parameters for erlang service."); if(my_environ) free(my_environ); return FALSE; } - if(*(srvi->keys[SName].data.bytes)) - sprintf(namebuff,"-nohup -sname %s",srvi->keys[SName].data.bytes); + if(*(srvi->keys[SName].data.string)) + swprintf(namebuff,MAX_PATH,L"-nohup -sname %s",srvi->keys[SName].data.string); else - sprintf(namebuff,"-nohup -name %s",srvi->keys[Name].data.bytes); + swprintf(namebuff,MAX_PATH,L"-nohup -name %s",srvi->keys[Name].data.string); if(srvi->keys[DebugType].data.value == DEBUG_TYPE_CONSOLE) - strcat(namebuff," -keep_window"); + wcscat(namebuff,L" -keep_window"); + + bufflen = MAX_PATH + + wcslen(srvi->keys[Machine].data.string) + + wcslen(srvi->event_name) + + wcslen(namebuff) + + wcslen(srvi->keys[Args].data.string); + + execbuff = malloc(bufflen * sizeof(wchar_t)); + errbuff = malloc((MAX_PATH + bufflen) * sizeof(wchar_t)); if (srvi->event_name != NULL) { - sprintf(execbuff,"\"%s\" -service_event %s %s %s", - srvi->keys[Machine].data.bytes, - srvi->event_name, - namebuff, - srvi->keys[Args].data.bytes); + swprintf(execbuff,bufflen,L"\"%s\" -service_event %s %s %s", + srvi->keys[Machine].data.string, + srvi->event_name, + namebuff, + srvi->keys[Args].data.string); } else { - sprintf(execbuff,"\"%s\" %s %s", - srvi->keys[Machine].data.bytes, - namebuff, - srvi->keys[Args].data.bytes); + swprintf(execbuff,bufflen,L"\"%s\" %s %s", + srvi->keys[Machine].data.string, + namebuff, + srvi->keys[Args].data.string); } memset (&start, 0, sizeof (start)); @@ -435,45 +446,49 @@ static BOOL start_a_service(ServerInfo *srvi){ if(console_allocated = AllocConsole()) SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),coord); else - log_warning("Unable to allocate debugging console!"); - } else if(*(srvi->keys[StopAction].data.bytes) || + log_warning(L"Unable to allocate debugging console!"); + } else if(*(srvi->keys[StopAction].data.string) || srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG){ pipe_security.nLength = sizeof(pipe_security); pipe_security.lpSecurityDescriptor = NULL; pipe_security.bInheritHandle = TRUE; if(!CreatePipe(&read_pipe,&write_pipe,&pipe_security,0)){ - log_error("Could not create pipe for erlang service."); + log_error(L"Could not create pipe for erlang service."); if(my_environ) - free(my_environ); + free(my_environ); + free(execbuff); + free(errbuff); return FALSE; } if(srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG){ - char *filename; - if(*(srvi->keys[WorkDir].data.bytes)){ - filename = malloc(strlen(srvi->keys[WorkDir].data.bytes) + 1 + - strlen(service_name)+strlen(".debug")+1); - sprintf(filename,"%s\\%s.debug", - srvi->keys[WorkDir].data.bytes, - service_name); + wchar_t *filename; + if(*(srvi->keys[WorkDir].data.string)){ + int filenamelen = (wcslen(srvi->keys[WorkDir].data.string) + 1 + + wcslen(service_name)+wcslen(L".debug")+1); + filename = malloc(filenamelen*sizeof(wchar_t)); + swprintf(filename,filenamelen,L"%s\\%s.debug", + srvi->keys[WorkDir].data.string, + service_name); } else { - filename = malloc(strlen(service_name)+strlen(".debug")+1); - sprintf(filename,"%s.debug",service_name); + int filenamelen = wcslen(service_name)+wcslen(L".debug")+1; + filename = malloc(filenamelen*sizeof(wchar_t)); + swprintf(filename,filenamelen,L"%s.debug",service_name); } log_debug(filename); if(srvi->keys[DebugType].data.value == DEBUG_TYPE_NEW){ - char *tmpfn = get_next_debug_file(filename); + wchar_t *tmpfn = get_next_debug_file(filename); if(tmpfn){ free(filename); filename = tmpfn; } else { - log_warning("Number of debug files exceeds system defined " - "limit, reverting to DebugType: reuse. "); + log_warning(L"Number of debug files exceeds system defined " + L"limit, reverting to DebugType: reuse. "); } } - nul = CreateFile(filename, + nul = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &pipe_security, @@ -492,9 +507,9 @@ static BOOL start_a_service(ServerInfo *srvi){ } if(nul == NULL){ log_error((srvi->keys[DebugType].data.value != DEBUG_TYPE_NO_DEBUG) - ? "Could not create debug file. " - "(Working directory not valid?)" - : "Cold not open NUL!"); + ? L"Could not create debug file. " + L"(Working directory not valid?)" + : L"Cold not open NUL!"); start.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); start.hStdError = GetStdHandle(STD_ERROR_HANDLE); } @@ -510,23 +525,24 @@ static BOOL start_a_service(ServerInfo *srvi){ new_acl(&save_acl); - if(!CreateProcess(NULL, - execbuff, - &attr, - NULL, - (read_pipe != NULL), - CREATE_DEFAULT_ERROR_MODE | - (srvi->keys[Priority].data.value), - my_environ, - (*(srvi->keys[WorkDir].data.bytes)) ? - srvi->keys[WorkDir].data.bytes : NULL, - &start, - &(srvi->info))){ - sprintf(errbuff,"Could not start erlang service " - "with commandline \"%s\".", - service_name, - execbuff - ); + if(!CreateProcessW(NULL, + execbuff, + &attr, + NULL, + (read_pipe != NULL), + CREATE_UNICODE_ENVIRONMENT | + CREATE_DEFAULT_ERROR_MODE | + (srvi->keys[Priority].data.value), + my_environ, + (*(srvi->keys[WorkDir].data.string)) ? + srvi->keys[WorkDir].data.string : NULL, + &start, + &(srvi->info))){ + swprintf(errbuff,bufflen+MAX_PATH,L"Could not start erlang service \"%s\"" + L"with commandline [%s].", + service_name, + execbuff + ); log_error(errbuff); if(read_pipe != NULL){ CloseHandle(read_pipe); @@ -539,14 +555,16 @@ static BOOL start_a_service(ServerInfo *srvi){ reset_acl(&save_acl); if(my_environ) free(my_environ); + free(execbuff); + free(errbuff); return FALSE; } if(console_allocated) FreeConsole(); #ifdef HARDDEBUG - sprintf(errbuff, - "Started %s with the following commandline: " - "%s",service_name,execbuff); + swprintf(errbuff,bufflen+MAX_PATH, + L"Started %s with the following commandline: %s", + service_name,execbuff); log_debug(errbuff); #endif if(read_pipe != NULL){ @@ -559,19 +577,21 @@ static BOOL start_a_service(ServerInfo *srvi){ reset_acl(&save_acl); if(my_environ) free(my_environ); + free(execbuff); + free(errbuff); return TRUE; } -static HANDLE create_erlang_event(char *event_name) +static HANDLE create_erlang_event(wchar_t *event_name) { HANDLE e; - if ((e = OpenEvent(EVENT_ALL_ACCESS,FALSE,event_name)) == NULL) { - if ((e = CreateEvent(NULL, TRUE, FALSE, event_name)) == NULL) { - log_warning("Could not create or access erlang termination event"); + if ((e = OpenEventW(EVENT_ALL_ACCESS,FALSE,event_name)) == NULL) { + if ((e = CreateEventW(NULL, TRUE, FALSE, event_name)) == NULL) { + log_warning(L"Could not create or access erlang termination event"); } } else { if (!ResetEvent(e)) { - log_warning("Could not reset erlang termination event."); + log_warning(L"Could not reset erlang termination event."); } } return e; @@ -580,17 +600,18 @@ static HANDLE create_erlang_event(char *event_name) static BOOL stop_erlang(ServerInfo *srvi, int waithint, int *checkpoint){ DWORD written = 0; - char *action = srvi->keys[StopAction].data.bytes; - DWORD towrite = strlen(action)+1; - char *toerl; + wchar_t *wc_action = srvi->keys[StopAction].data.string; + DWORD towrite = wcslen(wc_action); + char *toerl; DWORD exitcode; int i; int kill; if(towrite > 2 && srvi->erl_stdin != NULL){ - toerl = malloc(towrite+1); - strcpy(toerl,action); - strcat(toerl,"\n"); + towrite = WideCharToMultiByte(CP_UTF8, 0, wc_action, -1, NULL, 0, NULL, NULL); + toerl = malloc((1+towrite)*sizeof(char)); + WideCharToMultiByte(CP_UTF8, 0, wc_action, -1, toerl, towrite, NULL, NULL); + strcat(toerl, "\n"); WriteFile(srvi->erl_stdin, toerl, towrite, &written,0); free(toerl); /* Give it 45 seconds to terminate */ @@ -605,9 +626,9 @@ static BOOL stop_erlang(ServerInfo *srvi, int waithint, ++(*checkpoint); set_stop_pending(waithint,*checkpoint); } - log_warning("StopAction did not terminate erlang. Trying forced kill."); + log_warning(L"StopAction did not terminate erlang. Trying forced kill."); } - log_debug("Terminating erlang..."); + log_debug(L"Terminating erlang..."); kill = 1; if(eventKillErlang != NULL && SetEvent(eventKillErlang) != 0){ for(i=0;i<10;++i){ @@ -621,25 +642,25 @@ static BOOL stop_erlang(ServerInfo *srvi, int waithint, } else { #ifdef HARDDEBUG { - char *mes; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &mes, - 0, - NULL ); + wchar_t *mes; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &mes, + 0, + NULL ); log_info(mes); LocalFree(mes); } #endif - log_debug("Could not send control event to Erlang process"); + log_debug(L"Could not send control event to Erlang process"); } if(kill){ - log_warning("Using TerminateProcess to kill erlang."); + log_warning(L"Using TerminateProcess to kill erlang."); if(!TerminateProcess(srvi->info.hProcess,NO_ERROR)) - log_error("TerminateProcess failed"); + log_error(L"TerminateProcess failed"); } GetExitCodeProcess(srvi->info.hProcess,&exitcode); CloseHandle(srvi->info.hProcess); @@ -668,14 +689,14 @@ static BOOL enable_privilege(void) { static BOOL pull_service_name(void){ SC_HANDLE scm; DWORD sz = 1024; - static char service_name_buff[1024]; + static wchar_t service_name_buff[1024]; if((scm = OpenSCManager(NULL, NULL, GENERIC_READ)) == NULL){ return FALSE; } - if(!GetServiceDisplayName(scm,real_service_name,service_name_buff,&sz)) + if(!GetServiceDisplayNameW(scm,real_service_name,service_name_buff,&sz)) return FALSE; CloseServiceHandle(scm); service_name = service_name_buff; @@ -683,7 +704,7 @@ static BOOL pull_service_name(void){ } -static VOID WINAPI service_main_loop(DWORD argc, char **argv){ +static VOID WINAPI service_main_loop(DWORD argc, wchar_t **argv){ int waithint = 30000; int checkpoint = 1; RegEntry *keys; @@ -692,36 +713,35 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ HANDLE harr[2]; FILETIME creationt,exitt,kernelt,usert; LONGLONG creationl,exitl,diffl; - char event_name[MAX_PATH] = "ErlSrv_"; - char executable_name[MAX_PATH]; + wchar_t event_name[MAX_PATH] = L"ErlSrv_"; + wchar_t executable_name[MAX_PATH]; #ifdef DEBUG - char errorbuff[2048]; /* FIXME... */ + wchar_t errorbuff[2048]; /* FIXME... */ #endif int success_wait = NO_SUCCESS_WAIT; real_service_name = argv[0]; if(!pull_service_name()){ - log_error("Could not get Display name of erlang service."); + log_error(L"Could not get Display name of erlang service."); set_stopped(ERROR_CANTREAD); return; } - SetEnvironmentVariable((LPCTSTR) SERVICE_ENV, (LPCTSTR) service_name); + SetEnvironmentVariableW(SERVICE_ENV, service_name); - strncat(event_name, service_name, MAX_PATH - strlen(event_name)); - event_name[MAX_PATH - 1] = '\0'; + wcsncat(event_name, service_name, MAX_PATH - wcslen(event_name)); + event_name[MAX_PATH - 1] = L'\0'; - if(!GetModuleFileName(NULL, executable_name, MAX_PATH)){ - log_error("Unable to retrieve module file name, " EXECUTABLE_ENV - " will not be set."); + if(!GetModuleFileNameW(NULL, executable_name, MAX_PATH)){ + log_error(L"Unable to retrieve module file name, " EXECUTABLE_ENV + L" will not be set."); } else { - char quoted_exe_name[MAX_PATH+4]; - sprintf(quoted_exe_name, "\"%s\"", executable_name); - SetEnvironmentVariable((LPCTSTR) EXECUTABLE_ENV, - (LPCTSTR) quoted_exe_name); + wchar_t quoted_exe_name[MAX_PATH+4]; + swprintf(quoted_exe_name, MAX_PATH+4, L"\"%s\"", executable_name); + SetEnvironmentVariableW(EXECUTABLE_ENV, quoted_exe_name); } - log_debug("Here we go, service_main_loop..."); + log_debug(L"Here we go, service_main_loop..."); currentState = SERVICE_START_PENDING; InitializeCriticalSection(&crit); eventStop = CreateEvent(NULL,FALSE,FALSE,NULL); @@ -730,13 +750,13 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } else { srvi.event_name = NULL; } - statusHandle = RegisterServiceCtrlHandler(real_service_name, &handler); + statusHandle = RegisterServiceCtrlHandlerW(real_service_name, &handler); if(!statusHandle) return; set_start_pending(waithint,checkpoint); keys = get_keys(service_name); if(!keys){ - log_error("Could not get registry keys for erlang service."); + log_error(L"Could not get registry keys for erlang service."); set_stopped(ERROR_CANTREAD); return; } @@ -745,7 +765,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ ++checkpoint; if(!start_a_service(&srvi)){ - log_error("Could not start erlang machine"); + log_error(L"Could not start erlang machine"); set_stopped(ERROR_PROCESS_ABORTED); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); @@ -769,16 +789,16 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ if(ret == WAIT_TIMEOUT){ /* Just do the "success reporting" and continue */ if(success_wait == INITIAL_SUCCESS_WAIT){ - log_info("Erlang service started successfully."); + log_info(L"Erlang service started successfully."); } else { - log_warning("Erlang service restarted"); + log_warning(L"Erlang service restarted"); } success_wait = NO_SUCCESS_WAIT; continue; } if(ret == WAIT_FAILED || (int)(ret-WAIT_OBJECT_0) >= 2){ set_stopped(WAIT_FAILED); - log_error("Internal error, could not wait for objects."); + log_error(L"Internal error, could not wait for objects."); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); } @@ -791,7 +811,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ checkpoint = 2; /* 1 is taken by the handler */ set_stop_pending(waithint,checkpoint); if(stop_erlang(&srvi,waithint,&checkpoint)){ - log_debug("Erlang machine is stopped"); + log_debug(L"Erlang machine is stopped"); CloseHandle(eventStop); if (eventKillErlang != NULL) { CloseHandle(eventKillErlang); @@ -802,7 +822,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ free_keys(keys); return; } else { - log_warning("Unable to stop erlang service."); + log_warning(L"Unable to stop erlang service."); set_running(); continue; } @@ -811,12 +831,12 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ save_keys = keys; keys = get_keys(service_name); if(!keys){ - log_error("Could not reload registry keys."); + log_error(L"Could not reload registry keys."); keys = srvi.keys = save_keys; } else { #ifdef HARDDEBUG - sprintf(errorbuff,"Reloaded the registry keys because %s stopped.", - service_name); + swprintf(errorbuff,2048,L"Reloaded the registry keys because %s stopped.", + service_name); log_debug(errorbuff); #endif /* HARDDEBUG */ free_keys(save_keys); @@ -827,7 +847,7 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ if(!GetProcessTimes(srvi.info.hProcess,&creationt, &exitt,&kernelt,&usert)){ DWORD rcode = GetLastError(); - log_error("Could not get process time of terminated process."); + log_error(L"Could not get process time of terminated process."); CloseHandle(srvi.info.hProcess); CloseHandle(srvi.info.hThread); CloseHandle(eventStop); @@ -850,15 +870,14 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ diffl = exitl - creationl; diffl /= 10000000; #ifdef DEBUG - sprintf(errorbuff,"Process lived for %d seconds", (int) diffl); + swprintf(errorbuff,2048,L"Process lived for %d seconds", (int) diffl); log_debug(errorbuff); #endif if(diffl > CYCLIC_RESTART_LIMIT || srvi.keys[OnFail].data.value == ON_FAIL_RESTART_ALWAYS){ if(!start_a_service(&srvi)){ - log_error("Unable to restart failed erlang service, " - "aborting."); + log_error(L"Unable to restart failed erlang service, aborting."); CloseHandle(eventStop); set_stopped(ERROR_PROCESS_ABORTED); if (eventKillErlang != NULL) { @@ -867,19 +886,19 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ free_keys(keys); return; } - log_warning("Restarted erlang machine."); + log_warning(L"Restarted erlang machine."); if(diffl <= CYCLIC_RESTART_LIMIT) - log_warning("Possible cyclic restarting of erlang machine."); + log_warning(L"Possible cyclic restarting of erlang machine."); success_wait = RESTART_SUCCESS_WAIT; harr[0] = srvi.info.hProcess; } else { if(success_wait == INITIAL_SUCCESS_WAIT){ - log_error("Erlang machine stopped instantly " - "(distribution name conflict?). " - "The service is not restarted, ignoring OnFail option."); + log_error(L"Erlang machine stopped instantly " + L"(distribution name conflict?). " + L"The service is not restarted, ignoring OnFail option."); } else { - log_error("Erlang machine seems to die " - "continously, not restarted."); + log_error(L"Erlang machine seems to die " + L"continously, not restarted."); } CloseHandle(eventStop); set_stopped(ERROR_PROCESS_ABORTED); @@ -890,21 +909,21 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ return; } } else if(srvi.keys[OnFail].data.value == ON_FAIL_REBOOT){ - log_error("Rebooting because erlang machine stopped."); + log_error(L"Rebooting because erlang machine stopped."); enable_privilege(); if(!InitiateSystemShutdown("",NULL,0,TRUE,TRUE)){ - log_error("Failed to reboot!"); + log_error(L"Failed to reboot!"); #ifdef HARDDEBUG { - char *mes; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &mes, - 0, - NULL ); + wchar_t *mes; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &mes, + 0, + NULL ); log_debug(mes); LocalFree(mes); } @@ -923,13 +942,13 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } else { DWORD ecode = NO_ERROR; if(success_wait == NO_SUCCESS_WAIT){ - log_warning("Erlang machine voluntarily stopped. " - "The service is not restarted as OnFail " - "is set to ignore."); + log_warning(L"Erlang machine voluntarily stopped. " + L"The service is not restarted as OnFail " + L"is set to ignore."); } else { - log_error("Erlang machine stopped instantly " - "(distribution name conflict?). " - "The service is not restarted as OnFail is set to ignore."); + log_error(L"Erlang machine stopped instantly " + L"(distribution name conflict?). " + L"The service is not restarted as OnFail is set to ignore."); ecode = ERROR_PROCESS_ABORTED; } CloseHandle(srvi.info.hProcess); @@ -946,20 +965,19 @@ static VOID WINAPI service_main_loop(DWORD argc, char **argv){ } } -int service_main(int argc, char **argv){ - char dummy_name[] = ""; - SERVICE_TABLE_ENTRY serviceTable[] = +int service_main(int argc, wchar_t **argv){ + wchar_t dummy_name[] = L""; + SERVICE_TABLE_ENTRYW serviceTable[] = { { dummy_name, - (LPSERVICE_MAIN_FUNCTION) service_main_loop}, + (LPSERVICE_MAIN_FUNCTIONW) service_main_loop}, { NULL, NULL } }; BOOL success; - success = - StartServiceCtrlDispatcher(serviceTable); + success = StartServiceCtrlDispatcherW(serviceTable); if (!success) - log_error("Could not initiate service"); - log_debug("service_main done its job"); + log_error(L"Could not initiate service"); + log_debug(L"service_main done its job"); return 0; } diff --git a/erts/etc/win32/erlsrv/erlsrv_service.h b/erts/etc/win32/erlsrv/erlsrv_service.h index 3eab275836..4e1148cac2 100644 --- a/erts/etc/win32/erlsrv/erlsrv_service.h +++ b/erts/etc/win32/erlsrv/erlsrv_service.h @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -27,6 +28,6 @@ #define RESTART_SUCCESS_WAIT 2 -int service_main(int argc, char **argv); +int service_main(int argc, wchar_t **argv); #endif /* _ERLSRV_SERVICE_H */ diff --git a/erts/etc/win32/erlsrv/erlsrv_util.c b/erts/etc/win32/erlsrv/erlsrv_util.c index da3c6f5ef7..f719082d37 100644 --- a/erts/etc/win32/erlsrv/erlsrv_util.c +++ b/erts/etc/win32/erlsrv/erlsrv_util.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -25,76 +26,76 @@ #include "erlsrv_util.h" #include "erlsrv_logmess.h" -char *service_name = ""; -char *real_service_name = ""; +wchar_t *service_name = L""; +wchar_t *real_service_name = L""; -void log_warning(char *mess){ +void log_warning(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_WARNING_TYPE, 0, MSG_WARNING, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_WARNING_TYPE, 0, MSG_WARNING, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } -void log_error(char *mess){ +void log_error(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_ERROR_TYPE, 0, MSG_ERROR, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_ERROR_TYPE, 0, MSG_ERROR, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } -void log_info(char *mess){ +void log_info(wchar_t *mess){ HANDLE logh; - char *strings[] = {service_name, mess , NULL}; + wchar_t *strings[] = {service_name, mess , NULL}; - if(!(logh = RegisterEventSource(NULL,APP_NAME))) + if(!(logh = RegisterEventSourceW(NULL,APP_NAME))) return; - ReportEvent(logh, EVENTLOG_INFORMATION_TYPE, 0, MSG_INFO, - NULL, 2, 0, strings, NULL); + ReportEventW(logh, EVENTLOG_INFORMATION_TYPE, 0, MSG_INFO, + NULL, 2, 0, strings, NULL); DeregisterEventSource(logh); } #ifndef NDEBUG -void log_debug(char *mess){ - char *buff=malloc(strlen(mess)+100); - sprintf(buff,"DEBUG! %s",mess); +void log_debug(wchar_t *mess){ + wchar_t *buff=malloc((wcslen(mess)+100)*sizeof(wchar_t)); + swprintf(buff,wcslen(mess)+100,L"DEBUG! %s",mess); log_info(buff); free(buff); } #endif -char *envdup(char *env){ - char *tmp; +wchar_t *envdup(wchar_t *env){ + wchar_t *tmp; int len; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1) + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1) ; len = (tmp - env) + 1; if(len == 1) ++len; - tmp = malloc(len); - memcpy(tmp,env,len); + tmp = malloc(len*sizeof(wchar_t)); + memcpy(tmp,env,len*sizeof(wchar_t)); return tmp; } -char **env_to_arg(char *env){ - char **ret; - char *tmp; +wchar_t **env_to_arg(wchar_t *env){ + wchar_t **ret; + wchar_t *tmp; int i; int num_strings = 0; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1) + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1) ++num_strings; /* malloc enough to insert ONE string */ - ret = malloc(sizeof(char *) * (num_strings + 2)); + ret = malloc(sizeof(wchar_t *) * (num_strings + 2)); i = 0; - for(tmp = env; *tmp != '\0'; tmp += strlen(tmp)+1){ - ret[i++] = strdup(tmp); + for(tmp = env; *tmp != L'\0'; tmp += wcslen(tmp)+1){ + ret[i++] = wcsdup(tmp); } ret[i] = NULL; free(env); @@ -102,52 +103,52 @@ char **env_to_arg(char *env){ } static int compare(const void *a, const void *b){ - char *s1 = *((char **) a); - char *s2 = *((char **) b); - char *e1 = strchr(s1,'='); - char *e2 = strchr(s2,'='); + wchar_t *s1 = *((wchar_t **) a); + wchar_t *s2 = *((wchar_t **) b); + wchar_t *e1 = wcschr(s1,L'='); + wchar_t *e2 = wcschr(s2,L'='); int ret; int len; if(!e1) - e1 = s1 + strlen(s1); + e1 = s1 + wcslen(s1); if(!e2) - e2 = s2 + strlen(s2); + e2 = s2 + wcslen(s2); if((e1 - s1) > (e2 - s2)) len = (e2 - s2); else len = (e1 - s1); - ret = _strnicmp(s1,s2,len); + ret = _wcsnicmp(s1,s2,len); if(ret == 0) return ((e1 - s1) - (e2 - s2)); else return ret; } -char *arg_to_env(char **arg){ - char *block; - char *pek; +wchar_t *arg_to_env(wchar_t **arg){ + wchar_t *block; + wchar_t *pek; int i; int totlen = 1; /* extra '\0' */ for(i=0;arg[i] != NULL;++i) - totlen += strlen(arg[i])+1; + totlen += wcslen(arg[i])+1; /* sort the environment vector */ - qsort(arg,i,sizeof(char *),&compare); + qsort(arg,i,sizeof(wchar_t *),&compare); if(totlen == 1){ - block = malloc(2); - block[0] = block[1] = '\0'; + block = malloc(2*sizeof(wchar_t)); + block[0] = block[1] = L'\0'; } else { - block = malloc(totlen); + block = malloc(totlen*sizeof(wchar_t)); pek = block; for(i=0; arg[i] != NULL; ++i){ - strcpy(pek, arg[i]); + wcscpy(pek, arg[i]); free(arg[i]); - pek += strlen(pek)+1; + pek += wcslen(pek)+1; } - *pek = '\0'; + *pek = L'\0'; } free(arg); return block; diff --git a/erts/etc/win32/erlsrv/erlsrv_util.h b/erts/etc/win32/erlsrv/erlsrv_util.h index b98a6cd3ef..97cc91834f 100644 --- a/erts/etc/win32/erlsrv/erlsrv_util.h +++ b/erts/etc/win32/erlsrv/erlsrv_util.h @@ -1,48 +1,49 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ #ifndef _ERLSRV_UTIL_H #define _ERLSRV_UTIL_H -extern char *service_name; -extern char *real_service_name; -void log_warning(char *mess); -void log_error(char *mess); -void log_info(char *mess); +extern wchar_t *service_name; +extern wchar_t *real_service_name; +void log_warning(wchar_t *mess); +void log_error(wchar_t *mess); +void log_info(wchar_t *mess); -char *envdup(char *env); +wchar_t *envdup(wchar_t *env); /* ** Call before env_to_arg to get a 'freeable' environment block. */ -char *arg_to_env(char **arg); +wchar_t *arg_to_env(wchar_t **arg); /* ** Frees the argument list before returning! */ -char **env_to_arg(char *env); +wchar_t **env_to_arg(wchar_t *env); /* ** Frees the environment block before returning! */ #ifndef NDEBUG -void log_debug(char *mess); +void log_debug(wchar_t *mess); #else #define log_debug(mess) /* Debug removed */ #endif diff --git a/erts/etc/win32/init_file.c b/erts/etc/win32/init_file.c index 52f6c41d1d..147e299798 100644 --- a/erts/etc/win32/init_file.c +++ b/erts/etc/win32/init_file.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2016. 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% */ @@ -173,7 +174,7 @@ static void digout_key_value(char *line, char **key, char **value) } } -InitFile *load_init_file(char *filename) +InitFile *load_init_file(wchar_t *filename) { HANDLE infile; InitFile *inif; @@ -187,13 +188,13 @@ InitFile *load_init_file(char *filename) int i; - if ( (infile = CreateFile(filename, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) { + if ( (infile = CreateFileW(filename, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) { return NULL; } @@ -280,7 +281,7 @@ InitFile *load_init_file(char *filename) return inif; } -int store_init_file(InitFile *inif, char *filename) +int store_init_file(InitFile *inif, wchar_t *filename) { char *buff; int size = 10; @@ -297,13 +298,13 @@ int store_init_file(InitFile *inif, char *filename) buff[num++] = (Char); \ } while(0) - if ( (outfile = CreateFile(filename, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) { + if ( (outfile = CreateFileW(filename, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) { return INIT_FILE_OPEN_ERROR; } buff = ALLOC(size); diff --git a/erts/etc/win32/init_file.h b/erts/etc/win32/init_file.h index 48d2d2df62..df33d23a35 100644 --- a/erts/etc/win32/init_file.h +++ b/erts/etc/win32/init_file.h @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2003-2009. All Rights Reserved. + * Copyright Ericsson AB 2003-2016. 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% */ @@ -36,10 +37,10 @@ typedef struct { } InitFile; /* Load a file structure from a disk file */ -InitFile *load_init_file(char *filename); +InitFile *load_init_file(wchar_t *filename); /* Stores a file structure into a disk file */ -int store_init_file(InitFile *inif, char *filename); +int store_init_file(InitFile *inif, wchar_t *filename); /* Create an empty file structure */ InitFile *create_init_file(void); diff --git a/erts/etc/win32/msys_tools/erl b/erts/etc/win32/msys_tools/erl index 525253fd84..a2fe924e78 100644 --- a/erts/etc/win32/msys_tools/erl +++ b/erts/etc/win32/msys_tools/erl @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/msys_tools/erlc b/erts/etc/win32/msys_tools/erlc index 3f53ef7f4f..45d466743e 100644 --- a/erts/etc/win32/msys_tools/erlc +++ b/erts/etc/win32/msys_tools/erlc @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/msys_tools/javac.sh b/erts/etc/win32/msys_tools/javac.sh index 2d884bc2c8..6a8b245601 100644 --- a/erts/etc/win32/msys_tools/javac.sh +++ b/erts/etc/win32/msys_tools/javac.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/msys_tools/make_bootstrap_ini.sh b/erts/etc/win32/msys_tools/make_bootstrap_ini.sh index b61965f546..59fc6fc09a 100644 --- a/erts/etc/win32/msys_tools/make_bootstrap_ini.sh +++ b/erts/etc/win32/msys_tools/make_bootstrap_ini.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2011. All Rights Reserved. +# Copyright Ericsson AB 2003-2016. 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/win32/msys_tools/make_local_ini.sh b/erts/etc/win32/msys_tools/make_local_ini.sh index 6c5d84c4f5..046b3e9d00 100644 --- a/erts/etc/win32/msys_tools/make_local_ini.sh +++ b/erts/etc/win32/msys_tools/make_local_ini.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2011. All Rights Reserved. +# Copyright Ericsson AB 2003-2016. 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/win32/msys_tools/vc/ar.sh b/erts/etc/win32/msys_tools/vc/ar.sh index f4c61e1d92..a33c954c0f 100644 --- a/erts/etc/win32/msys_tools/vc/ar.sh +++ b/erts/etc/win32/msys_tools/vc/ar.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/msys_tools/vc/cc.sh b/erts/etc/win32/msys_tools/vc/cc.sh index 38b3d2ee81..2b0482e876 100644 --- a/erts/etc/win32/msys_tools/vc/cc.sh +++ b/erts/etc/win32/msys_tools/vc/cc.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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% # @@ -241,7 +242,7 @@ for x in $SOURCES; do if [ $PREPROCESSING = true ]; then output_flag="-E" else - output_flag="-c -Fo`cmd //C echo ${output_filename}`" + output_flag="-FS -c -Fo`cmd //C echo ${output_filename}`" fi params="$COMMON_CFLAGS $MD $DEBUG_FLAGS $OPTIMIZE_FLAGS \ $CMD ${output_flag} $MPATH" @@ -249,6 +250,8 @@ for x in $SOURCES; do echo cc.sh "$SAVE" >>$CC_SH_DEBUG_LOG echo cl.exe $params >>$CC_SH_DEBUG_LOG fi + # MSYS2 (currently) converts the paths wrong, avoid it + export MSYS2_ARG_CONV_EXCL=-FoC eval cl.exe $params >$MSG_FILE 2>$ERR_FILE RES=$? if test $PREPROCESSING = false; then @@ -265,7 +268,7 @@ for x in $SOURCES; do echo echo after_sed=`date '+%s'` - echo Made dependencises for $x':' `expr $after_sed '-' $start_time` 's' >&2 + echo Made dependencies for $x':' `expr $after_sed '-' $start_time` 's' >&2 fi else cat $MSG_FILE @@ -273,6 +276,7 @@ for x in $SOURCES; do fi rm -f $ERR_FILE $MSG_FILE if [ $RES != 0 ]; then + echo Failed: cl.exe $params rm -rf $TMPOBJDIR exit $RES fi @@ -311,7 +315,10 @@ if [ $LINKING = true ]; then stdlib="-lLIBMTD";; esac # And finally call the next script to do the linking... - params="$out_spec $LINKCMD $stdlib" + params="$out_spec $LINKCMD $stdlib" + if [ "X$CC_SH_DEBUG_LOG" != "X" ]; then + echo ld.sh $ACCUM_OBJECTS $params + fi eval ld.sh $ACCUM_OBJECTS $params RES=$? fi diff --git a/erts/etc/win32/msys_tools/vc/coffix.c b/erts/etc/win32/msys_tools/vc/coffix.c index 1773b222fe..bf1096c425 100644 --- a/erts/etc/win32/msys_tools/vc/coffix.c +++ b/erts/etc/win32/msys_tools/vc/coffix.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1999-2011. All Rights Reserved. + * Copyright Ericsson AB 1999-2016. 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/win32/msys_tools/vc/emu_cc.sh b/erts/etc/win32/msys_tools/vc/emu_cc.sh index 68ce4e359f..2de3a07aca 100644 --- a/erts/etc/win32/msys_tools/vc/emu_cc.sh +++ b/erts/etc/win32/msys_tools/vc/emu_cc.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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% # @@ -28,6 +29,7 @@ WTOOLDIR0=`win2msys_path.sh "$TOOLDIR"` WTOOLDIR=`cmd //C echo $WTOOLDIR0` # Do primitive 'make' newer_exe=`find $TOOLDIR -newer $COFFIX.c -name coffix.exe -print` +export MSYS2_ARG_CONV_EXCL="-FeC" if [ -z $newer_exe ]; then echo recompiling $COFFIX.exe cl.exe -Fe${WTOOLDIR}/coffix.exe ${WTOOLDIR}/coffix.c diff --git a/erts/etc/win32/msys_tools/vc/ld.sh b/erts/etc/win32/msys_tools/vc/ld.sh index 0fcbf6f7d9..8917251f51 100644 --- a/erts/etc/win32/msys_tools/vc/ld.sh +++ b/erts/etc/win32/msys_tools/vc/ld.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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/win32/msys_tools/vc/mc.sh b/erts/etc/win32/msys_tools/vc/mc.sh index 27d985f73e..a074a1a89f 100644 --- a/erts/etc/win32/msys_tools/vc/mc.sh +++ b/erts/etc/win32/msys_tools/vc/mc.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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% # @@ -79,9 +80,14 @@ if [ -n "$OUTPUT_DIRNAME" ]; then exit $RES fi fi +# MSYS2 (currently) converts the paths wrong, avoid it +export MSYS2_ARG_CONV_EXCL= eval $MCC "$CMD" >/tmp/mc.exe.${p}.1 2>/tmp/mc.exe.${p}.2 RES=$? -tail +2 /tmp/mc.exe.${p}.2 >&2 +if [ $RES != 0 ]; then + echo Failed: $MCC "$CMD" +fi +tail -n +2 /tmp/mc.exe.${p}.2 >&2 cat /tmp/mc.exe.${p}.1 rm -f /tmp/mc.exe.${p}.2 /tmp/mc.exe.${p}.1 exit $RES diff --git a/erts/etc/win32/msys_tools/vc/rc.sh b/erts/etc/win32/msys_tools/vc/rc.sh index dfa9e324db..3d1186ca91 100644 --- a/erts/etc/win32/msys_tools/vc/rc.sh +++ b/erts/etc/win32/msys_tools/vc/rc.sh @@ -3,18 +3,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2002-2011. All Rights Reserved. +# Copyright Ericsson AB 2002-2016. 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% # @@ -78,9 +79,14 @@ if [ "X$RC_SH_DEBUG_LOG" != "X" ]; then echo rc.sh "$SAVE" >>$RC_SH_DEBUG_LOG echo rc.exe $CMD >>$RC_SH_DEBUG_LOG fi +# MSYS2 (currently) converts the paths wrong, avoid it +export MSYS2_ARG_CONV_EXCL=-Fo eval $RCC "$CMD" >/tmp/rc.exe.${p}.1 2>/tmp/rc.exe.${p}.2 RES=$? -tail +2 /tmp/rc.exe.${p}.2 >&2 +if [ $RES != 0 ]; then + echo Failed: $RCC "$CMD" +fi +tail -n +2 /tmp/rc.exe.${p}.2 >&2 cat /tmp/rc.exe.${p}.1 rm -f /tmp/rc.exe.${p}.2 /tmp/rc.exe.${p}.1 exit $RES diff --git a/erts/etc/win32/nsis/Makefile b/erts/etc/win32/nsis/Makefile index 7bcecaa264..0b4e0d0359 100644 --- a/erts/etc/win32/nsis/Makefile +++ b/erts/etc/win32/nsis/Makefile @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2003-2012. All Rights Reserved. +# Copyright Ericsson AB 2003-2016. 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% # @@ -41,7 +42,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk TARGET_DIR = $(RELEASE_PATH) -ifeq ($(MSYSTEM),MINGW32) +ifdef MSYSTEM + ifeq ($(MSYSTEM),$(filter $(MSYSTEM),MSYS MINGW32 MINGW64)) + USEMSYS := true + endif +endif + +ifeq ($(USEMSYS),true) MAKENSISFLAGS = //V2 WTESTROOT=$(shell (msys2win_path.sh "$(RELEASE_PATH)")) @@ -62,7 +69,7 @@ else endif REDIST_FILE=$(shell (sh ./find_redist.sh || echo "")) -ifeq ($(MSYSTEM),MINGW32) +ifeq ($(USEMSYS),true) NICEREDISTFILE=$(shell (msys2win_path.sh -m "$(REDIST_FILE)" 2>/dev/null || echo "")) else NICEREDISTFILE=$(shell (cygpath -d -m "$(REDIST_FILE)" 2>/dev/null || echo "")) diff --git a/erts/etc/win32/nsis/dll_version_helper.sh b/erts/etc/win32/nsis/dll_version_helper.sh index e75edf3738..9eafb6ce0e 100755 --- a/erts/etc/win32/nsis/dll_version_helper.sh +++ b/erts/etc/win32/nsis/dll_version_helper.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2013. All Rights Reserved. +# Copyright Ericsson AB 2007-2016. 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/win32/nsis/erlang20.nsi b/erts/etc/win32/nsis/erlang20.nsi index 3333c4a9aa..66746b684d 100644 --- a/erts/etc/win32/nsis/erlang20.nsi +++ b/erts/etc/win32/nsis/erlang20.nsi @@ -7,18 +7,19 @@ ;
; %CopyrightBegin%
;
-; Copyright Ericsson AB 2012. All Rights Reserved.
+; Copyright Ericsson AB 2012-2016. 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%
;
diff --git a/erts/etc/win32/nsis/find_redist.sh b/erts/etc/win32/nsis/find_redist.sh index 7c449c9e4e..c070ad469a 100755 --- a/erts/etc/win32/nsis/find_redist.sh +++ b/erts/etc/win32/nsis/find_redist.sh @@ -2,18 +2,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2011. All Rights Reserved. +# Copyright Ericsson AB 2007-2016. 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% # @@ -163,7 +164,7 @@ fi #echo $BPATH_LIST for BP in $BPATH_LIST; do - for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0" "v7.0A" "v7.1"; do + for verdir in "sdk v2.0" "sdk v3.5" "v6.0A" "v7.0" "v7.0A" "v7.1" "VC redist 1033"; do BPATH=$BP fail=false allow_fail=false diff --git a/erts/etc/win32/port_entry.c b/erts/etc/win32/port_entry.c index 30b54035e0..8b1d3a44b8 100644 --- a/erts/etc/win32/port_entry.c +++ b/erts/etc/win32/port_entry.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2012. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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/win32/resource.h b/erts/etc/win32/resource.h index 697931952a..e59baadb50 100644 --- a/erts/etc/win32/resource.h +++ b/erts/etc/win32/resource.h @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * Copyright Ericsson AB 1997-2016. 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/win32/start_erl.c b/erts/etc/win32/start_erl.c index facf79e5ff..07bcd19b81 100644 --- a/erts/etc/win32/start_erl.c +++ b/erts/etc/win32/start_erl.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1998-2012. All Rights Reserved. + * Copyright Ericsson AB 1998-2016. 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% */ @@ -30,7 +31,7 @@ #include <windows.h> #include <assert.h> -char *progname; +wchar_t *progname; /* * If CASE_SENSITIVE_OPTIONS is specified, options are case sensitive @@ -43,26 +44,26 @@ char *progname; #define strnicmp _strnicmp #endif -#define RELEASE_SUBDIR "\\releases" -#define ERTS_SUBDIR_PREFIX "\\erts-" -#define BIN_SUBDIR "\\bin" -#define REGISTRY_BASE "Software\\Ericsson\\Erlang\\" -#define DEFAULT_DATAFILE "start_erl.data" +#define RELEASE_SUBDIR L"\\releases" +#define ERTS_SUBDIR_PREFIX L"\\erts-" +#define BIN_SUBDIR L"\\bin" +#define REGISTRY_BASE L"Software\\Ericsson\\Erlang\\" +#define DEFAULT_DATAFILE L"start_erl.data" /* Global variables holding option values and command lines */ -char *CommandLineStart = NULL; -char *ErlCommandLine = NULL; -char *MyCommandLine = NULL; -char *DataFileName = NULL; -char *RelDir = NULL; -char *BootFlagsFile = NULL; -char *BootFlags = NULL; -char *RegistryKey = NULL; -char *BinDir = NULL; -char *RootDir = NULL; -char *VsnDir = NULL; -char *Version = NULL; -char *Release = NULL; +wchar_t *CommandLineStart = NULL; +wchar_t *ErlCommandLine = NULL; +wchar_t *MyCommandLine = NULL; +wchar_t *DataFileName = NULL; +wchar_t *RelDir = NULL; +wchar_t *BootFlagsFile = NULL; +wchar_t *BootFlags = NULL; +wchar_t *RegistryKey = NULL; +wchar_t *BinDir = NULL; +wchar_t *RootDir = NULL; +wchar_t *VsnDir = NULL; +wchar_t *Version = NULL; +wchar_t *Release = NULL; BOOL NoConfig=FALSE; PROCESS_INFORMATION ErlProcessInfo; @@ -100,7 +101,7 @@ void exit_help(char *err) ShowLastError(); fprintf(stderr, "** Error: %s\n", err); - printf("Usage:\n%s\n" + printf("Usage:\n%S\n" " [<erlang options>] ++\n" " [-data <datafile>]\n" " {-rootdir <erlang root directory> | \n" @@ -119,56 +120,56 @@ void exit_help(char *err) */ void split_commandline(void) { - char *cmdline = CommandLineStart; + wchar_t *cmdline = CommandLineStart; progname=cmdline; /* Remove the first (quoted) string (our program name) */ - if(*cmdline == '"') { + if(*cmdline == L'"') { cmdline++; /* Skip " */ - while( (*cmdline != '\0') && (*cmdline++) != '"' ) + while( (*cmdline != L'\0') && (*cmdline++) != L'"' ) ; } else { - while( (*cmdline != '\0') && (*cmdline++) != ' ' ) + while( (*cmdline != L'\0') && (*cmdline++) != L' ' ) ; } - while( (*cmdline) == ' ' ) + while( (*cmdline) == L' ' ) cmdline++; - if( *cmdline == '\0') { - ErlCommandLine = ""; - MyCommandLine = ""; + if( *cmdline == L'\0') { + ErlCommandLine = L""; + MyCommandLine = L""; return; } - cmdline[-1] = '\0'; + cmdline[-1] = L'\0'; /* Start from the end of the string and search for "++ " (PLUS PLUS SPACE) */ ErlCommandLine = cmdline; - if(strncmp(cmdline,"++ ",3)) - cmdline = strstr(cmdline," ++ "); + if(wcsncmp(cmdline,L"++ ",3)) + cmdline = wcsstr(cmdline,L" ++ "); if( cmdline == NULL ) { - MyCommandLine = ""; + MyCommandLine = L""; return; } /* Terminate the ErlCommandLine where MyCommandLine starts */ *cmdline++ = '\0'; /* Skip 'whitespace--whitespace' (WHITESPACE MINUS MINUS WHITESPACE) */ - while( (*cmdline) == ' ' ) + while( (*cmdline) == L' ' ) cmdline++; - while( (*cmdline) == '+' ) + while( (*cmdline) == L'+' ) cmdline++; - while( (*cmdline) == ' ' ) + while( (*cmdline) == L' ' ) cmdline++; MyCommandLine = cmdline; #ifdef _DEBUG - fprintf(stderr, "ErlCommandLine: '%s'\n", ErlCommandLine); - fprintf(stderr, "MyCommandLine: '%s'\n", MyCommandLine); + fprintf(stderr, "ErlCommandLine: '%S'\n", ErlCommandLine); + fprintf(stderr, "MyCommandLine: '%S'\n", MyCommandLine); #endif } @@ -178,30 +179,30 @@ void split_commandline(void) * Skips any leading spaces and parses up to NULL or end of quoted string. * Calls exit_help() if an unterminated quote is detected. */ -char * unquote_optionarg(char *str, char **strp) +wchar_t * unquote_optionarg(wchar_t *str, wchar_t **strp) { - char *newstr = (char *)malloc(strlen(str)+1); /* This one is - realloc:ed later */ + /* This one is realloc:ed later */ + wchar_t *newstr = (wchar_t *)malloc((wcslen(str)+1)*sizeof(wchar_t)); int i = 0, inquote = 0; assert(newstr); assert(str); /* Skip leading spaces */ - while( *str == ' ' ) + while( *str == L' ' ) str++; /* Loop while in quote or until EOS or unquoted space */ - while( (inquote==1) || ( (*str!=0) && (*str!=' ') ) ) { + while( (inquote==1) || ( (*str!=0) && (*str!=L' ') ) ) { switch( *str ) { - case '\\': + case L'\\': /* If we are inside a quoted string we should convert \c to c */ - if( inquote && str[1] == '"' ) + if( inquote && str[1] == L'"' ) str++; newstr[i++]=*str++; break; - case '"': + case L'"': inquote = 1-inquote; *str++; break; @@ -220,7 +221,7 @@ char * unquote_optionarg(char *str, char **strp) *strp = str; /* Adjust memblock of newstr */ - newstr = (char *)realloc(newstr, i); + newstr = (wchar_t *)realloc(newstr, i*sizeof(wchar_t)); assert(newstr); return(newstr); } @@ -232,34 +233,34 @@ char * unquote_optionarg(char *str, char **strp) */ void parse_commandline(void) { - char *cmdline = MyCommandLine; + wchar_t *cmdline = MyCommandLine; - while( *cmdline != '\0' ) { + while( *cmdline != L'\0' ) { switch( *cmdline ) { case '-': /* Handle both -arg and /arg */ case '/': *cmdline++; - if( strnicmp(cmdline, "data", 4) == 0) { + if( _wcsnicmp(cmdline, L"data", 4) == 0) { DataFileName = unquote_optionarg(cmdline+4, &cmdline); - } else if( strnicmp(cmdline, "rootdir", 7) == 0) { + } else if( _wcsnicmp(cmdline, L"rootdir", 7) == 0) { RootDir = unquote_optionarg(cmdline+7, &cmdline); #ifdef _DEBUG - fprintf(stderr, "RootDir: '%s'\n", RootDir); + fprintf(stderr, "RootDir: '%S'\n", RootDir); #endif - } else if( strnicmp(cmdline, "reldir", 6) == 0) { + } else if( _wcsnicmp(cmdline, L"reldir", 6) == 0) { RelDir = unquote_optionarg(cmdline+6, &cmdline); #ifdef _DEBUG - fprintf(stderr, "RelDir: '%s'\n", RelDir); + fprintf(stderr, "RelDir: '%S'\n", RelDir); #endif - } else if( strnicmp(cmdline, "bootflags", 9) == 0) { + } else if( _wcsnicmp(cmdline, L"bootflags", 9) == 0) { BootFlagsFile = unquote_optionarg(cmdline+9, &cmdline); - } else if( strnicmp(cmdline, "noconfig", 8) == 0) { + } else if( _wcsnicmp(cmdline, L"noconfig", 8) == 0) { NoConfig=TRUE; #ifdef _DEBUG fprintf(stderr, "NoConfig=TRUE\n"); #endif } else { - fprintf(stderr, "Unkown option: '%s'\n", cmdline); + fprintf(stderr, "Unkown option: '%S'\n", cmdline); exit_help("Unknown command line option"); } break; @@ -281,32 +282,35 @@ void parse_commandline(void) void read_datafile(void) { FILE *fp; - char *newname; + wchar_t *newname; long size; + char *ver; + char *rel; - if(!DataFileName){ - DataFileName = malloc(strlen(DEFAULT_DATAFILE) + 1); - strcpy(DataFileName,DEFAULT_DATAFILE); + if(!DataFileName){ + DataFileName = malloc((wcslen(DEFAULT_DATAFILE) + 1)*sizeof(wchar_t)); + wcscpy(DataFileName,DEFAULT_DATAFILE); } /* Is DataFileName relative or absolute ? */ - if( (DataFileName[0] != '\\') && (strncmp(DataFileName+1, ":\\", 2)!=0) ) { + if( (DataFileName[0] != L'\\') && (wcsncmp(DataFileName+1, L":\\", 2)!=0) ) { /* Relative name, we have to prepend RelDir to it. */ if( !RelDir ) { exit_help("Need -reldir when -data filename has relative path."); } else { - newname = (char *)malloc(strlen(DataFileName)+strlen(RelDir)+2); + size = (wcslen(DataFileName)+wcslen(RelDir)+2); + newname = (wchar_t *)malloc(size*sizeof(wchar_t)); assert(newname); - sprintf(newname, "%s\\%s", RelDir, DataFileName); + swprintf(newname, size, L"%s\\%s", RelDir, DataFileName); free(DataFileName); DataFileName=newname; } } #ifdef _DEBUG - fprintf(stderr, "DataFileName: '%s'\n", DataFileName); + fprintf(stderr, "DataFileName: '%S'\n", DataFileName); #endif - if( (fp=fopen(DataFileName, "rb")) == NULL) { + if( (fp=_wfopen(DataFileName, L"rb")) == NULL) { exit_help("Cannot find the datafile."); } @@ -314,21 +318,33 @@ void read_datafile(void) size=ftell(fp); fseek(fp, 0, SEEK_SET); - Version = (char *)malloc(size+1); - Release = (char *)malloc(size+1); - assert(Version); - assert(Release); + ver = (char *)malloc(size+1); + rel = (char *)malloc(size+1); + assert(ver); + assert(rel); - if( (fscanf(fp, "%s %s", Version, Release)) == 0) { + if( (fscanf(fp, "%s %s", ver, rel)) == 0) { fclose(fp); exit_help("Format error in datafile."); } fclose(fp); + size = MultiByteToWideChar(CP_UTF8, 0, ver, -1, NULL, 0); + Version = malloc(size*sizeof(wchar_t)); + assert(Version); + MultiByteToWideChar(CP_UTF8, 0, ver, -1, Version, size); + free(ver); + + size = MultiByteToWideChar(CP_UTF8, 0, rel, -1, NULL, 0); + Release = malloc(size*sizeof(wchar_t)); + assert(Release); + MultiByteToWideChar(CP_UTF8, 0, rel, -1, Release, size); + free(rel); + #ifdef _DEBUG - fprintf(stderr, "DataFile version: '%s'\n", Version); - fprintf(stderr, "DataFile release: '%s'\n", Release); + fprintf(stderr, "DataFile version: '%S'\n", Version); + fprintf(stderr, "DataFile release: '%S'\n", Release); #endif } @@ -340,31 +356,33 @@ void read_bootflags(void) { FILE *fp; long fsize; - char *newname; - + wchar_t *newname; + char *bootf; + if(BootFlagsFile) { /* Is BootFlagsFile relative or absolute ? */ - if( (BootFlagsFile[0] != '\\') && - (strncmp(BootFlagsFile+1, ":\\", 2)!=0) ) { + if( (BootFlagsFile[0] != L'\\') && + (wcsncmp(BootFlagsFile+1, L":\\", 2)!=0) ) { /* Relative name, we have to prepend RelDir\\Version to it. */ if( !RelDir ) { exit_help("Need -reldir when -bootflags " "filename has relative path."); } else { - newname = (char *)malloc(strlen(BootFlagsFile)+ - strlen(RelDir)+strlen(Release)+3); + int len = wcslen(BootFlagsFile)+ + wcslen(RelDir)+wcslen(Release)+3; + newname = (wchar_t *)malloc(len*sizeof(wchar_t)); assert(newname); - sprintf(newname, "%s\\%s\\%s", RelDir, Release, BootFlagsFile); + swprintf(newname, len, L"%s\\%s\\%s", RelDir, Release, BootFlagsFile); free(BootFlagsFile); BootFlagsFile=newname; } } #ifdef _DEBUG - fprintf(stderr, "BootFlagsFile: '%s'\n", BootFlagsFile); + fprintf(stderr, "BootFlagsFile: '%S'\n", BootFlagsFile); #endif - if( (fp=fopen(BootFlagsFile, "rb")) == NULL) { + if( (fp=_wfopen(BootFlagsFile, L"rb")) == NULL) { exit_help("Could not open BootFlags file."); } @@ -372,80 +390,86 @@ void read_bootflags(void) fsize=ftell(fp); fseek(fp, 0, SEEK_SET); - BootFlags = (char *)malloc(fsize+1); - assert(BootFlags); - if( (fgets(BootFlags, fsize+1, fp)) == NULL) { + bootf = (char *)malloc(fsize+1); + assert(bootf); + if( (fgets(bootf, fsize+1, fp)) == NULL) { exit_help("Error while reading BootFlags file"); } fclose(fp); /* Adjust buffer size */ - BootFlags = (char *)realloc(BootFlags, strlen(BootFlags)+1); - assert(BootFlags); + bootf = (char *)realloc(bootf, strlen(bootf)+1); + assert(bootf); /* Strip \r\n from BootFlags */ - fsize = strlen(BootFlags); + fsize = strlen(bootf); while( fsize > 0 && - ( (BootFlags[fsize-1] == '\r') || - (BootFlags[fsize-1] == '\n') ) ) { - BootFlags[--fsize]=0; + ( (bootf[fsize-1] == '\r') || + (bootf[fsize-1] == '\n') ) ) { + bootf[--fsize]=0; } - + fsize = MultiByteToWideChar(CP_UTF8, 0, bootf, -1, NULL, 0); + BootFlags = malloc(fsize*sizeof(wchar_t)); + assert(BootFlags); + MultiByteToWideChar(CP_UTF8, 0, bootf, -1, BootFlags, fsize); + free(bootf); } else { /* Set empty BootFlags */ - BootFlags = ""; + BootFlags = L""; } #ifdef _DEBUG - fprintf(stderr, "BootFlags: '%s'\n", BootFlags); + fprintf(stderr, "BootFlags: '%S'\n", BootFlags); #endif } long start_new_node(void) { - char *CommandLine; + wchar_t *CommandLine; unsigned long i; - STARTUPINFO si; - DWORD dwExitCode; + STARTUPINFOW si; + DWORD dwExitCode; - i = strlen(RelDir) + strlen(Release) + 4; - VsnDir = (char *)malloc(i); + i = wcslen(RelDir) + wcslen(Release) + 4; + VsnDir = (wchar_t *)malloc(i*sizeof(wchar_t)); assert(VsnDir); - sprintf(VsnDir, "%s\\%s", RelDir, Release); + swprintf(VsnDir, i, L"%s\\%s", RelDir, Release); if( NoConfig ) { - i = strlen(BinDir) + strlen(ErlCommandLine) + - strlen(BootFlags) + 64; - CommandLine = (char *)malloc(i); + i = wcslen(BinDir) + wcslen(ErlCommandLine) + + wcslen(BootFlags) + 64; + CommandLine = (wchar_t *)malloc(i*sizeof(wchar_t)); assert(CommandLine); - sprintf(CommandLine, - "\"%s\\erl.exe\" -boot \"%s\\start\" %s %s", - BinDir, - VsnDir, - ErlCommandLine, - BootFlags); + swprintf(CommandLine, + i, + L"\"%s\\erl.exe\" -boot \"%s\\start\" %s %s", + BinDir, + VsnDir, + ErlCommandLine, + BootFlags); } else { - i = strlen(BinDir) + strlen(ErlCommandLine) - + strlen(BootFlags) + strlen(VsnDir)*2 + 64; - CommandLine = (char *)malloc(i); + i = wcslen(BinDir) + wcslen(ErlCommandLine) + + wcslen(BootFlags) + wcslen(VsnDir)*2 + 64; + CommandLine = (wchar_t *)malloc(i*sizeof(wchar_t)); assert(CommandLine); - sprintf(CommandLine, - "\"%s\\erl.exe\" -boot \"%s\\start\" -config \"%s\\sys\" %s %s", - BinDir, - VsnDir, - VsnDir, - ErlCommandLine, - BootFlags); + swprintf(CommandLine, + i, + L"\"%s\\erl.exe\" -boot \"%s\\start\" -config \"%s\\sys\" %s %s", + BinDir, + VsnDir, + VsnDir, + ErlCommandLine, + BootFlags); } #ifdef _DEBUG - fprintf(stderr, "CommandLine: '%s'\n", CommandLine); + fprintf(stderr, "CommandLine: '%S'\n", CommandLine); #endif /* Initialize the STARTUPINFO structure. */ - memset(&si, 0, sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); + memset(&si, 0, sizeof(STARTUPINFOW)); + si.cb = sizeof(STARTUPINFOW); si.lpTitle = NULL; si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); @@ -453,19 +477,19 @@ long start_new_node(void) si.hStdError = GetStdHandle(STD_ERROR_HANDLE); /* Create the new Erlang process */ - if( (CreateProcess( - NULL, /* pointer to name of executable module */ - CommandLine, /* pointer to command line string */ - NULL, /* pointer to process security attributes */ - NULL, /* pointer to thread security attributes */ - TRUE, /* handle inheritance flag */ - GetPriorityClass(GetCurrentProcess()), - /* creation flags */ - NULL, /* pointer to new environment block */ - BinDir,/* pointer to current directory name */ - &si, /* pointer to STARTUPINFO */ - &ErlProcessInfo /* pointer to PROCESS_INFORMATION */ - )) == FALSE) { + if( (CreateProcessW( + NULL, /* pointer to name of executable module */ + CommandLine, /* pointer to command line string */ + NULL, /* pointer to process security attributes */ + NULL, /* pointer to thread security attributes */ + TRUE, /* handle inheritance flag */ + GetPriorityClass(GetCurrentProcess()), + /* creation flags */ + NULL, /* pointer to new environment block */ + BinDir,/* pointer to current directory name */ + &si, /* pointer to STARTUPINFO */ + &ErlProcessInfo /* pointer to PROCESS_INFORMATION */ + )) == FALSE) { ShowLastError(); exit_help("Failed to start new node"); } @@ -504,6 +528,7 @@ long start_new_node(void) */ void complete_options(void) { + int len; /* Try to find a descent RelDir */ if( !RelDir ) { DWORD sz = 32; @@ -511,15 +536,13 @@ void complete_options(void) DWORD nsz; if (RelDir) free(RelDir); - RelDir = malloc(sz); + RelDir = malloc(sz*sizeof(wchar_t)); if (!RelDir) { fprintf(stderr, "** Error : failed to allocate memory\n"); exit(1); } SetLastError(0); - nsz = GetEnvironmentVariable((LPCTSTR) "RELDIR", - (LPTSTR) RelDir, - sz); + nsz = GetEnvironmentVariableW(L"RELDIR", RelDir, sz); if (nsz == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { free(RelDir); RelDir = NULL; @@ -536,9 +559,10 @@ void complete_options(void) exit_help("Need either Root directory nor Release directory."); } /* Ok, construct our own RelDir from RootDir */ - RelDir = (char *) malloc(strlen(RootDir)+strlen(RELEASE_SUBDIR)+1); + sz = wcslen(RootDir)+wcslen(RELEASE_SUBDIR)+1; + RelDir = (wchar_t *) malloc(sz * sizeof(wchar_t)); assert(RelDir); - sprintf(RelDir, "%s" RELEASE_SUBDIR, RootDir); + swprintf(RelDir, sz, L"%s" RELEASE_SUBDIR, RootDir); read_datafile(); } else { read_datafile(); @@ -548,32 +572,32 @@ void complete_options(void) } if( !RootDir ) { /* Try to construct RootDir from RelDir */ - char *p; - RootDir = malloc(strlen(RelDir)+1); - strcpy(RootDir,RelDir); - p = RootDir+strlen(RootDir)-1; - if (p >= RootDir && (*p == '/' || *p == '\\')) + wchar_t *p; + RootDir = malloc((wcslen(RelDir)+1)*sizeof(wchar_t)); + wcscpy(RootDir,RelDir); + p = RootDir+wcslen(RootDir)-1; + if (p >= RootDir && (*p == L'/' || *p == L'\\')) --p; - while (p >= RootDir && *p != '/' && *p != '\\') + while (p >= RootDir && *p != L'/' && *p != L'\\') --p; if (p <= RootDir) { /* Empty RootDir is also an error */ exit_help("Cannot determine Root directory from " "Release directory."); } - *p = '\0'; + *p = L'\0'; } - - BinDir = (char *) malloc(strlen(RootDir)+strlen(ERTS_SUBDIR_PREFIX)+ - strlen(Version)+strlen(BIN_SUBDIR)+1); + len = wcslen(RootDir)+wcslen(ERTS_SUBDIR_PREFIX)+ + wcslen(Version)+wcslen(BIN_SUBDIR)+1; + BinDir = (wchar_t *) malloc(len * sizeof(wchar_t)); assert(BinDir); - sprintf(BinDir, "%s" ERTS_SUBDIR_PREFIX "%s" BIN_SUBDIR, RootDir, Version); + swprintf(BinDir, len, L"%s" ERTS_SUBDIR_PREFIX L"%s" BIN_SUBDIR, RootDir, Version); read_bootflags(); #ifdef _DEBUG - fprintf(stderr, "RelDir: '%s'\n", RelDir); - fprintf(stderr, "BinDir: '%s'\n", BinDir); + fprintf(stderr, "RelDir: '%S'\n", RelDir); + fprintf(stderr, "BinDir: '%S'\n", BinDir); #endif } @@ -598,17 +622,17 @@ BOOL WINAPI LogoffHandlerRoutine( DWORD dwCtrlType ) int main(void) { DWORD dwExitCode; - char *cmdline; + wchar_t *cmdline; /* Make sure a logoff does not distrurb us. */ SetConsoleCtrlHandler(LogoffHandlerRoutine, TRUE); - cmdline = GetCommandLine(); + cmdline = GetCommandLineW(); assert(cmdline); - CommandLineStart = (char *) malloc(strlen(cmdline) + 1); + CommandLineStart = (wchar_t *) malloc((wcslen(cmdline) + 1)*sizeof(wchar_t)); assert(CommandLineStart); - strcpy(CommandLineStart,cmdline); + wcscpy(CommandLineStart,cmdline); split_commandline(); parse_commandline(); diff --git a/erts/etc/win32/win_erlexec.c b/erts/etc/win32/win_erlexec.c index 11cc6a30f7..39dac358e9 100644 --- a/erts/etc/win32/win_erlexec.c +++ b/erts/etc/win32/win_erlexec.c @@ -1,18 +1,19 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2011. All Rights Reserved. + * Copyright Ericsson AB 1997-2016. 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% */ @@ -62,12 +63,18 @@ static SysGetKeyFunction *sys_get_key_p; static ErlStartFunction *erl_start_p; static SysPrimitiveInitFunction *sys_primitive_init_p; -static HMODULE load_win_beam_dll(char *name) +/* + * To enable debugging of argument processing etc + * #define ARGS_HARDDEBUG 1 + * #define HARDDEBUG 1 + */ + +static HMODULE load_win_beam_dll(wchar_t *name) { HMODULE beam_module; - beam_module=LoadLibrary(name); + beam_module=LoadLibraryW(name); if (beam_module == INVALID_HANDLE_VALUE || beam_module == NULL) { - error("Unable to load emulator DLL\n(%s)",name); + error("Unable to load emulator DLL\n(%S)",name); return NULL; } sys_get_key_p = (SysGetKeyFunction *) @@ -83,9 +90,21 @@ static HMODULE load_win_beam_dll(char *name) #define DLL_ENV "ERL_EMULATOR_DLL" static void -set_env(char *key, char *value) +set_env(char *key, char *value) /* Both in UTF-8 encoding */ { - if (!SetEnvironmentVariable((LPCTSTR) key, (LPCTSTR) value)) + wchar_t *wkey=NULL; + wchar_t *wvalue=NULL; + int keylen; + int valuelen; + + + keylen = MultiByteToWideChar(CP_UTF8, 0, key, -1, NULL, 0); + valuelen = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0); + wkey = malloc(keylen*sizeof(wchar_t)); + wvalue = malloc(valuelen*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, keylen); + MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, valuelen); + if (!SetEnvironmentVariableW( wkey, wvalue)) error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value); } @@ -121,55 +140,97 @@ free_env_val(char *value) int -start_win_emulator(char* emu, char *start_prog, char** argv, int start_detached) +start_win_emulator(char* utf8emu, char *utf8start_prog, char** utf8argv, int start_detached) { - int result; + int len; + int argc = 0; windowed = 1; + while (utf8argv[argc] != NULL) { + ++argc; + } + if (start_detached) { - char *buff; + wchar_t *start_prog=NULL; + int result; + int i; + wchar_t **argv; close(0); close(1); close(2); set_env("ERL_CONSOLE_MODE", "detached"); - set_env(DLL_ENV, emu); + set_env(DLL_ENV, utf8emu); - argv[0] = start_prog; - argv = fnuttify_argv(argv); - result = spawnv(_P_DETACH, start_prog, argv); - free_fnuttified(argv); + utf8argv[0] = utf8start_prog; + utf8argv = fnuttify_argv(utf8argv); + + len = MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, NULL, 0); + start_prog = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, start_prog, len); + + /* Convert utf8argv to multibyte argv */ + argv = malloc((argc+1) * sizeof(wchar_t*)); + for (i=0; i<argc; i++) { + len = MultiByteToWideChar(CP_UTF8, 0, utf8argv[i], -1, NULL, 0); + argv[i] = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8argv[i], -1, argv[i], len); + } + argv[argc] = NULL; + +#ifdef ARGS_HARDDEBUG + { + wchar_t tempbuf[2048] = L""; + wchar_t *sbuf; + int i; + sbuf=tempbuf; + sbuf += swprintf(sbuf, 2048, L"utf16: %s\n", start_prog); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%s|", argv[i]); + }; + sbuf += swprintf(sbuf, 2048, L"\nutf8: \n"); + for (i = 0; i < argc; ++i) { + sbuf += swprintf(sbuf, 2048, L"|%S|", utf8argv[i]); + }; + MessageBoxW(NULL, tempbuf, L"respawn args", MB_OK|MB_ICONERROR); + } +#endif + + result = _wspawnv(_P_DETACH, start_prog, argv); + free_fnuttified(utf8argv); + if (result == -1) { + error("Failed to execute %S: %s", start_prog, win32_errorstr(_doserrno)); + } } else { - int argc = 0; + wchar_t *emu=NULL; #ifdef LOAD_BEAM_DYNAMICALLY - HMODULE beam_module = load_win_beam_dll(emu); -#endif - set_env("ERL_CONSOLE_MODE", "window"); - while (argv[argc] != NULL) { - ++argc; - } + HMODULE beam_module = NULL; + len = MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, NULL, 0); + emu = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, emu, len); #ifdef ARGS_HARDDEBUG { char sbuf[2048] = ""; int i; + strcat(sbuf,utf8emu); + strcat(sbuf,":"); for (i = 0; i < argc; ++i) { strcat(sbuf,"|"); - strcat(sbuf, argv[i]); + strcat(sbuf, utf8argv[i]); strcat(sbuf,"| "); } - MessageBox(NULL, sbuf, "Werl", MB_OK|MB_ICONERROR); + MessageBox(NULL, sbuf, "erl_start args", MB_OK|MB_ICONERROR); } #endif + beam_module = load_win_beam_dll(emu); +#endif + set_env("ERL_CONSOLE_MODE", "window"); #ifdef LOAD_BEAM_DYNAMICALLY (*sys_primitive_init_p)(beam_module); - (*erl_start_p)(argc,argv); + (*erl_start_p)(argc,utf8argv); #else - erl_start(argc, argv); + erl_start(argc,utf8argv); #endif - result = 0; - } - if (result == -1) { - error("Failed to execute %s: %s", emu, win32_errorstr(_doserrno)); } return 0; } @@ -186,61 +247,103 @@ do_keep_window(void) } int -start_emulator(char* emu, char *start_prog, char** argv, int start_detached) +start_emulator(char* utf8emu, char *utf8start_prog, char** utf8argv, int start_detached) { - int result; static char console_mode[] = "tty:ccc"; char* fd_type; char* title; + int len; + int argc = 0; #ifdef HARDDEBUG - fprintf(stderr,"emu = %s, start_prog = %s\n",emu, start_prog); + fprintf(stderr,"utf8emu = %s, start_prog = %s\n", utf8emu, utf8start_prog); #endif fd_type = strchr(console_mode, ':'); fd_type++; _flushall(); - + + while (utf8argv[argc] != NULL) { + ++argc; + } + /* * If no console, we will spawn the emulator detached. */ if (start_detached) { - char *buff; + int result; + int i; + wchar_t *start_prog=NULL; + wchar_t **argv; close(0); close(1); close(2); set_env("ERL_CONSOLE_MODE", "detached"); - set_env(DLL_ENV, emu); + set_env(DLL_ENV, utf8emu); + + utf8argv[0] = utf8start_prog; + utf8argv = fnuttify_argv(utf8argv); + + len = MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, NULL, 0); + start_prog = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8start_prog, -1, start_prog, len); + + /* Convert utf8argv to multibyte argv */ + argv = malloc((argc+1) * sizeof(wchar_t*)); + for (i=0; i<argc; i++) { + len = MultiByteToWideChar(CP_UTF8, 0,utf8argv[i], -1, NULL, 0); + argv[i] = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8argv[i], -1, argv[i], len); + } + argv[argc] = NULL; - argv[0] = start_prog; - argv = fnuttify_argv(argv); #ifdef ARGS_HARDDEBUG { - char buffer[2048]; + wchar_t buffer[2048]; int i; - sprintf(buffer,"Start detached [%s]\n",start_prog); + wsprintfW(buffer,L"Start detached [%s]\n",start_prog); for(i=0;argv[i] != NULL;++i) { - strcat(buffer,"|"); - strcat(buffer,argv[i]); - strcat(buffer,"|\n"); + wcscat(buffer,L"|"); + wcscat(buffer,argv[i]); + wcscat(buffer,L"|\n"); } - MessageBox(NULL, buffer,"Start detached",MB_OK); + MessageBoxW(NULL, buffer, L"Start detached",MB_OK); } -#endif - result = spawnv(_P_DETACH, start_prog, argv); - free_fnuttified(argv); +#endif + result = _wspawnv(_P_DETACH, start_prog, argv); + free_fnuttified(utf8argv); + free(start_prog); + if (result == -1) { #ifdef ARGS_HARDDEBUG - MessageBox(NULL, "_spawnv failed","Start detached",MB_OK); + MessageBox(NULL, "_wspawnv failed","Start detached",MB_OK); #endif return 1; } SetPriorityClass((HANDLE) result, GetPriorityClass(GetCurrentProcess())); } else { - int argc = 0; + wchar_t *emu=NULL; #ifdef LOAD_BEAM_DYNAMICALLY - HMODULE beam_module = load_win_beam_dll(emu); + HMODULE beam_module; + len = MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, NULL, 0); + emu = malloc(len*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, utf8emu, -1, emu, len); +#ifdef ARGS_HARDDEBUG + { + char sbuf[2048] = ""; + int i; + strcat(sbuf,utf8emu); + strcat(sbuf,":"); + for (i = 0; i < argc; ++i) { + strcat(sbuf,"|"); + strcat(sbuf, utf8argv[i]); + strcat(sbuf,"| "); + } + MessageBox(NULL, sbuf, "erl_start args", MB_OK|MB_ICONERROR); + } +#endif + beam_module = load_win_beam_dll(emu); #endif /* @@ -254,9 +357,6 @@ start_emulator(char* emu, char *start_prog, char** argv, int start_detached) free_env_val(title); set_env("ERL_CONSOLE_MODE", console_mode); - while (argv[argc] != NULL) { - ++argc; - } if (keep_window) { atexit(do_keep_window); } @@ -266,17 +366,17 @@ start_emulator(char* emu, char *start_prog, char** argv, int start_detached) int i; for (i = 0; i < argc; ++i) { strcat(sbuf,"|"); - strcat(sbuf, argv[i]); + strcat(sbuf, utf8argv[i]); strcat(sbuf,"|\n"); } - MessageBox(NULL, sbuf, "erl", MB_OK); + MessageBox(NULL, sbuf, "erl_start", MB_OK); } #endif #ifdef LOAD_BEAM_DYNAMICALLY (*sys_primitive_init_p)(beam_module); - (*erl_start_p)(argc,argv); + (*erl_start_p)(argc,utf8argv); #else - erl_start(argc, argv); + erl_start(argc, utf8argv); #endif } return 0; |