File 0400-erlexec-Fix-argument-separation-when-mixing-env-flag.patch of Package erlang

From 889cc75f40c74ee574b0943524df4f786371efaf Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Mon, 3 Jun 2019 15:10:06 +0200
Subject: [PATCH] erlexec: Fix argument separation when mixing env flags

Example:
    export ERL_AFLAGS=-test
    erl dummy_param

In the above example, the dummy_param would be interpreted
as an argument to -test, and not as a separate argument as
it should.
---
 erts/etc/common/erlexec.c   | 15 +++++++++++----
 erts/test/erlexec_SUITE.erl | 32 ++++++++++++++++++++++++--------
 2 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index c793243c13..477a501876 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -1690,9 +1690,9 @@ static char **build_args_from_string(char *string)
     for(;;) {
 	switch (state) {
 	case Start:
-	    if (!*p) 
+	    if (!*p)
 		goto done;
-	    if (argc >= alloced - 1) { /* Make room for extra NULL */
+	    if (argc >= alloced - 2) { /* Make room for extra NULL and "--" */
 		argv = erealloc(argv, (alloced += 10) * sizeof(char *));
 	    }
 	    cur_s = argc + argv;
@@ -1781,11 +1781,14 @@ static char **build_args_from_string(char *string)
 	}
     }
 done:
-    argv[argc] = NULL; /* Sure to be large enough */
     if (!argc) {
 	efree(argv);
 	return NULL;
     }
+    argv[argc++] = "--"; /* Add a -- separator in order
+                            for different from different environments
+                            to effect each other */
+    argv[argc++] = NULL; /* Sure to be large enough */
     return argv;
 #undef ENSURE
 }
@@ -2036,11 +2039,13 @@ initial_argv_massage(int *argc, char ***argv)
     argv_buf ab = {0}, xab = {0};
     int ix, vix, ac;
     char **av;
+    char *sep = "--";
     struct {
 	int argc;
 	char **argv;
     } avv[] = {{INT_MAX, NULL}, {INT_MAX, NULL}, {INT_MAX, NULL},
-	       {INT_MAX, NULL}, {INT_MAX, NULL}, {INT_MAX, NULL}};
+	       {INT_MAX, NULL}, {INT_MAX, NULL},
+               {INT_MAX, NULL}, {INT_MAX, NULL}};
     /*
      * The environment flag containing OTP release is intentionally
      * undocumented and intended for OTP internal use only.
@@ -2060,6 +2065,8 @@ initial_argv_massage(int *argc, char ***argv)
     if (*argc > 1) {
 	avv[vix].argc = *argc - 1;
 	avv[vix++].argv = &(*argv)[1];
+        avv[vix].argc = 1;
+        avv[vix++].argv = &sep;
     }
 
     av = build_args_from_env("ERL_FLAGS");
diff --git a/erts/test/erlexec_SUITE.erl b/erts/test/erlexec_SUITE.erl
index 602dc5ce2e..952e6da4dc 100644
--- a/erts/test/erlexec_SUITE.erl
+++ b/erts/test/erlexec_SUITE.erl
@@ -30,7 +30,7 @@
 -export([all/0, suite/0, init_per_testcase/2, end_per_testcase/2]).
 
 -export([args_file/1, evil_args_file/1, env/1, args_file_env/1,
-         otp_7461/1, otp_7461_remote/1, otp_8209/1,
+         otp_7461/1, otp_7461_remote/1, argument_separation/1,
          zdbbl_dist_buf_busy_limit/1]).
 
 -include_lib("common_test/include/ct.hrl").
@@ -51,21 +51,28 @@ suite() ->
 
 all() -> 
     [args_file, evil_args_file, env, args_file_env,
-     otp_7461, otp_8209, zdbbl_dist_buf_busy_limit].
+     otp_7461, argument_separation, zdbbl_dist_buf_busy_limit].
 
 %% Test that plain first argument does not
-%% destroy -home switch [OTP-8209]
-otp_8209(Config) when is_list(Config) ->
+%% destroy -home switch [OTP-8209] or interact with environments
+argument_separation(Config) when is_list(Config) ->
     {ok,[[PName]]} = init:get_argument(progname),
     SNameS = "erlexec_test_01",
     SName = list_to_atom(SNameS++"@"++
 			 hd(tl(string:lexemes(atom_to_list(node()),"@")))),
-    Cmd = PName ++ " dummy_param -sname "++SNameS++" -setcookie "++
-	atom_to_list(erlang:get_cookie()),
-    open_port({spawn,Cmd},[]),
+    Cmd = PName ++ " cmd_param -sname "++SNameS++" -setcookie "++
+	atom_to_list(erlang:get_cookie()) ++ " -cmd_test",
+    open_port({spawn,Cmd},[{env,[{"ERL_AFLAGS","-atest"},
+                                 {"ERL_FLAGS","env_param -test"},
+                                 {"ERL_ZFLAGS","zenv_param"}]}]),
     pong = loop_ping(SName,40),
+    ct:log("emu_args: ~p",[rpc:call(SName,erlang,system_info,[emu_args])]),
     {ok,[[_]]} = rpc:call(SName,init,get_argument,[home]),
-    ["dummy_param"] = rpc:call(SName,init,get_plain_arguments,[]),
+    {ok,[[]]} = rpc:call(SName,init,get_argument,[atest]),
+    {ok,[[]]} = rpc:call(SName,init,get_argument,[cmd_test]),
+    {ok,[[]]} = rpc:call(SName,init,get_argument,[test]),
+    error = rpc:call(SName,init,get_argument,[unkown]),
+    ["cmd_param","env_param","zenv_param"] = rpc:call(SName,init,get_plain_arguments,[]),
     ok = cleanup_nodes(),
     ok.
 
@@ -85,6 +92,7 @@ cleanup_node(SNameS,N) ->
     end.
 
 loop_ping(_,0) ->
+    flush(),
     pang;
 loop_ping(Node,N) ->
     case net_adm:ping(Node) of
@@ -98,6 +106,14 @@ loop_ping(Node,N) ->
 	    pong
     end.
 
+flush() ->
+    receive M ->
+            ct:pal("~p",[M]),
+            flush()
+    after 10 ->
+            ok
+    end.
+
 args_file(Config) when is_list(Config) ->
     AFN1 = privfile("1", Config),
     AFN2 = privfile("2", Config),
-- 
2.16.4

openSUSE Build Service is sponsored by