From ad5b84bd154e27d9e4db3af12b8b4326c564b2bf Mon Sep 17 00:00:00 2001 From: Vitaliy Batichko Date: Tue, 23 Nov 2010 17:08:01 +0200 Subject: Add char (~c) type parameters to ei_format --- lib/erl_interface/doc/src/ei.xml | 1 + lib/erl_interface/src/misc/ei_format.c | 9 +++++++++ lib/erl_interface/test/ei_format_SUITE.erl | 2 +- lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'lib/erl_interface') diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml index d7af7a1b67..be5d7ebef8 100644 --- a/lib/erl_interface/doc/src/ei.xml +++ b/lib/erl_interface/doc/src/ei.xml @@ -641,6 +641,7 @@ ei_x_encode_empty_list(&x);

 ~a - an atom, char*
+~c - a character, char
 ~s - a string, char*
 ~i - an integer, int
 ~l - a long integer, long int
diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c
index b35421d4b2..96203a0d15 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -47,6 +47,7 @@
  * array of unions.
  */
 union arg {
+  char c;
   char* s;
   long l;
   unsigned long u;
@@ -224,6 +225,7 @@ static int pquotedatom(const char** fmt, ei_x_buff* x)
  /* 
   * The format letters are:
   *   a  -  An atom
+  *   c  -  A character
   *   s  -  A string
   *   i  -  An integer
   *   l  -  A long integer
@@ -240,6 +242,10 @@ static int pformat(const char** fmt, union arg** args, ei_x_buff* x)
 	res = ei_x_encode_atom(x, (*args)->s);
 	(*args)++;
 	break;
+    case 'c':
+	res = ei_x_encode_char(x, (*args)->c);
+	(*args)++;
+	break;
     case 's':
 	res = ei_x_encode_string(x, (*args)->s);
 	(*args)++;
@@ -396,6 +402,9 @@ static int read_args(const char* fmt, va_list ap, union arg **argp)
 	  return -1;	/* Error, string not complete */
 	}
 	switch (*p++) {
+	case 'c':
+	  args[i++].c = (char) va_arg(ap, int);
+	  break;
 	case 'a': 
 	case 's':
 	  args[i++].s = va_arg(ap, char*);
diff --git a/lib/erl_interface/test/ei_format_SUITE.erl b/lib/erl_interface/test/ei_format_SUITE.erl
index cbe9fa52d7..6d44e0adf3 100644
--- a/lib/erl_interface/test/ei_format_SUITE.erl
+++ b/lib/erl_interface/test/ei_format_SUITE.erl
@@ -155,7 +155,7 @@ format_wo_ver(suite) -> [];
 format_wo_ver(Config) when is_list(Config) ->
     ?line P = runner:start(?format_wo_ver),
 
-    ?line {term, [-1, 2, {a, "b"}, {c, 10}]} = get_term(P),
+    ?line {term, [-1, 2, $c, {a, "b"}, {c, 10}]} = get_term(P),
 
     ?line runner:recv_eot(P),
     ok.
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
index ecdce402f5..a6eeb25abc 100644
--- a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
+++ b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
@@ -176,7 +176,7 @@ TESTCASE(format_wo_ver) {
     ei_x_buff x;
     
     ei_x_new (&x);
-    ei_x_format(&x, "[-1, +2, {~a,~s},{~a,~i}]", "a", "b", "c", 10);
+    ei_x_format(&x, "[-1, +2, ~c, {~a,~s},{~a,~i}]", 'c', "a", "b", "c", 10);
     send_bin_term(&x);
 
     free(x.buff);
-- 
cgit v1.2.3


From 95392e693e210189df82173c9bcd345b58b004fe Mon Sep 17 00:00:00 2001
From: Vitaliy Batichko 
Date: Tue, 23 Nov 2010 18:44:24 +0200
Subject: Add PID (~p) type parameters to ei_format

---
 lib/erl_interface/doc/src/ei.xml                   |  1 +
 lib/erl_interface/src/misc/ei_format.c             |  9 +++++++++
 lib/erl_interface/test/ei_connect_SUITE.erl        | 19 ++++++++++++++++++
 .../test/ei_connect_SUITE_data/ei_connect_test.c   | 23 +++++++++++++++++++++-
 4 files changed, 51 insertions(+), 1 deletion(-)

(limited to 'lib/erl_interface')

diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index be5d7ebef8..de4e4b4301 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -648,6 +648,7 @@ ei_x_encode_empty_list(&x);
 ~u - a unsigned long integer, unsigned long int
 ~f - a float, float
 ~d - a double float, double float
+~p - an Erlang PID, erlang_pid*
         

For instance, to encode a tuple with some stuff:

diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c
index 96203a0d15..dbd7a4479a 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -52,6 +52,7 @@ union arg {
   long l;
   unsigned long u;
   double d;
+  erlang_pid* pid;
 };
 
 static int eiformat(const char** s, union arg** args, ei_x_buff* x);
@@ -232,6 +233,7 @@ static int pquotedatom(const char** fmt, ei_x_buff* x)
   *   u  -  An unsigned long integer
   *   f  -  A float 
   *   d  -  A double float 
+  *   p  -  An Erlang PID
   */
 static int pformat(const char** fmt, union arg** args, ei_x_buff* x)
 {
@@ -267,6 +269,10 @@ static int pformat(const char** fmt, union arg** args, ei_x_buff* x)
 	res = ei_x_encode_double(x, (*args)->d);
 	(*args)++;
 	break;	
+    case 'p':
+	res = ei_x_encode_pid(x, (*args)->pid);
+	(*args)++;
+	break;
     default:
 	res = -1;
 	break;
@@ -424,6 +430,9 @@ static int read_args(const char* fmt, va_list ap, union arg **argp)
 	case 'd':
 	  args[i++].d = va_arg(ap, double);
 	  break;	
+	case 'p':
+	  args[i++].pid = va_arg(ap, erlang_pid*);
+	  break;
 	default:
 	  ei_free(args);	/* Invalid specifier */
 	  return -1;
diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl
index fe82a73ef9..3c72188e16 100644
--- a/lib/erl_interface/test/ei_connect_SUITE.erl
+++ b/lib/erl_interface/test/ei_connect_SUITE.erl
@@ -30,6 +30,7 @@
 
 	ei_send/1, 
 	ei_reg_send/1, 
+	ei_format_pid/1,
 	ei_rpc/1, 
 	rpc_test/1, 
 	ei_send_funs/1,
@@ -41,6 +42,7 @@
 
 all(suite) -> [ ei_send, 
 		ei_reg_send, 
+		ei_format_pid,
 		ei_rpc, 
 		ei_send_funs, 
 		ei_threaded_send,
@@ -67,6 +69,19 @@ ei_send(Config) when is_list(Config) ->
     ?line runner:recv_eot(P),
     ok.
 
+ei_format_pid(Config) when is_list(Config) ->
+    ?line S = self(),
+    ?line P = runner:start(?interpret),
+    ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+    ?line {ok,Fd} = ei_connect(P, node()),
+
+    ?line ok = ei_format_pid(P, Fd, S),
+    ?line receive S -> ok end,
+
+    ?line runner:send_eot(P),
+    ?line runner:recv_eot(P),
+    ok.
+
 ei_send_funs(Config) when is_list(Config) ->
     ?line P = runner:start(?interpret),
     ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
@@ -189,6 +204,10 @@ ei_send(P, Fd, To, Msg) ->
     send_command(P, ei_send, [Fd,To,Msg]),
     get_send_result(P).
 
+ei_format_pid(P, Fd, To) ->
+    send_command(P, ei_format_pid, [Fd, To]),
+    get_send_result(P).
+
 ei_send_funs(P, Fd, To, Msg) ->
     send_command(P, ei_send_funs, [Fd,To,Msg]),
     get_send_result(P).
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
index debd3e789b..8183ac9dd8 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
@@ -35,6 +35,7 @@
 static void cmd_ei_connect_init(char* buf, int len);
 static void cmd_ei_connect(char* buf, int len);
 static void cmd_ei_send(char* buf, int len);
+static void cmd_ei_format_pid(char* buf, int len);
 static void cmd_ei_send_funs(char* buf, int len);
 static void cmd_ei_reg_send(char* buf, int len);
 static void cmd_ei_rpc(char* buf, int len);
@@ -57,6 +58,7 @@ static struct {
     "ei_reg_send", 	     3, cmd_ei_reg_send,
     "ei_rpc",  		     4, cmd_ei_rpc,
     "ei_set_get_tracelevel", 1, cmd_ei_set_get_tracelevel,
+    "ei_format_pid",         2, cmd_ei_format_pid,
 };
 
 
@@ -111,7 +113,7 @@ static void cmd_ei_connect_init(char* buf, int len)
     ei_x_buff res;
     if (ei_decode_long(buf, &index, &l) < 0)
 	fail("expected int");
-    sprintf(b, "c%d", l);
+    sprintf(b, "c%ld", l);
     /* FIXME don't use internal and maybe use skip?! */
     ei_get_type_internal(buf, &index, &type, &size);
     if (ei_decode_atom(buf, &index, cookie) < 0)
@@ -183,6 +185,25 @@ static void cmd_ei_send(char* buf, int len)
     ei_x_free(&x);
 }
 
+static void cmd_ei_format_pid(char* buf, int len)
+{
+    int index = 0;
+    long fd;
+    erlang_pid pid;
+    ei_x_buff x;
+
+    if (ei_decode_long(buf, &index, &fd) < 0)
+	fail("expected long");
+    if (ei_decode_pid(buf, &index, &pid) < 0)
+	fail("expected pid (node)");
+    if (ei_x_new_with_version(&x) < 0)
+	fail("ei_x_new_with_version");
+    if (ei_x_format_wo_ver(&x, "~p", &pid) < 0)
+	fail("ei_x_format_wo_ver");
+    send_errno_result(ei_send(fd, &pid, x.buff, x.index));
+    ei_x_free(&x);
+}
+
 static void cmd_ei_send_funs(char* buf, int len)
 {
     int index = 0, n;
-- 
cgit v1.2.3


From 7992d6a6bfa0f460f8663c2d72d07b60755a4857 Mon Sep 17 00:00:00 2001
From: Vitaliy Batichko 
Date: Mon, 29 Nov 2010 20:42:28 +0200
Subject: Correct erl_global{register, unregister} functions

C node needs DFLAG_DIST_MONITOR flag set when connecting,
and support for processing monitoring start/end messages
received from counterpart, to make global registration
actually work.
---
 lib/erl_interface/include/ei.h                     |  29 ++-
 lib/erl_interface/src/connect/ei_connect.c         |   1 +
 lib/erl_interface/src/legacy/global_register.c     |  12 +-
 lib/erl_interface/src/legacy/global_unregister.c   |  12 +-
 lib/erl_interface/test/Makefile                    |   1 +
 lib/erl_interface/test/erl_global_SUITE.erl        | 125 ++++++++++
 .../test/erl_global_SUITE_data/Makefile.first      |  21 ++
 .../test/erl_global_SUITE_data/Makefile.src        |  41 ++++
 .../test/erl_global_SUITE_data/erl_global_test.c   | 263 +++++++++++++++++++++
 9 files changed, 486 insertions(+), 19 deletions(-)
 create mode 100644 lib/erl_interface/test/erl_global_SUITE.erl
 create mode 100644 lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
 create mode 100644 lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
 create mode 100644 lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c

(limited to 'lib/erl_interface')

diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index 466d84bb99..ae815b414a 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -80,21 +80,24 @@
 #define ERL_NO_TIMEOUT -1
 
 /* these are the control message types */
-#define ERL_LINK          1
-#define ERL_SEND          2
-#define ERL_EXIT          3
-#define ERL_UNLINK        4
-#define ERL_NODE_LINK     5
-#define ERL_REG_SEND      6
-#define ERL_GROUP_LEADER  7
-#define ERL_EXIT2         8
-#define ERL_PASS_THROUGH      'p'
+#define ERL_LINK           1
+#define ERL_SEND           2
+#define ERL_EXIT           3
+#define ERL_UNLINK         4
+#define ERL_NODE_LINK      5
+#define ERL_REG_SEND       6
+#define ERL_GROUP_LEADER   7
+#define ERL_EXIT2          8
+#define ERL_PASS_THROUGH  'p'
 
 /* new ones for tracing, from Kenneth */
-#define ERL_SEND_TT      12
-#define ERL_EXIT_TT      13
-#define ERL_REG_SEND_TT  16
-#define ERL_EXIT2_TT     18
+#define ERL_SEND_TT        12
+#define ERL_EXIT_TT        13
+#define ERL_REG_SEND_TT    16
+#define ERL_EXIT2_TT       18
+#define ERL_MONITOR_P      19
+#define ERL_DEMONITOR_P    20
+#define ERL_MONITOR_P_EXIT 21
 
 
 /* -------------------------------------------------------------------- */
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 99ccba0686..10824c8a5f 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -1329,6 +1329,7 @@ static int send_name_or_challenge(int fd, char *nodename,
     put8(s, 'n');
     put16be(s, version);
     put32be(s, (DFLAG_EXTENDED_REFERENCES
+		| DFLAG_DIST_MONITOR
 		| DFLAG_EXTENDED_PIDS_PORTS
 		| DFLAG_FUN_TAGS
 		| DFLAG_NEW_FUN_TAGS
diff --git a/lib/erl_interface/src/legacy/global_register.c b/lib/erl_interface/src/legacy/global_register.c
index 3a4de8b08e..f12eb6b448 100644
--- a/lib/erl_interface/src/legacy/global_register.c
+++ b/lib/erl_interface/src/legacy/global_register.c
@@ -31,7 +31,7 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
   int index = 0;
   erlang_pid self;
   erlang_msg msg;
-  int needlink, needatom;
+  int needlink, needatom, needmonitor;
   int arity;
   int version;
   int msglen;
@@ -65,7 +65,7 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
   if (ei_send_reg_encoded(fd,&self,"rex",buf,index)) return -1;
 
   /* get the reply: expect link and an atom, or just an atom */
-  needlink = needatom = 1;
+  needlink = needatom = needmonitor = 1;
   while (1) {
     /* get message */
     while (1) {
@@ -78,9 +78,15 @@ int erl_global_register(int fd, const char *name, ETERM *pid)
     case ERL_LINK:
       /* got link */
       if (!needlink) return -1;
-	needlink = 0;
+      needlink = 0;
       break;
       
+    case ERL_MONITOR_P-10:
+      /* got monitor */
+	if (!needmonitor) { return -1;}
+	needmonitor = 0;
+      break;
+
     case ERL_SEND:
       /* got message - does it contain our atom? */
       if (!needatom) return -1;
diff --git a/lib/erl_interface/src/legacy/global_unregister.c b/lib/erl_interface/src/legacy/global_unregister.c
index 514dbc3c68..97a1c2d03c 100644
--- a/lib/erl_interface/src/legacy/global_unregister.c
+++ b/lib/erl_interface/src/legacy/global_unregister.c
@@ -37,7 +37,7 @@ int erl_global_unregister(int fd, const char *name)
   erlang_msg msg;
   int i;
   int version,arity,msglen;
-  int needunlink, needatom;
+  int needunlink, needatom, needdemonitor;
 
   /* make a self pid */
   self->num = fd;
@@ -57,7 +57,7 @@ int erl_global_unregister(int fd, const char *name)
   if (ei_send_reg_encoded(fd,self,"rex",buf,index)) return -1;
 
   /* get the reply: expect unlink and an atom, or just an atom */
-  needunlink = needatom = 1;
+  needunlink = needatom = needdemonitor = 1;
   while (1) {
     /* get message */
     while (1) {
@@ -68,11 +68,17 @@ int erl_global_unregister(int fd, const char *name)
 
     switch (i) {
     case ERL_UNLINK:
-      /* got link */
+      /* got unlink */
       if (!needunlink) return -1;
       needunlink = 0;
       break;
 
+    case ERL_DEMONITOR_P-10:
+      /* got demonitor */
+      if (!needdemonitor) return -1;
+      needdemonitor = 0;
+      break;
+
     case ERL_SEND:
       /* got message - does it contain our atom? */
       if (!needatom) return -1;
diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile
index b7a1a4e4d8..07404fda4d 100644
--- a/lib/erl_interface/test/Makefile
+++ b/lib/erl_interface/test/Makefile
@@ -33,6 +33,7 @@ MODULES= \
 	ei_print_SUITE \
 	ei_tmo_SUITE \
 	erl_connect_SUITE \
+	erl_global_SUITE \
 	erl_eterm_SUITE \
 	erl_ext_SUITE \
 	erl_format_SUITE \
diff --git a/lib/erl_interface/test/erl_global_SUITE.erl b/lib/erl_interface/test/erl_global_SUITE.erl
new file mode 100644
index 0000000000..9826e47d55
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE.erl
@@ -0,0 +1,125 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_global_SUITE).
+
+-include("test_server.hrl").
+-include("erl_global_SUITE_data/erl_global_test_cases.hrl").
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,
+	 erl_global_registration/1, erl_global_whereis/1, erl_global_names/1]).
+
+-import(runner, [get_term/1,send_term/2]).
+
+-define(GLOBAL_NAME, global_register_node_test).
+
+all(suite) ->
+    [erl_global_registration].
+
+init_per_testcase(_Case, Config) ->
+    Dog = ?t:timetrap(?t:minutes(0.25)),
+    [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+    Dog = ?config(watchdog, Config),
+    test_server:timetrap_cancel(Dog),
+    ok.
+
+erl_global_registration(Config) when is_list(Config) ->
+    ?line P = runner:start(?interpret),
+    ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+
+    ?line ok = erl_global_register(P, Fd, ?GLOBAL_NAME),
+    ?line ok = erl_global_unregister(P, Fd, ?GLOBAL_NAME),
+
+    ?line 0 = erl_close_connection(P,Fd),
+    ?line runner:send_eot(P),
+    ?line runner:recv_eot(P),
+    ok.
+
+erl_global_whereis(Config) when is_list(Config) ->
+    ?line P = runner:start(?interpret),
+    ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+
+    ?line Self = self(),
+    ?line global:register_name(?GLOBAL_NAME, Self),
+    ?line Self = erl_global_whereis(P, Fd, ?GLOBAL_NAME),
+    ?line global:unregister_name(?GLOBAL_NAME),
+    ?line 0 = erl_close_connection(P, Fd),
+    ?line runner:send_eot(P),
+    ?line runner:recv_eot(P),
+    ok.
+
+erl_global_names(Config) when is_list(Config) ->
+    ?line P = runner:start(?interpret),
+    ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
+
+    ?line Self = self(),
+    ?line global:register_name(?GLOBAL_NAME, Self),
+    ?line {[?GLOBAL_NAME], 1} = erl_global_names(P, Fd),
+    ?line global:unregister_name(?GLOBAL_NAME),
+    ?line 0 = erl_close_connection(P, Fd),
+    ?line runner:send_eot(P),
+    ?line runner:recv_eot(P),
+    ok.
+
+
+%%% Interface functions for erl_interface functions.
+
+erl_connect(P, Node, Num, Cookie, Creation) ->
+    send_command(P, erl_connect, [Num, Node, Cookie, Creation]),
+    case get_term(P) of
+	{term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
+	{term,{-1,Errno}} -> {error,Errno}
+    end.
+
+erl_close_connection(P, FD) ->
+    send_command(P, erl_close_connection, [FD]),
+    case get_term(P) of
+	{term,Int} when is_integer(Int) -> Int
+    end.
+
+erl_global_register(P, Fd, Name) ->
+    send_command(P, erl_global_register, [Fd,Name]),
+    get_send_result(P).
+
+erl_global_whereis(P, Fd, Name) ->
+    send_command(P, erl_global_whereis, [Fd,Name]),
+    get_send_result(P).
+
+erl_global_names(P, Fd) ->
+    send_command(P, erl_global_names, [Fd]),
+    get_send_result(P).
+
+erl_global_unregister(P, Fd, Name) ->
+    send_command(P, erl_global_unregister, [Fd,Name]),
+    get_send_result(P).
+
+get_send_result(P) ->
+    case get_term(P) of
+	{term,{1,_}} -> ok;
+	{term,{0, 0}} -> ok;
+	{term,{-1, Errno}} -> {error,Errno};
+	{term,{_,_}}->
+	    ?t:fail(bad_return_value)
+    end.
+
+send_command(P, Name, Args) ->
+    runner:send_term(P, {Name,list_to_tuple(Args)}).
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..8e3fcb924e
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+erl_global_test_decl.c: erl_global_test.c
+	erl -noinput -pa ../all_SUITE_data -s init_tc run erl_global_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..ef846bc440
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE_data/Makefile.src
@@ -0,0 +1,41 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@DS@eidefs.mk
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/runner@obj@ \
+	$(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+	@erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+OBJS = erl_global_test@obj@ erl_global_test_decl@obj@
+
+all: erl_global_test@exe@
+
+erl_global_test@exe@: $(OBJS) $(LIBERL) $(LIBEI)
+	$(LD) @CROSSLDFLAGS@ -o $@ $(OBJS) $(LIBFLAGS)
+
+clean:
+	$(RM) $(OBJS)
+	$(RM) erl_global_test@exe@
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
new file mode 100644
index 0000000000..fc698ca0c4
--- /dev/null
+++ b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
@@ -0,0 +1,263 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the functions in erl_global.c.
+ *
+ * See the erl_global_SUITE.erl file for a "table of contents".
+ */
+
+#include 
+#include 
+#include 
+
+#include "runner.h"
+
+static void cmd_erl_connect(ETERM* args);
+static void cmd_erl_global_register(ETERM *args);
+static void cmd_erl_global_whereis(ETERM *args);
+static void cmd_erl_global_names(ETERM *args);
+static void cmd_erl_global_unregister(ETERM *args);
+static void cmd_erl_close_connection(ETERM *args);
+
+static void send_errno_result(int value);
+
+static struct {
+    char* name;
+    int num_args;		/* Number of arguments. */
+    void (*func)(ETERM* args);
+} commands[] = {
+    "erl_connect", 	     4, cmd_erl_connect,
+    "erl_close_connection",  1, cmd_erl_close_connection,
+    "erl_global_register",   2, cmd_erl_global_register,
+    "erl_global_whereis",    1, cmd_erl_global_whereis,
+    "erl_global_names",      0, cmd_erl_global_names,
+    "erl_global_unregister", 2, cmd_erl_global_unregister,
+};
+
+
+/*
+ * Sends a list contaning all data types to the Erlang side.
+ */
+
+TESTCASE(interpret)
+{
+    ETERM* term;
+
+    erl_init(NULL, 0);
+
+    outer_loop:
+
+    term = get_term();
+
+    if (term == NULL) {
+	report(1);
+	return;
+    } else {
+	ETERM* Func;
+	ETERM* Args;
+	int i;
+
+	if (!ERL_IS_TUPLE(term) || ERL_TUPLE_SIZE(term) != 2) {
+	    fail("term should be a tuple of size 2");
+	}
+
+	Func = erl_element(1, term);
+	if (!ERL_IS_ATOM(Func)) {
+	    fail("function name should be an atom");
+	}
+	Args = erl_element(2, term);
+	if (!ERL_IS_TUPLE(Args)) {
+	    fail("function arguments should be a tuple");
+	}
+	erl_free_term(term);
+	for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
+	    int n = strlen(commands[i].name);
+	    if (ERL_ATOM_SIZE(Func) != n) {
+		continue;
+	    }
+	    if (memcmp(ERL_ATOM_PTR(Func), commands[i].name, n) == 0) {
+		erl_free_term(Func);
+		if (ERL_TUPLE_SIZE(Args) != commands[i].num_args) {
+		    fail("wrong number of arguments");
+		}
+		commands[i].func(Args);
+		erl_free_term(Args);
+		goto outer_loop;
+	    }
+	}
+	fail("bad command");
+    }
+}
+
+#define VERIFY_TYPE(Test, Term)		        \
+if (!Test(Term)) { 				\
+    fail("wrong type for " #Term);		\
+} else {					\
+}
+
+static void
+cmd_erl_connect(ETERM* args)
+{
+    ETERM* number;
+    ETERM* node;
+    ETERM* cookie;
+
+    int res;
+    char buffer[256];
+
+    number = ERL_TUPLE_ELEMENT(args, 0);
+    VERIFY_TYPE(ERL_IS_INTEGER, number);
+    node = ERL_TUPLE_ELEMENT(args, 1);
+    VERIFY_TYPE(ERL_IS_ATOM, node);
+    cookie = ERL_TUPLE_ELEMENT(args, 2);
+    VERIFY_TYPE(ERL_IS_ATOM, cookie);
+
+    if (ERL_ATOM_SIZE(cookie) == 0) {
+	res = erl_connect_init(ERL_INT_VALUE(number), 0, 0);
+    } else {
+	memcpy(buffer, ERL_ATOM_PTR(cookie), ERL_ATOM_SIZE(cookie));
+	buffer[ERL_ATOM_SIZE(cookie)] = '\0';
+	res = erl_connect_init(ERL_INT_VALUE(number), buffer, 0);
+    }
+
+    if(!res) {
+	send_errno_result(res);
+	return;
+    }
+
+    memcpy(buffer, ERL_ATOM_PTR(node), ERL_ATOM_SIZE(node));
+    buffer[ERL_ATOM_SIZE(node)] = '\0';
+    send_errno_result(erl_connect(buffer));
+}
+
+static void
+cmd_erl_close_connection(ETERM* args)
+{
+    ETERM* number;
+    ETERM* res;
+
+    number = ERL_TUPLE_ELEMENT(args, 0);
+    VERIFY_TYPE(ERL_IS_INTEGER, number);
+    res = erl_mk_int(erl_close_connection(ERL_INT_VALUE(number)));
+    send_term(res);
+    erl_free_term(res);
+}
+
+static void
+cmd_erl_global_register(ETERM* args)
+{
+    ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+    ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
+    ETERM* pid = erl_mk_pid(erl_thisnodename(), 14, 0, 0);
+
+    char buffer[256];
+
+    VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+    VERIFY_TYPE(ERL_IS_ATOM, name);
+
+    memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
+    buffer[ERL_ATOM_SIZE(name)] = '\0';
+
+    send_errno_result(erl_global_register(ERL_INT_VALUE(fd_term), buffer, pid));
+    erl_free_term(pid);
+}
+
+static void
+cmd_erl_global_whereis(ETERM* args)
+{
+    ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+    ETERM* name = ERL_TUPLE_ELEMENT(args, 1);
+    ETERM* pid = NULL;
+
+    char buffer[256];
+
+    VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+    VERIFY_TYPE(ERL_IS_ATOM, name);
+
+    memcpy(buffer, ERL_ATOM_PTR(name), ERL_ATOM_SIZE(name));
+    buffer[ERL_ATOM_SIZE(name)] = '\0';
+
+    pid = erl_global_whereis(ERL_INT_VALUE(fd_term), buffer, NULL);
+    send_term(pid);
+    erl_free_term(pid);
+}
+
+static void
+cmd_erl_global_names(ETERM* args)
+{
+    ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+
+    ETERM* res_array[2], *res_tuple, *name;
+    char** names = NULL;
+    int count = 0, i;
+
+    VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+
+    names = erl_global_names(ERL_INT_VALUE(fd_term), &count);
+
+    res_array[0] = erl_mk_empty_list();
+    for(i=0; i
Date: Fri, 10 Dec 2010 16:38:13 +0200
Subject: Fix wrong erl_compare_ext result comparing lists

Function erl_compare_ext of erl_interface library returns
1 instead -1 when comparing lists like [0] and [0, 1000].

Credits to: Evgeny Khirin  erlios.com>
---
 lib/erl_interface/src/legacy/erl_marshal.c           | 13 ++++++++-----
 lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c | 12 ++++++++++++
 2 files changed, 20 insertions(+), 5 deletions(-)

(limited to 'lib/erl_interface')

diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index a6c2f64dd0..70949a7adf 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -1646,11 +1646,14 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
       min = (i < j) ? i : j;
       k = 0;
       while (1) {
-	if (k++ == min)
-	  return compare_top_ext(e1 , e2);
-	if ((ret = compare_top_ext(e1 , e2)) == 0) 
-	  continue;
-	return ret;
+	  if (k++ == min){
+	      if (i == j) return 0;
+	      if (i < j) return -1;
+	      return 1;
+	  }
+	  if ((ret = compare_top_ext(e1 , e2)) == 0)
+	      continue;
+	  return ret;
       }
     case ERL_STRING_EXT:
       i = (**e1 << 8) | ((*e1)[1]);
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
index ba1a6c66da..59e0e0cce7 100644
--- a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
@@ -82,6 +82,11 @@ TESTCASE(compare_list) {
     // erlang:term_to_binary([34,{a,n},a,erlang])
     unsigned char term2[] = {131,108,0,0,0,4,97,34,104,2,100,0,1,97,100,0,1,110,100,0,1,97,100,0,6,101,114,108,97,110,103,106};
 
+    // erlang:term_to_binary([0])
+    unsigned char term3[] = {131,107,0,1,0};
+    // erlang:term_to_binary([0, 1000])
+    unsigned char term4[] = {131,108,0,0,0,2,97,0,98,0,0,3,232,106};
+
     erl_init(NULL, 0);
     start_a = term1;
     start_b = term2;
@@ -90,6 +95,13 @@ TESTCASE(compare_list) {
     
     test_compare_ext("lists", start_a, end_a, start_b, end_b, 1);
 
+    start_a = term3;
+    start_b = term4;
+    end_a   = term3 + sizeof(term3);
+    end_b   = term4 + sizeof(term4);
+
+    test_compare_ext("lists1", start_a, end_a, start_b, end_b, -1);
+
     report(1);
 }
 
-- 
cgit v1.2.3


From bcbe0813a0b97f86a7db354e09bf0397cf68f787 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= 
Date: Thu, 30 Dec 2010 17:48:36 +0100
Subject: Fix testcases erl_global_whereis, erl_global_names

Enable erl_global_whereis and erl_global names.
---
 lib/erl_interface/test/erl_global_SUITE.erl          | 20 ++++++++++++++------
 .../test/erl_global_SUITE_data/erl_global_test.c     |  4 ++--
 lib/erl_interface/test/port_call_SUITE.erl           |  2 ++
 3 files changed, 18 insertions(+), 8 deletions(-)

(limited to 'lib/erl_interface')

diff --git a/lib/erl_interface/test/erl_global_SUITE.erl b/lib/erl_interface/test/erl_global_SUITE.erl
index 9826e47d55..4f332037c6 100644
--- a/lib/erl_interface/test/erl_global_SUITE.erl
+++ b/lib/erl_interface/test/erl_global_SUITE.erl
@@ -31,7 +31,7 @@
 -define(GLOBAL_NAME, global_register_node_test).
 
 all(suite) ->
-    [erl_global_registration].
+    [erl_global_registration, erl_global_whereis, erl_global_names].
 
 init_per_testcase(_Case, Config) ->
     Dog = ?t:timetrap(?t:minutes(0.25)),
@@ -59,7 +59,7 @@ erl_global_whereis(Config) when is_list(Config) ->
     ?line {ok, Fd} = erl_connect(P, node(), 42, erlang:get_cookie(), 0),
 
     ?line Self = self(),
-    ?line global:register_name(?GLOBAL_NAME, Self),
+    ?line yes = global:register_name(?GLOBAL_NAME, Self),
     ?line Self = erl_global_whereis(P, Fd, ?GLOBAL_NAME),
     ?line global:unregister_name(?GLOBAL_NAME),
     ?line 0 = erl_close_connection(P, Fd),
@@ -73,14 +73,16 @@ erl_global_names(Config) when is_list(Config) ->
 
     ?line Self = self(),
     ?line global:register_name(?GLOBAL_NAME, Self),
-    ?line {[?GLOBAL_NAME], 1} = erl_global_names(P, Fd),
+    ?line {Names1, _N1} = erl_global_names(P, Fd),
+    ?line true = lists:member(atom_to_list(?GLOBAL_NAME), Names1),
     ?line global:unregister_name(?GLOBAL_NAME),
+    ?line {Names2, _N2} = erl_global_names(P, Fd),
+    ?line false = lists:member(atom_to_list(?GLOBAL_NAME), Names2),
     ?line 0 = erl_close_connection(P, Fd),
     ?line runner:send_eot(P),
     ?line runner:recv_eot(P),
     ok.
 
-
 %%% Interface functions for erl_interface functions.
 
 erl_connect(P, Node, Num, Cookie, Creation) ->
@@ -102,11 +104,17 @@ erl_global_register(P, Fd, Name) ->
 
 erl_global_whereis(P, Fd, Name) ->
     send_command(P, erl_global_whereis, [Fd,Name]),
-    get_send_result(P).
+    case get_term(P) of
+	{term, What} ->
+	    What
+    end.
 
 erl_global_names(P, Fd) ->
     send_command(P, erl_global_names, [Fd]),
-    get_send_result(P).
+    case get_term(P) of
+	{term, What} ->
+	    What
+    end.
 
 erl_global_unregister(P, Fd, Name) ->
     send_command(P, erl_global_unregister, [Fd,Name]),
diff --git a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
index fc698ca0c4..dc0d8a0091 100644
--- a/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
+++ b/lib/erl_interface/test/erl_global_SUITE_data/erl_global_test.c
@@ -46,8 +46,8 @@ static struct {
     "erl_connect", 	     4, cmd_erl_connect,
     "erl_close_connection",  1, cmd_erl_close_connection,
     "erl_global_register",   2, cmd_erl_global_register,
-    "erl_global_whereis",    1, cmd_erl_global_whereis,
-    "erl_global_names",      0, cmd_erl_global_names,
+    "erl_global_whereis",    2, cmd_erl_global_whereis,
+    "erl_global_names",      1, cmd_erl_global_names,
     "erl_global_unregister", 2, cmd_erl_global_unregister,
 };
 
diff --git a/lib/erl_interface/test/port_call_SUITE.erl b/lib/erl_interface/test/port_call_SUITE.erl
index 895e29ad2e..2c550e4c0c 100644
--- a/lib/erl_interface/test/port_call_SUITE.erl
+++ b/lib/erl_interface/test/port_call_SUITE.erl
@@ -42,6 +42,8 @@ all(suite) ->
 basic(suite) -> [];
 basic(Config) when is_list(Config) ->
     case os:type() of
+	{unix, linux} ->
+	    do_basic(Config);
 	{unix, sunos} ->
 	    do_basic(Config);
 	{win32,_} ->
-- 
cgit v1.2.3