File 2116-escript-Handle-symbolic-link-to-a-standalone-escript.patch of Package erlang

From 1d8dbc7123245a536df6bb09e891d3a075fb70ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A5kan=20Mattsson?= <hm@tail-f.com>
Date: Thu, 22 Dec 2016 09:57:21 +0100
Subject: [PATCH] escript: Handle symbolic link to a standalone escript
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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
    └── ...
---
 erts/etc/common/escript.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 71c278881..4134a3ff3 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
      */
-- 
2.13.0

openSUSE Build Service is sponsored by