aboutsummaryrefslogtreecommitdiffstats
path: root/erts/etc/common/escript.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/etc/common/escript.c')
-rw-r--r--erts/etc/common/escript.c110
1 files changed, 75 insertions, 35 deletions
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 7fd02ed436..7f0af77a4c 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2007-2013. All Rights Reserved.
+ * Copyright Ericsson AB 2007-2017. 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.
@@ -71,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);
@@ -79,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
/*
@@ -154,6 +155,29 @@ free_env_val(char *value)
efree(value);
#endif
}
+
+static void
+set_env(char *key, char *value)
+{
+#ifdef __WIN32__
+ WCHAR wkey[MAXPATHLEN];
+ WCHAR wvalue[MAXPATHLEN];
+ MultiByteToWideChar(CP_UTF8, 0, key, -1, wkey, MAXPATHLEN);
+ MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, MAXPATHLEN);
+ if (!SetEnvironmentVariableW(wkey, wvalue))
+ error("SetEnvironmentVariable(\"%s\", \"%s\") failed!", key, value);
+#else
+ size_t size = strlen(key) + 1 + strlen(value) + 1;
+ char *str = emalloc(size);
+ sprintf(str, "%s=%s", key, value);
+ if (putenv(str) != 0)
+ error("putenv(\"%s\") failed!", str);
+#ifdef HAVE_COPYING_PUTENV
+ efree(str);
+#endif
+#endif
+}
+
/*
* Find absolute path to this program
*/
@@ -409,7 +433,7 @@ main(int argc, char** argv)
char* emulator;
char* env;
char* basename;
- char* absname;
+ char* def_emu_lookup_path;
char scriptname[PMAX];
char** last_opt;
char** first_opt;
@@ -418,23 +442,15 @@ main(int argc, char** argv)
int i;
int len;
/* Convert argv to utf8 */
- argv = malloc((argc+1) * sizeof(char*));
+ 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] = malloc(len*sizeof(char));
+ 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) {
- emulator = get_default_emulator(argv[0]);
- }
-
- if (strlen(emulator) >= PMAX)
- error("Value of environment variable ESCRIPT_EMULATOR is too large");
-
/*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
@@ -445,21 +461,10 @@ main(int argc, char** argv)
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
- push_words(emulator);
eargc_base = eargc;
eargv = eargv + eargv_size/2;
eargc = 0;
- free_env_val(env);
-
- /*
- * Push initial arguments.
- */
-
- PUSH("+B");
- PUSH2("-boot", "start_clean");
- PUSH("-noshell");
-
/* Determine basename of the executable */
for (basename = argv[0]+strlen(argv[0]);
basename > argv[0] && !(IS_DIRSEP(basename[-1]));
@@ -475,6 +480,7 @@ main(int argc, char** argv)
#else
if (strcmp(basename, "escript") == 0) {
#endif
+ def_emu_lookup_path = argv[0];
/*
* Locate all options before the script name.
*/
@@ -493,22 +499,40 @@ main(int argc, char** argv)
argc--;
argv++;
} else {
+ char *absname = find_prog(argv[0]);
#ifdef __WIN32__
- int len;
-#endif
- absname = find_prog(argv[0]);
-#ifdef __WIN32__
- len = strlen(absname);
+ int len = strlen(absname);
if (len >= 4 && _stricmp(absname+len-4, ".exe") == 0) {
absname[len-4] = '\0';
}
#endif
-
erts_snprintf(scriptname, sizeof(scriptname), "%s.escript",
absname);
- efree(absname);
+ efree(absname);
+ def_emu_lookup_path = scriptname;
}
+ /* Determine path to emulator */
+ emulator = env = get_env("ESCRIPT_EMULATOR");
+
+ if (emulator == NULL) {
+ emulator = get_default_emulator(def_emu_lookup_path);
+ }
+
+ if (strlen(emulator) >= PMAX)
+ error("Value of environment variable ESCRIPT_EMULATOR is too large");
+
+ /*
+ * Push initial arguments.
+ */
+
+ PUSH(emulator);
+ free_env_val(env);
+
+ PUSH("+B");
+ PUSH2("-boot", "start_clean");
+ PUSH("-noshell");
+
/*
* Read options from the %%! row in the script and add them as args
*/
@@ -545,7 +569,12 @@ main(int argc, char** argv)
while (--eargc_base >= 0) {
UNSHIFT(eargv_base[eargc_base]);
}
-
+
+ /*
+ * Add scriptname to env
+ */
+ set_env("ESCRIPT_NAME", scriptname);
+
/*
* Invoke Erlang with the collected options.
*/
@@ -594,7 +623,7 @@ wchar_t *make_commandline(char **argv)
buff = (wchar_t *) emalloc(siz*sizeof(wchar_t));
} else if (siz < num) {
siz = num;
- buff = (wchar_t *) realloc(buff,siz*sizeof(wchar_t));
+ buff = (wchar_t *) erealloc(buff,siz*sizeof(wchar_t));
}
p = buff;
num=0;
@@ -694,15 +723,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)
{