diff options
Diffstat (limited to 'erts/etc/common/erlexec.c')
-rw-r--r-- | erts/etc/common/erlexec.c | 274 |
1 files changed, 143 insertions, 131 deletions
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 709c6f02d1..08e326b33b 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-2017. 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% */ @@ -22,19 +23,15 @@ * additions required for Windows NT. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "etc_common.h" -#include "sys.h" #include "erl_driver.h" -#include <stdlib.h> -#include <stdarg.h> #include "erl_misc_utils.h" #ifdef __WIN32__ # include "erl_version.h" # include "init_file.h" +# include <Shlobj.h> #endif #define NO 0 @@ -64,6 +61,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 +70,8 @@ static const char plusM_au_allocs[]= { 'R', /* driver_alloc */ 'S', /* sl_alloc */ 'T', /* temp_alloc */ + 'X', /* exec_alloc */ + 'Z', /* test_alloc */ '\0' }; @@ -119,6 +119,8 @@ static char *plusM_other_switches[] = { "Ym", "Ytp", "Ytt", + "Iscs", + "Xscs", NULL }; @@ -128,12 +130,15 @@ static char *pluss_val_switches[] = { "bwt", "cl", "ct", + "ecio", "fwi", "tbt", "wct", "wt", "ws", "ss", + "ssdcpu", + "ssdio", "pp", "ub", NULL @@ -142,6 +147,11 @@ static char *pluss_val_switches[] = { static char *plush_val_switches[] = { "ms", "mbs", + "pds", + "max", + "maxk", + "maxel", + "mqd", "", NULL }; @@ -155,6 +165,8 @@ static char *plusr_val_switches[] = { /* +z arguments with values */ static char *plusz_val_switches[] = { "dbbl", + "dntgc", + "ebwt", NULL }; @@ -168,19 +180,9 @@ static char *plusz_val_switches[] = { #endif #define SMP_SUFFIX ".smp" -#define DEBUG_SUFFIX ".debug" -#define EMU_TYPE_SUFFIX_LENGTH strlen(DEBUG_SUFFIX) - -/* - * Define flags for different memory architectures. - */ -#define EMU_TYPE_SMP 0x0001 - -#ifdef __WIN32__ -#define EMU_TYPE_DEBUG 0x0004 -#endif void usage(const char *switchname); +static void usage_format(char *format, ...); void start_epmd(char *epmd); void error(char* format, ...); @@ -188,9 +190,7 @@ void error(char* format, ...); * Local functions. */ -#if !defined(ERTS_HAVE_SMP_EMU) -static void usage_notsup(const char *switchname); -#endif +static void usage_notsup(const char *switchname, const char *alt); static char **build_args_from_env(char *env_var); static char **build_args_from_string(char *env_var); static void initial_argv_massage(int *argc, char ***argv); @@ -204,7 +204,7 @@ static void *erealloc(void *p, size_t size); static void efree(void *p); static char* strsave(char* string); static int is_one_of_strings(char *str, char *strs[]); -static char *write_str(char *to, char *from); +static char *write_str(char *to, const char *from); static void get_home(void); static void add_epmd_port(void); #ifdef __WIN32__ @@ -238,9 +238,8 @@ static int verbose = 0; /* If non-zero, print some extra information. */ static int start_detached = 0; /* If non-zero, the emulator should be * started detached (in the background). */ -static int emu_type = 0; /* If non-zero, start beam.ARCH or beam.ARCH.exe - * instead of beam or beam.exe, where ARCH is defined by flags. */ -static int emu_type_passed = 0; /* Types explicitly set */ +static int start_smp_emu = 1; /* Start the smp emulator. */ +static const char* emu_type = 0; /* Type of emulator (lcnt, valgrind, etc) */ #ifdef __WIN32__ static char *start_emulator_program = NULL; /* For detachec mode - @@ -335,11 +334,11 @@ free_env_val(char *value) } /* - * Add the architecture suffix to the program name if needed, - * except on Windows, where we insert it just before ".DLL". + * Add the type and architecture suffix to the program name if needed. + * On Windows, we insert it just before ".DLL". */ static char* -add_extra_suffixes(char *prog, int type) +add_extra_suffixes(char *prog) { char *res; char *p; @@ -349,16 +348,10 @@ add_extra_suffixes(char *prog, int type) int dll = 0; #endif - if (!type) { - return prog; - } - len = strlen(prog); - /* Worst-case allocation */ - p = emalloc(len + - EMU_TYPE_SUFFIX_LENGTH + - + 1); + /* Allocate enough extra space for suffixes */ + p = emalloc(len + 100); res = p; p = write_str(p, prog); @@ -375,13 +368,11 @@ add_extra_suffixes(char *prog, int type) } #endif -#ifdef __WIN32__ - if (type & EMU_TYPE_DEBUG) { - p = write_str(p, DEBUG_SUFFIX); - type &= ~(EMU_TYPE_DEBUG); + if (emu_type) { + p = write_str(p, "."); + p = write_str(p, emu_type); } -#endif - if (type == EMU_TYPE_SMP) { + if (start_smp_emu) { p = write_str(p, SMP_SUFFIX); } #ifdef __WIN32__ @@ -470,15 +461,9 @@ int main(int argc, char **argv) * Construct the path of the executable. */ cpuinfo = erts_cpu_info_create(); - /* '-smp auto' is default */ -#ifdef ERTS_HAVE_SMP_EMU - if (erts_get_cpu_configured(cpuinfo) > 1) - emu_type |= EMU_TYPE_SMP; -#endif #if defined(__WIN32__) && defined(WIN32_ALWAYS_DEBUG) - emu_type_passed |= EMU_TYPE_DEBUG; - emu_type |= EMU_TYPE_DEBUG; + emu_type = "debug"; #endif /* We need to do this before the ordinary processing. */ @@ -503,54 +488,32 @@ int main(int argc, char **argv) if (strcmp(argv[i+1], "auto") == 0) { i++; - smp_auto: - emu_type_passed |= EMU_TYPE_SMP; -#ifdef ERTS_HAVE_SMP_EMU - if (erts_get_cpu_configured(cpuinfo) > 1) - emu_type |= EMU_TYPE_SMP; - else -#endif - emu_type &= ~EMU_TYPE_SMP; - } - else if (strcmp(argv[i+1], "enable") == 0) { + } else if (strcmp(argv[i+1], "enable") == 0) { i++; smp_enable: - emu_type_passed |= EMU_TYPE_SMP; -#ifdef ERTS_HAVE_SMP_EMU - emu_type |= EMU_TYPE_SMP; -#else - usage_notsup("-smp enable"); -#endif - } - else if (strcmp(argv[i+1], "disable") == 0) { + ; + } else if (strcmp(argv[i+1], "disable") == 0) { i++; smp_disable: - emu_type_passed |= EMU_TYPE_SMP; - emu_type &= ~EMU_TYPE_SMP; - } - else { + usage_notsup("-smp disable", " Use \"+S 1\" instead."); + } else { smp: - - emu_type_passed |= EMU_TYPE_SMP; -#ifdef ERTS_HAVE_SMP_EMU - emu_type |= EMU_TYPE_SMP; -#else - usage_notsup("-smp"); -#endif + ; } } else if (strcmp(argv[i], "-smpenable") == 0) { goto smp_enable; } else if (strcmp(argv[i], "-smpauto") == 0) { - goto smp_auto; + ; } else if (strcmp(argv[i], "-smpdisable") == 0) { goto smp_disable; -#ifdef __WIN32__ - } else if (strcmp(argv[i], "-debug") == 0) { - emu_type_passed |= EMU_TYPE_DEBUG; - emu_type |= EMU_TYPE_DEBUG; -#endif } else if (strcmp(argv[i], "-extra") == 0) { break; + } else if (strcmp(argv[i], "-emu_type") == 0) { + if (i + 1 >= argc) { + usage(argv[i]); + } + emu_type = argv[i+1]; + i++; } } i++; @@ -563,13 +526,17 @@ int main(int argc, char **argv) if (strcmp(malloc_lib, "libc") != 0) usage("+MYm"); } - emu = add_extra_suffixes(emu, emu_type); + emu = add_extra_suffixes(emu); emu_name = strsave(emu); erts_snprintf(tmpStr, sizeof(tmpStr), "%s" DIRSEP "%s" BINARY_EXT, bindir, emu); emu = strsave(tmpStr); - add_Eargs(emu); /* Will be argv[0] -- necessary! */ - + s = get_env("ESCRIPT_NAME"); + if(s) { + add_Eargs(s); /* argv[0] = scriptname*/ + } else { + add_Eargs(emu); /* argv[0] = erl or cerl */ + } /* * Add the bindir to the path (unless it is there already). */ @@ -713,7 +680,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 */ @@ -781,6 +748,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]); @@ -806,6 +791,7 @@ int main(int argc, char **argv) case 'a': case 'A': case 'b': + case 'C': case 'e': case 'i': case 'n': @@ -825,12 +811,33 @@ int main(int argc, char **argv) add_Eargs(argv[i+1]); i++; break; + case 'I': + if (argv[i][2] == 'O' && (argv[i][3] == 't' || argv[i][3] == 'p')) { + if (argv[i][4] != '\0') + goto the_default; + argv[i][0] = '-'; + add_Eargs(argv[i]); + add_Eargs(argv[i+1]); + i++; + break; + } + if (argv[i][2] == 'O' && argv[i][3] == 'P' && + (argv[i][4] == 't' || argv[i][4] == 'p')) { + if (argv[i][5] != '\0') + goto the_default; + argv[i][0] = '-'; + add_Eargs(argv[i]); + add_Eargs(argv[i+1]); + i++; + break; + } + usage(argv[i]); + break; case 'S': if (argv[i][2] == 'P') { if (argv[i][3] != '\0') goto the_default; } -#ifdef ERTS_DIRTY_SCHEDULERS else if (argv[i][2] == 'D') { char* type = argv[i]+3; if (strncmp(type, "cpu", 3) != 0 && @@ -842,7 +849,6 @@ int main(int argc, char **argv) (argv[i][3] == 'i' && argv[i][5] != '\0')) goto the_default; } -#endif else if (argv[i][2] != '\0') goto the_default; if (i+1 >= argc) @@ -879,6 +885,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 (strcmp(argv[i+1], "true") == 0 + || 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++) @@ -999,7 +1018,7 @@ int main(int argc, char **argv) start_epmd(epmd_prog); #if (! defined(__WIN32__)) && defined(DEBUG) - if (start_detached) { + if (start_detached && get_env("ERL_CONSOLE_MODE")) { /* Start the emulator within an xterm. * Move up all arguments and insert * "xterm -e " first. @@ -1123,7 +1142,11 @@ int main(int argc, char **argv) { execv(emu, Eargsp); } - error("Error %d executing \'%s\'.", errno, emu); + if (errno == ENOENT) { + error("The emulator \'%s\' does not exist.", emu); + } else { + error("Error %d executing \'%s\'.", errno, emu); + } return 1; #endif } @@ -1138,25 +1161,16 @@ usage_aux(void) #ifdef __WIN32__ "[-start_erl [datafile]] " #endif - "[-smp " -#ifdef ERTS_HAVE_SMP_EMU - "[enable|" -#endif - "auto|disable" -#ifdef ERTS_HAVE_SMP_EMU - "]" -#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] " "[+SP PERCENTAGE_SCHEDULERS:PERCENTAGE_SCHEDULERS_ONLINE] " "[+T LEVEL] [+V] [+v] " - "[+W<i|w>] [+z MISC_OPTION] [args ...]\n"); + "[+W<i|w|e>] [+z MISC_OPTION] [args ...]\n"); exit(1); } @@ -1167,14 +1181,12 @@ usage(const char *switchname) usage_aux(); } -#if !defined(ERTS_HAVE_SMP_EMU) static void -usage_notsup(const char *switchname) +usage_notsup(const char *switchname, const char *alt) { - fprintf(stderr, "Argument \'%s\' not supported.\n", switchname); + fprintf(stderr, "Argument \'%s\' not supported.%s\n", switchname, alt); usage_aux(); } -#endif static void usage_format(char *format, ...) @@ -1323,7 +1335,7 @@ is_one_of_strings(char *str, char *strs[]) return 0; } -static char *write_str(char *to, char *from) +static char *write_str(char *to, const char *from) { while (*from) *(to++) = *(from++); @@ -1520,17 +1532,16 @@ static void get_parameters(int argc, char** argv) static void get_home(void) { - int len; - char tmpstr[MAX_PATH+1]; + wchar_t *profile; char* homedrive; char* homepath; homedrive = get_env("HOMEDRIVE"); homepath = get_env("HOMEPATH"); if (!homedrive || !homepath) { - if (len = GetWindowsDirectory(tmpstr,MAX_PATH)) { - home = emalloc(len+1); - strcpy(home,tmpstr); + if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, NULL, &profile) == S_OK) { + home = utf16_to_utf8(profile); + /* CoTaskMemFree(profile); */ } else error("HOMEDRIVE or HOMEPATH is not set and GetWindowsDir failed"); } else { @@ -1850,6 +1861,7 @@ read_args_file(char *filename) #undef SAVE_CHAR } + typedef struct { char **argv; int argc; @@ -2173,18 +2185,18 @@ static WCHAR *utf8_to_utf16(unsigned char *bytes) res = target = emalloc((num + 1) * sizeof(WCHAR)); while (*bytes) { if (((*bytes) & ((unsigned char) 0x80)) == 0) { - unipoint = (Uint) *bytes; + unipoint = (unsigned int) *bytes; ++bytes; } else if (((*bytes) & ((unsigned char) 0xE0)) == 0xC0) { unipoint = - (((Uint) ((*bytes) & ((unsigned char) 0x1F))) << 6) | - ((Uint) (bytes[1] & ((unsigned char) 0x3F))); + (((unsigned int) ((*bytes) & ((unsigned char) 0x1F))) << 6) | + ((unsigned int) (bytes[1] & ((unsigned char) 0x3F))); bytes += 2; } else if (((*bytes) & ((unsigned char) 0xF0)) == 0xE0) { unipoint = - (((Uint) ((*bytes) & ((unsigned char) 0xF))) << 12) | - (((Uint) (bytes[1] & ((unsigned char) 0x3F))) << 6) | - ((Uint) (bytes[2] & ((unsigned char) 0x3F))); + (((unsigned int) ((*bytes) & ((unsigned char) 0xF))) << 12) | + (((unsigned int) (bytes[1] & ((unsigned char) 0x3F))) << 6) | + ((unsigned int) (bytes[2] & ((unsigned char) 0x3F))); if (unipoint > 0xFFFF) { unipoint = (unsigned int) '?'; } @@ -2203,7 +2215,7 @@ static WCHAR *utf8_to_utf16(unsigned char *bytes) static int put_utf8(WCHAR ch, unsigned char *target, int sz, int *pos) { - Uint x = (Uint) ch; + unsigned int x = (unsigned int) ch; if (x < 0x80) { if (*pos >= sz) { return -1; |