From e645b6b4a5d01406416aa40a0fb822e8993c45bd Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Fri, 15 Mar 2019 15:15:20 +0100
Subject: Fix initialization of erl_call

Previously erl_call relied on the implicit initialization made
of the ei-lib if no explicit initialization had been done. This
implicit initialization was utterly broken and was removed in
erl_interface-3.11 (OTP 21.3) since it has been documented for
a very long time that an explicit initialization is required.
---
 lib/erl_interface/src/prog/erl_call.c | 54 ++---------------------------------
 1 file changed, 2 insertions(+), 52 deletions(-)

diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index 52ad6885e8..ab91157035 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -88,10 +88,6 @@
 #include "ei_resolve.h"
 #include "erl_start.h"		/* FIXME remove dependency */
 
-#ifdef __WIN32__
-static void initWinSock(void);
-#endif
-
 /*
  * Some nice global variables
  * (I don't think "nice" is the right word actually... -gordon)
@@ -157,6 +153,8 @@ int erl_call(int argc, char **argv)
     char* progname = argv[0];
     ei_cnode ec;
 
+    ei_init();
+
     /* Get the command line options */
     while (i < argc) {
 	if (argv[i][0] != '-') {
@@ -317,14 +315,6 @@ int erl_call(int argc, char **argv)
       struct in_addr h_ipadr;
       char* ct;
 
-#ifdef __WIN32__
-      /*
-       * FIXME Extremly ugly, but needed to get ei_gethostbyname() below
-       * to work.
-       */
-      initWinSock();
-#endif
-
       /* gethostname requires len to be max(hostname) + 1 */
       if (gethostname(h_hostname, EI_MAXHOSTNAMELEN+1) < 0) {
 	  fprintf(stderr,"erl_call: failed to get host name: %d\n", errno);
@@ -857,46 +847,6 @@ static void usage(const char *progname) {
   exit(0);
 }
 
-
-/***************************************************************************
- *
- *  OS specific functions
- *
- ***************************************************************************/
-
-#ifdef __WIN32__
-/*
- * FIXME This should not be here.  This is a quick fix to make erl_call
- * work at all on Windows NT.
- */
-static void initWinSock(void)
-{
-    WORD wVersionRequested;  
-    WSADATA wsaData; 
-    int err; 
-    static int initialized;
-
-    wVersionRequested = MAKEWORD(1, 1); 
-    if (!initialized) {
-	initialized = 1;
-	err = WSAStartup(wVersionRequested, &wsaData); 
- 
-	if (err != 0) {
-	    fprintf(stderr,"erl_call: "
-		    "Can't initialize windows sockets: %d\n", err);
-	}
-  
-	if ( LOBYTE( wsaData.wVersion ) != 1 || 
-	    HIBYTE( wsaData.wVersion ) != 1 ) { 
-	    fprintf(stderr,"erl_call: This version of "
-		    "windows sockets not supported\n");
-	    WSACleanup(); 
-	}
-    }
-}
-#endif
-
-
 /***************************************************************************
  *
  *  Utility functions
-- 
cgit v1.2.3


From adf61f3cbf1a63d4408cc9cdf831b8935e129876 Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Mon, 18 Mar 2019 15:52:36 +0100
Subject: Fix timeout value when waiting for emulator start

---
 lib/erl_interface/src/prog/erl_start.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/erl_interface/src/prog/erl_start.c b/lib/erl_interface/src/prog/erl_start.c
index 670a5900c9..c766f4780e 100644
--- a/lib/erl_interface/src/prog/erl_start.c
+++ b/lib/erl_interface/src/prog/erl_start.c
@@ -657,7 +657,7 @@ static int wait_for_erlang(int sockd, int magic, struct timeval *timeout)
     gettimeofday(&now,NULL);
     to.tv_sec = stop_time.tv_sec - now.tv_sec;
     to.tv_usec = stop_time.tv_usec - now.tv_usec;
-    while ((to.tv_usec <= 0) && (to.tv_sec >= 0)) {
+    while ((to.tv_usec < 0) && (to.tv_sec > 0)) {
       to.tv_usec += 1000000;
       to.tv_sec--;
     }
-- 
cgit v1.2.3


From f85c6c84faf7108a2e08d3923c30efbf8cb24e0c Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Fri, 15 Mar 2019 15:30:30 +0100
Subject: Add new api functions to ei_fake_prog

These functions were added in erl_interface-3.11
---
 lib/erl_interface/src/prog/ei_fake_prog.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/lib/erl_interface/src/prog/ei_fake_prog.c b/lib/erl_interface/src/prog/ei_fake_prog.c
index c7a16dc7c4..158464b385 100644
--- a/lib/erl_interface/src/prog/ei_fake_prog.c
+++ b/lib/erl_interface/src/prog/ei_fake_prog.c
@@ -98,11 +98,18 @@ int main(void)
   EI_ULONGLONG ulonglongx = 0;
 #endif
   erlang_char_encoding enc;
+  ei_socket_callbacks cbs;
 
   intx = erl_errno;
 
+  ei_init();
+
+  ei_close_connection(intx);
+  
   ei_connect_init(&xec, charp, charp, creation);
+  ei_connect_init_ussi(&xec, charp, charp, creation, &cbs, sizeof(cbs), NULL);
   ei_connect_xinit (&xec, charp, charp, charp, thisipaddr, charp, creation);
+  ei_connect_xinit_ussi(&xec, charp, charp, charp, thisipaddr, charp, creation, &cbs, sizeof(cbs), NULL);
 
   ei_connect(&xec, charp);
   ei_xconnect (&xec, thisipaddr, charp);
@@ -121,6 +128,8 @@ int main(void)
   ei_publish(&xec, intx);
   ei_accept(&xec, intx, &conp);
   ei_unpublish(&xec);
+  ei_listen(&xec, intp, intx);
+  ei_xlisten(&xec, thisipaddr, intp, intx);
 
   ei_thisnodename(&xec);
   ei_thishostname(&xec);
@@ -187,7 +196,7 @@ int main(void)
   ei_decode_char(charp, intp, charp);
   ei_decode_string(charp, intp, charp);
   ei_decode_atom(charp, intp, charp);
-  ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_WHATEVER, &enc, &enc);
+  ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_UTF8, &enc, &enc);
   ei_decode_binary(charp, intp, (void *)0, longp);
   ei_decode_fun(charp, intp, &efun);
   free_fun(&efun);
-- 
cgit v1.2.3


From 543ca376a922c6dbe34e2207c4c512c5f6b5d624 Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Fri, 15 Mar 2019 16:47:38 +0100
Subject: Add smoke test for erl_call

---
 lib/erl_interface/test/Makefile           |  1 +
 lib/erl_interface/test/erl_call_SUITE.erl | 96 +++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+)
 create mode 100644 lib/erl_interface/test/erl_call_SUITE.erl

diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile
index 94f4b422d6..f8f2ef0156 100644
--- a/lib/erl_interface/test/Makefile
+++ b/lib/erl_interface/test/Makefile
@@ -33,6 +33,7 @@ MODULES= \
 	ei_format_SUITE \
 	ei_print_SUITE \
 	ei_tmo_SUITE \
+	erl_call_SUITE \
 	erl_connect_SUITE \
 	erl_global_SUITE \
 	erl_eterm_SUITE \
diff --git a/lib/erl_interface/test/erl_call_SUITE.erl b/lib/erl_interface/test/erl_call_SUITE.erl
new file mode 100644
index 0000000000..9e2b2e4251
--- /dev/null
+++ b/lib/erl_interface/test/erl_call_SUITE.erl
@@ -0,0 +1,96 @@
+%%
+%% %CopyrightBegin%
+%% 
+%% Copyright Ericsson AB 2019. 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.
+%% You may obtain a copy of the License at
+%%
+%%     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%
+%%
+
+%%
+-module(erl_call_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+-export([all/0, smoke/1]).
+
+all() -> 
+    [smoke].
+
+smoke(Config) when is_list(Config) ->
+    ErlCall = find_erl_call(),
+    NameSwitch = case net_kernel:longnames() of
+                     true ->
+                         "-name";
+                     false ->
+                         "-sname"
+                 end,
+    Name = atom_to_list(?MODULE)
+        ++ "-"
+        ++ integer_to_list(erlang:system_time(microsecond)),
+
+    ArgsList = ["-s", "-a", "erlang node", NameSwitch, Name],
+    io:format("erl_call: \"~ts\"\n~nargs list: ~p~n", [ErlCall, ArgsList]),
+    CmdRes = get_smoke_port_res(open_port({spawn_executable, ErlCall},
+                                          [{args, ArgsList}, eof]), []),
+    io:format("CmdRes: ~p~n", [CmdRes]),
+
+    [_, Hostname] = string:lexemes(atom_to_list(node()), "@"),
+    NodeName = list_to_atom(Name ++ "@" ++ Hostname),
+    io:format("NodeName: ~p~n~n", [NodeName]),
+
+    pong = net_adm:ping(NodeName),
+    rpc:cast(NodeName, erlang, halt, []),
+    NodeName = list_to_atom(string:trim(CmdRes, both, "'")),
+    ok.
+
+%
+% Utility functions...
+%
+
+find_erl_call() ->
+    ErlCallName = case os:type() of
+                      {win32, _} -> "erl_call.exe";
+                      _ -> "erl_call"
+                  end,
+    LibDir = code:lib_dir(erl_interface),
+    InstalledErlCall = filename:join([LibDir, "bin", ErlCallName]),
+    TargetDir = erlang:system_info(system_architecture),
+    TargetErlCall = filename:join([LibDir, "bin", TargetDir, ErlCallName]),
+    
+    try
+        lists:foreach(fun (F) ->
+                              io:format("Checking: \"~ts\"~n", [F]),
+                              case file:read_file_info(F) of
+                                  {ok, _} ->
+                                      throw(F);
+                                  _ ->
+                                      ok
+                              end
+                      end,
+                      [InstalledErlCall, TargetErlCall]),
+        exit({missing, erl_call})
+    catch
+        throw:ErlCall ->
+            ErlCall
+    end.
+
+get_smoke_port_res(Port, Acc) when is_port(Port) ->
+    receive
+        {Port, {data, Data}} ->
+            get_smoke_port_res(Port, [Acc|Data]);
+        {Port, eof} ->
+            lists:flatten(Acc)
+    end.
+            
-- 
cgit v1.2.3