aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorHåkan Mattsson <[email protected]>2016-12-22 09:57:21 +0100
committerHåkan Mattsson <[email protected]>2016-12-22 14:43:15 +0100
commit1d8dbc7123245a536df6bb09e891d3a075fb70ed (patch)
treeb867ffae19324c06c0578b6c5bfef05158074198 /erts
parent691a6d0f68c5a2ef64315dd4d7759aa7aa8e2e99 (diff)
downloadotp-1d8dbc7123245a536df6bb09e891d3a075fb70ed.tar.gz
otp-1d8dbc7123245a536df6bb09e891d3a075fb70ed.tar.bz2
otp-1d8dbc7123245a536df6bb09e891d3a075fb70ed.zip
escript: Handle symbolic link to a standalone escript
The code has been rearranged to make use of the actual path "get_default_emulator(scriptname)" to the escript instead of the given one "get_default_emulator(argv[0])". TL;DR Assume a source system with some Erlang applications (app1, app2 etc.) and an escript called "mytool". When generating a standalone target system (with reltool for example), the escript(s) are located in the same top bin directory as "erl". See mytool* below. In such a system the original "mytool" escript is given the extension ".escript" and the file with the same name as the original escript is a copy of the "escript" executable. One purpose of the escript executable is to determine which "erl" to use to start the system. In a standalone system we want it to find the runtime system bundled with the escript(s). This is done by analyzing the path in order to find the "erl" located in the same directory as the escript. A dilemma here is that we do not want to put the top bin directory in the execution path (PATH env var) as we then would cause other Erlang applications to make use of our bundled run-time system. One way of solving this is to choose some suitable bin directory in the execution path (such as /user/local/bin) and put a symbolic link there to our mytool executable. Unfortunately this did not work as the escript executable (in this case called mytool) would try to find "erl" in /usr/local/bin and when it did not find such a file it resorted to use the command "erl" which would find some (unwanted) "erl" in the execution path. My fix solves that problem. ├── bin/ │   ├── erl* (dyn_erl.c) │   ├── mytool* (escript.c) │   ├── mytool.escript* (original mytool escript) │   └── start_clean.boot ├── erts-vsn/ │   └── bin/ │   ├── beam* │   ├── beam.smp* │   ├── erl* │   ├── erl_child_setup* │   ├── erlexec* │   └── inet_gethost* └── lib/ ├── app1-vsn ├── app2-vsn └── ...
Diffstat (limited to 'erts')
-rw-r--r--erts/etc/common/escript.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 71c278881c..4134a3ff36 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -428,14 +428,6 @@ main(int argc, char** argv)
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
@@ -446,21 +438,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]));
@@ -510,6 +491,27 @@ main(int argc, char** argv)
efree(absname);
}
+ /* Determine path to emulator */
+ emulator = env = get_env("ESCRIPT_EMULATOR");
+
+ if (emulator == NULL) {
+ emulator = get_default_emulator(scriptname);
+ }
+
+ if (strlen(emulator) >= PMAX)
+ error("Value of environment variable ESCRIPT_EMULATOR is too large");
+
+ /*
+ * Push initial arguments.
+ */
+
+ push_words(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
*/