aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--erts/emulator/beam/bif.c5
-rw-r--r--erts/emulator/beam/dist.c159
-rw-r--r--erts/emulator/beam/dist.h3
-rw-r--r--erts/emulator/drivers/common/inet_drv.c52
-rw-r--r--erts/emulator/drivers/win32/win_con.c12
-rw-r--r--erts/emulator/test/distribution_SUITE.erl290
-rw-r--r--erts/emulator/test/erl_link_SUITE.erl3
-rw-r--r--lib/erl_interface/include/ei.h2
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c3
-rw-r--r--lib/erl_interface/src/connect/eirecv.c6
-rw-r--r--lib/erl_interface/src/misc/show_msg.c9
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl23
-rw-r--r--lib/hipe/cerl/erl_types.erl28
-rw-r--r--lib/ic/doc/src/notes.xml20
-rw-r--r--lib/ic/src/ic_forms.erl6
-rw-r--r--lib/ic/src/ic_pragma.erl12
-rw-r--r--lib/ic/src/ic_symtab.erl4
-rw-r--r--lib/ic/src/icforms.hrl3
-rw-r--r--lib/ic/src/icparse.yrl22
-rw-r--r--lib/ic/src/ictype.erl41
-rw-r--r--lib/ic/vsn.mk2
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java7
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java3
-rw-r--r--lib/orber/doc/src/ch_idl_to_erlang_mapping.xml37
-rw-r--r--lib/orber/doc/src/notes.xml30
-rw-r--r--lib/orber/src/cdr_decode.erl78
-rw-r--r--lib/orber/src/cdr_encode.erl30
-rw-r--r--lib/orber/src/orber_socket.erl16
-rw-r--r--lib/orber/test/Makefile6
-rw-r--r--lib/orber/test/orber_test_lib.erl16
-rw-r--r--lib/orber/test/orber_test_server.idl25
-rw-r--r--lib/orber/test/orber_test_server_impl.erl15
-rw-r--r--lib/orber/vsn.mk2
34 files changed, 745 insertions, 231 deletions
diff --git a/.gitignore b/.gitignore
index d67116d6e3..54bfadea9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,10 @@
# Match at any level.
+
+# emacs
*~
+# vim
+.*.sw[a-z]
+
autom4te.cache
*.beam
*.asn1db
@@ -162,6 +167,7 @@ make/win32/
/erts/emulator/test/*_SUITE_make.erl
/erts/emulator/test/*_SUITE_data/Makefile
/erts/test/install_SUITE_data/install_bin
+/erts/test/autoimport_SUITE_data/erlang.xml
# asn1
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index d4a43f6e5f..bb237e378a 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -1351,9 +1351,10 @@ BIF_RETTYPE exit_2(BIF_ALIST_2)
#ifdef ERTS_SMP
if (rp == BIF_P)
rp_locks &= ~ERTS_PROC_LOCK_MAIN;
- else
+ if (rp_locks)
+ erts_smp_proc_unlock(rp, rp_locks);
+ if (rp != BIF_P)
erts_smp_proc_dec_refc(rp);
- erts_smp_proc_unlock(rp, rp_locks);
#endif
/*
* We may have exited ourselves and may have to take action.
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 694460d702..02910fad90 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -917,6 +917,7 @@ int erts_net_message(Port *prt,
Eterm token_size;
ErtsMonitor *mon;
ErtsLink *lnk;
+ Uint tuple_arity;
int res;
#ifdef ERTS_DIST_MSG_DBG
int orig_len = len;
@@ -1003,29 +1004,23 @@ int erts_net_message(Port *prt,
#endif
if (is_not_tuple(arg) ||
- (tuple = tuple_val(arg), arityval(*tuple) < 1) ||
+ (tuple = tuple_val(arg), (tuple_arity = arityval(*tuple)) < 1) ||
is_not_small(tuple[1])) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp, "Invalid distribution message: %.200T", arg);
- erts_send_error_to_logger_nogl(dsbufp);
- goto data_error;
+ goto invalid_message;
}
token_size = 0;
switch (type = unsigned_val(tuple[1])) {
case DOP_LINK:
+ if (tuple_arity != 3) {
+ goto invalid_message;
+ }
from = tuple[2];
to = tuple[3]; /* local proc to link to */
if (is_not_pid(from) || is_not_pid(to)) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- PURIFY_MSG("data error");
- erts_dsprintf(dsbufp,
- "Invalid DOP_LINK distribution message: %.200T",
- arg);
- erts_send_error_to_logger_nogl(dsbufp);
- goto data_error;
+ goto invalid_message;
}
rp = erts_pid2proc_opt(NULL, 0,
@@ -1064,8 +1059,14 @@ int erts_net_message(Port *prt,
case DOP_UNLINK: {
ErtsDistLinkData dld;
+ if (tuple_arity != 3) {
+ goto invalid_message;
+ }
from = tuple[2];
to = tuple[3];
+ if (is_not_pid(from) || is_not_pid(to)) {
+ goto invalid_message;
+ }
rp = erts_pid2proc_opt(NULL, 0,
to, ERTS_PROC_LOCK_LINK,
@@ -1092,11 +1093,19 @@ int erts_net_message(Port *prt,
/* A remote process wants to monitor us, we get:
{DOP_MONITOR_P, Remote pid, local pid or name, ref} */
Eterm name;
+
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
watcher = tuple[2];
watched = tuple[3]; /* local proc to monitor */
ref = tuple[4];
+ if (is_not_ref(ref)) {
+ goto invalid_message;
+ }
+
if (is_atom(watched)) {
name = watched;
rp = erts_whereis_process(NULL, 0,
@@ -1138,10 +1147,17 @@ int erts_net_message(Port *prt,
We get {DOP_DEMONITOR_P, Remote pid, Local pid or name, ref},
We need only the ref of course */
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
/* watcher = tuple[2]; */
/* watched = tuple[3]; May be an atom in case of monitor name */
ref = tuple[4];
+ if(is_not_ref(ref)) {
+ goto invalid_message;
+ }
+
erts_smp_de_links_lock(dep);
mon = erts_remove_monitor(&(dep->monitors),ref);
erts_smp_de_links_unlock(dep);
@@ -1166,10 +1182,11 @@ int erts_net_message(Port *prt,
erts_destroy_monitor(mon);
break;
- case DOP_NODE_LINK: /* XXX never sent ?? */
- break;
-
case DOP_REG_SEND_TT:
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+
token_size = size_object(tuple[5]);
/* Fall through ... */
case DOP_REG_SEND:
@@ -1180,12 +1197,19 @@ int erts_net_message(Port *prt,
* There is intentionally no testing of the cookie (it is always '')
* from R9B and onwards.
*/
+ if (type != DOP_REG_SEND_TT && tuple_arity != 4) {
+ goto invalid_message;
+ }
+
#ifdef ERTS_DIST_MSG_DBG
dist_msg_dbg(&ede, "MSG", buf, orig_len);
#endif
from = tuple[2];
to = tuple[4];
+ if (is_not_pid(from) || is_not_atom(to)){
+ goto invalid_message;
+ }
rp = erts_whereis_process(NULL, 0, to, 0, ERTS_P2P_FLG_SMP_INC_REFC);
if (rp) {
Uint xsize = (type == DOP_REG_SEND
@@ -1217,6 +1241,10 @@ int erts_net_message(Port *prt,
break;
case DOP_SEND_TT:
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
+
token_size = size_object(tuple[4]);
/* Fall through ... */
case DOP_SEND:
@@ -1227,8 +1255,13 @@ int erts_net_message(Port *prt,
#ifdef ERTS_DIST_MSG_DBG
dist_msg_dbg(&ede, "MSG", buf, orig_len);
#endif
-
+ if (type != DOP_SEND_TT && tuple_arity != 3) {
+ goto invalid_message;
+ }
to = tuple[3];
+ if (is_not_pid(to)) {
+ goto invalid_message;
+ }
rp = erts_pid2proc_opt(NULL, 0, to, 0, ERTS_P2P_FLG_SMP_INC_REFC);
if (rp) {
Uint xsize = type == DOP_SEND ? 0 : ERTS_HEAP_FRAG_SIZE(token_size);
@@ -1266,11 +1299,19 @@ int erts_net_message(Port *prt,
Eterm sysname;
ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_MSG_SEND|ERTS_PROC_LOCK_LINK;
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+
/* watched = tuple[2]; */ /* remote proc which died */
/* watcher = tuple[3]; */
ref = tuple[4];
reason = tuple[5];
+ if(is_not_ref(ref)) {
+ goto invalid_message;
+ }
+
erts_smp_de_links_lock(dep);
sysname = dep->sysname;
mon = erts_remove_monitor(&(dep->monitors), ref);
@@ -1317,24 +1358,25 @@ int erts_net_message(Port *prt,
ErtsProcLocks rp_locks = ERTS_PROC_LOCK_LINK|ERTS_PROC_LOCKS_XSIG_SEND;
/* 'from', which 'to' is linked to, died */
if (type == DOP_EXIT) {
- from = tuple[2];
- to = tuple[3];
- reason = tuple[4];
- token = NIL;
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
+
+ from = tuple[2];
+ to = tuple[3];
+ reason = tuple[4];
+ token = NIL;
} else {
- from = tuple[2];
- to = tuple[3];
- token = tuple[4];
- reason = tuple[5];
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+ from = tuple[2];
+ to = tuple[3];
+ token = tuple[4];
+ reason = tuple[5];
}
- if (is_not_internal_pid(to)) {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- PURIFY_MSG("data error");
- erts_dsprintf(dsbufp,
- "Invalid DOP_EXIT distribution message: %.200T",
- arg);
- erts_send_error_to_logger_nogl(dsbufp);
- goto data_error;
+ if (is_not_pid(from) || is_not_internal_pid(to)) {
+ goto invalid_message;
}
rp = erts_pid2proc(NULL, 0, to, rp_locks);
@@ -1381,15 +1423,24 @@ int erts_net_message(Port *prt,
ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
/* 'from' is send an exit signal to 'to' */
if (type == DOP_EXIT2) {
- from = tuple[2];
- to = tuple[3];
- reason = tuple[4];
- token = NIL;
+ if (tuple_arity != 4) {
+ goto invalid_message;
+ }
+ from = tuple[2];
+ to = tuple[3];
+ reason = tuple[4];
+ token = NIL;
} else {
- from = tuple[2];
- to = tuple[3];
- token = tuple[4];
- reason = tuple[5];
+ if (tuple_arity != 5) {
+ goto invalid_message;
+ }
+ from = tuple[2];
+ to = tuple[3];
+ token = tuple[4];
+ reason = tuple[5];
+ }
+ if (is_not_pid(from) || is_not_internal_pid(to)) {
+ goto invalid_message;
}
rp = erts_pid2proc_opt(NULL, 0, to, rp_locks,
ERTS_P2P_FLG_SMP_INC_REFC);
@@ -1408,10 +1459,14 @@ int erts_net_message(Port *prt,
break;
}
case DOP_GROUP_LEADER:
+ if (tuple_arity != 3) {
+ goto invalid_message;
+ }
from = tuple[2]; /* Group leader */
to = tuple[3]; /* new member */
- if (is_not_pid(from))
- break;
+ if (is_not_pid(from) || is_not_pid(to)) {
+ goto invalid_message;
+ }
rp = erts_pid2proc(NULL, 0, to, ERTS_PROC_LOCK_MAIN);
if (!rp)
@@ -1420,16 +1475,8 @@ int erts_net_message(Port *prt,
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_MAIN);
break;
- default: {
- erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
- erts_dsprintf(dsbufp,
- "Illegal value in distribution dispatch switch: "
- "%.200T",
- arg);
- erts_send_error_to_logger_nogl(dsbufp);
- PURIFY_MSG("data error");
- goto data_error;
- }
+ default:
+ goto invalid_message;
}
erts_cleanup_offheap(&off_heap);
@@ -1441,8 +1488,14 @@ int erts_net_message(Port *prt,
UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
ERTS_SMP_CHK_NO_PROC_LOCKS;
return 0;
-
+ invalid_message:
+ {
+ erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
+ erts_dsprintf(dsbufp, "Invalid distribution message: %.200T", arg);
+ erts_send_error_to_logger_nogl(dsbufp);
+ }
data_error:
+ PURIFY_MSG("data error");
erts_cleanup_offheap(&off_heap);
#ifndef HYBRID /* FIND ME! */
if (ctl != ctl_default) {
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index 9ccc3e5ba9..695a4fc3fe 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -52,7 +52,7 @@
#define DOP_SEND 2
#define DOP_EXIT 3
#define DOP_UNLINK 4
-#define DOP_NODE_LINK 5
+/* Ancient DOP_NODE_LINK (5) was here, can be reused */
#define DOP_REG_SEND 6
#define DOP_GROUP_LEADER 7
#define DOP_EXIT2 8
@@ -69,7 +69,6 @@
/* distribution trap functions */
extern Export* dsend2_trap;
extern Export* dsend3_trap;
-/*extern Export* dsend_nosuspend_trap;*/
extern Export* dlink_trap;
extern Export* dunlink_trap;
extern Export* dmonitor_node_trap;
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 1382d1dfe4..818bc6334e 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -4945,39 +4945,45 @@ static int inet_ctl_getifaddrs(inet_descriptor* desc_p,
*buf_p++ = '\0';
*buf_p++ = INET_IFOPT_FLAGS;
put_int32(IFGET_FLAGS(ifa_p->ifa_flags), buf_p); buf_p += 4;
- if (ifa_p->ifa_addr->sa_family == AF_INET
+ if (ifa_p->ifa_addr) {
+ if (ifa_p->ifa_addr->sa_family == AF_INET
#if defined(AF_INET6)
- || ifa_p->ifa_addr->sa_family == AF_INET6
+ || ifa_p->ifa_addr->sa_family == AF_INET6
#endif
- ) {
- SOCKADDR_TO_BUF(INET_IFOPT_ADDR, ifa_p->ifa_addr);
- BUF_ENSURE(1);
- SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, ifa_p->ifa_netmask);
- if (ifa_p->ifa_flags & IFF_POINTOPOINT) {
- BUF_ENSURE(1);
- SOCKADDR_TO_BUF(INET_IFOPT_DSTADDR, ifa_p->ifa_dstaddr);
- } else if (ifa_p->ifa_flags & IFF_BROADCAST) {
- BUF_ENSURE(1);
- SOCKADDR_TO_BUF(INET_IFOPT_BROADADDR, ifa_p->ifa_broadaddr);
+ ) {
+ SOCKADDR_TO_BUF(INET_IFOPT_ADDR, ifa_p->ifa_addr);
+ if (ifa_p->ifa_netmask) {
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, ifa_p->ifa_netmask);
+ }
+ if (ifa_p->ifa_dstaddr &&
+ (ifa_p->ifa_flags & IFF_POINTOPOINT)) {
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_DSTADDR, ifa_p->ifa_dstaddr);
+ } else if (ifa_p->ifa_broadaddr &&
+ (ifa_p->ifa_flags & IFF_BROADCAST)) {
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_BROADADDR, ifa_p->ifa_broadaddr);
+ }
}
- }
#if defined(AF_LINK) || defined(AF_PACKET)
- else if (
+ else if (
#if defined(AF_LINK)
- ifa_p->ifa_addr->sa_family == AF_LINK
+ ifa_p->ifa_addr->sa_family == AF_LINK
#else
- 0
+ 0
#endif
#if defined(AF_PACKET)
- || ifa_p->ifa_addr->sa_family == AF_PACKET
+ || ifa_p->ifa_addr->sa_family == AF_PACKET
#endif
- ) {
- char *bp = buf_p;
- BUF_ENSURE(1);
- SOCKADDR_TO_BUF(INET_IFOPT_HWADDR, ifa_p->ifa_addr);
- if (buf_p - bp < 4) buf_p = bp; /* Empty hwaddr */
- }
+ ) {
+ char *bp = buf_p;
+ BUF_ENSURE(1);
+ SOCKADDR_TO_BUF(INET_IFOPT_HWADDR, ifa_p->ifa_addr);
+ if (buf_p - bp < 4) buf_p = bp; /* Empty hwaddr */
+ }
#endif
+ }
BUF_ENSURE(1);
*buf_p++ = '\0';
}
diff --git a/erts/emulator/drivers/win32/win_con.c b/erts/emulator/drivers/win32/win_con.c
index 2202ca655f..14f7941643 100644
--- a/erts/emulator/drivers/win32/win_con.c
+++ b/erts/emulator/drivers/win32/win_con.c
@@ -704,6 +704,18 @@ FrameWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
}
write_inbuf(&c, 1);
return 0;
+ case WM_MOUSEWHEEL:
+ {
+ int delta = GET_WHEEL_DELTA_WPARAM(wParam);
+ if (delta < 0) {
+ PostMessage(hClientWnd, WM_VSCROLL, MAKELONG(SB_THUMBTRACK,
+ (iVscrollPos + 5)),0);
+ } else {
+ WORD pos = ((iVscrollPos - 5) < 0) ? 0 : (iVscrollPos - 5);
+ PostMessage(hClientWnd, WM_VSCROLL, MAKELONG(SB_THUMBTRACK,pos),0);
+ }
+ return 0;
+ }
case WM_CHAR:
c = (TCHAR)wParam;
write_inbuf(&c,1);
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index 79252d0593..f26455e6da 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -39,6 +39,7 @@
atom_roundtrip/1,
atom_roundtrip_r12b/1,
contended_atom_cache_entry/1,
+ bad_dist_structure/1,
bad_dist_ext/1,
bad_dist_ext_receive/1,
bad_dist_ext_process_info/1,
@@ -61,6 +62,7 @@ all(suite) -> [
stop_dist, trap_bif, dist_auto_connect, dist_parallel_send,
atom_roundtrip, atom_roundtrip_r12b,
contended_atom_cache_entry,
+ bad_dist_structure,
bad_dist_ext
].
@@ -174,7 +176,7 @@ bulk_sendsend2(Terms, BinSize, BusyBufSize) ->
?line {ok, NodeRecv} = start_node(bulk_receiver),
?line Recv = spawn(NodeRecv, erlang, apply, [fun receiver/2, [0, 0]]),
?line Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)),
- ?line Size = Terms*size(Bin),
+ %%?line Size = Terms*size(Bin),
%% SLF LEFT OFF HERE.
%% When the caller uses small hunks, like 4k via
@@ -187,7 +189,7 @@ bulk_sendsend2(Terms, BinSize, BusyBufSize) ->
?line {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ integer_to_list(BusyBufSize)),
?line _Send = spawn(NodeSend, erlang, apply, [fun sendersender/4, [self(), Recv, Bin, Terms]]),
- ?line {Elapsed, {TermsN, SizeN}, MonitorCount} =
+ ?line {Elapsed, {_TermsN, SizeN}, MonitorCount} =
receive {sendersender, BigRes} ->
BigRes
end,
@@ -227,7 +229,7 @@ sendersender3(To, _Bin, 0, SendDone, MonitorCount) ->
ok
end,
receive
- {monitor, _Pid, _Type, _Info} = M ->
+ {monitor, _Pid, _Type, _Info} ->
sendersender3(To, _Bin, 0, SendDone, MonitorCount + 1)
after 0 ->
if SendDone ->
@@ -522,7 +524,7 @@ sink1() ->
lost_exit(doc) ->
"Test that EXIT and DOWN messages send to another node are not lost if "
- "if the distribution port is busy.";
+ "the distribution port is busy.";
lost_exit(Config) when is_list(Config) ->
?line {ok, Node} = start_node(lost_exit),
@@ -1143,8 +1145,7 @@ contended_atom_cache_entry(Config) when is_list(Config) ->
?line {ok, SNode} = start_node(Config),
?line {ok, RNode} = start_node(Config),
?line Success = make_ref(),
- ?line Mstr
- = spawn_link(
+ ?line spawn_link(
SNode,
fun () ->
erts_debug:set_internal_state(available_internal_state,
@@ -1201,13 +1202,13 @@ contended_atom_cache_entry(Config) when is_list(Config) ->
?line stop_node(RNode),
?line ok.
-send_ref_atom(To, Ref, Atom, 0) ->
+send_ref_atom(_To, _Ref, _Atom, 0) ->
ok;
send_ref_atom(To, Ref, Atom, N) ->
To ! {Ref, Atom},
send_ref_atom(To, Ref, Atom, N-1).
-receive_ref_atom(Ref, Atom, 0) ->
+receive_ref_atom(_Ref, _Atom, 0) ->
ok;
receive_ref_atom(Ref, Atom, N) ->
receive
@@ -1242,7 +1243,7 @@ unwanted_cixs() ->
nodes()).
-get_conflicting_atoms(CIX, 0) ->
+get_conflicting_atoms(_CIX, 0) ->
[];
get_conflicting_atoms(CIX, N) ->
{A, B, C} = now(),
@@ -1256,6 +1257,186 @@ get_conflicting_atoms(CIX, N) ->
get_conflicting_atoms(CIX, N)
end.
+-define(COOKIE, '').
+-define(DOP_LINK, 1).
+-define(DOP_SEND, 2).
+-define(DOP_EXIT, 3).
+-define(DOP_UNLINK, 4).
+-define(DOP_REG_SEND, 6).
+-define(DOP_GROUP_LEADER, 7).
+-define(DOP_EXIT2, 8).
+
+-define(DOP_SEND_TT, 12).
+-define(DOP_EXIT_TT, 13).
+-define(DOP_REG_SEND_TT, 16).
+-define(DOP_EXIT2_TT, 18).
+
+-define(DOP_MONITOR_P, 19).
+-define(DOP_DEMONITOR_P, 20).
+-define(DOP_MONITOR_P_EXIT, 21).
+
+start_monitor(Offender,P) ->
+ ?line Parent = self(),
+ ?line Q = spawn(Offender,
+ fun () ->
+ Ref = erlang:monitor(process,P),
+ Parent ! {self(),ref,Ref},
+ receive
+ just_stay_alive -> ok
+ end
+ end),
+ ?line Ref = receive
+ {Q,ref,R} ->
+ R
+ after 5000 ->
+ error
+ end,
+ io:format("Ref is ~p~n",[Ref]),
+ ok.
+start_link(Offender,P) ->
+ ?line Parent = self(),
+ ?line Q = spawn(Offender,
+ fun () ->
+ process_flag(trap_exit,true),
+ link(P),
+ Parent ! {self(),ref,P},
+ receive
+ just_stay_alive -> ok
+ end
+ end),
+ ?line Ref = receive
+ {Q,ref,R} ->
+ R
+ after 5000 ->
+ error
+ end,
+ io:format("Ref is ~p~n",[Ref]),
+ ok.
+
+bad_dist_structure(suite) ->
+ [];
+bad_dist_structure(doc) ->
+ ["Test dist messages with valid structure (binary to term ok) but malformed"
+ "control content"];
+bad_dist_structure(Config) when is_list(Config) ->
+ %process_flag(trap_exit,true),
+ ODog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(ODog),
+ Dog = ?t:timetrap(?t:seconds(15)),
+
+ ?line {ok, Offender} = start_node(bad_dist_structure_offender),
+ ?line {ok, Victim} = start_node(bad_dist_structure_victim),
+ ?line start_node_monitors([Offender,Victim]),
+ ?line Parent = self(),
+ ?line P = spawn(Victim,
+ fun () ->
+ process_flag(trap_exit,true),
+ Parent ! {self(), started},
+ receive check_msgs -> ok end,
+ bad_dist_struct_check_msgs([one,
+ two]),
+ Parent ! {self(), messages_checked},
+ receive done -> ok end
+ end),
+ ?line receive {P, started} -> ok end,
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line verify_up(Offender, Victim),
+ ?line true = lists:member(Offender, rpc:call(Victim, erlang, nodes, [])),
+ ?line start_monitor(Offender,P),
+ ?line P ! one,
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P_EXIT,'replace',P,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P_EXIT,'replace',P,normal,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_LINK},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,'replace'},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,'replace',make_ref()},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,make_ref(),P},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_link(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_UNLINK,normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_MONITOR_P,'replace',P,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_DEMONITOR_P,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line start_monitor(Offender,P),
+ ?line send_bad_structure(Offender, P,{?DOP_DEMONITOR_P,'replace',P,normal},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT,make_ref(),normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT_TT,'replace',token,P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT_TT,make_ref(),token,normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2,'replace',P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2,make_ref(),normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2_TT,'replace',token,P},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_EXIT2_TT,make_ref(),token,normal,normal},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace'},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace','atomic'},2),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_GROUP_LEADER,'replace',P},0),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND_TT,'replace','',name},2,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND_TT,'replace','',name,token},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace',''},2,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',P},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',name},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_REG_SEND,'replace','',name,{token}},2,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND_TT,'',P},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND_TT,'',name,token},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND,''},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND,'',name},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line send_bad_structure(Offender, P,{?DOP_SEND,'',P,{token}},0,{message}),
+ ?line pong = rpc:call(Victim, net_adm, ping, [Offender]),
+ ?line P ! two,
+ ?line P ! check_msgs,
+ ?line receive
+ {P, messages_checked} -> ok
+ after 5000 ->
+ exit(victim_is_dead)
+ end,
+
+ ?line {message_queue_len, 0}
+ = rpc:call(Victim, erlang, process_info, [P, message_queue_len]),
+
+ ?line unlink(P),
+ ?line P ! done,
+ ?line stop_node(Offender),
+ ?line stop_node(Victim),
+ ?t:timetrap_cancel(Dog),
+ ok.
bad_dist_ext(doc) -> [];
bad_dist_ext(suite) ->
@@ -1483,6 +1664,22 @@ bad_dist_ext_connection_id(Config) when is_list(Config) ->
?line stop_node(Victim).
+bad_dist_struct_check_msgs([]) ->
+ receive
+ Msg ->
+ exit({unexpected_message, Msg})
+ after 0 ->
+ ok
+ end;
+bad_dist_struct_check_msgs([M|Ms]) ->
+ receive
+ {'EXIT',_,_} = EM ->
+ io:format("Ignoring exit message: ~p~n",[EM]),
+ bad_dist_struct_check_msgs([M|Ms]);
+ Msg ->
+ M = Msg,
+ bad_dist_struct_check_msgs(Ms)
+ end.
bad_dist_ext_check_msgs([]) ->
receive
Msg ->
@@ -1497,24 +1694,6 @@ bad_dist_ext_check_msgs([M|Ms]) ->
bad_dist_ext_check_msgs(Ms)
end.
--define(COOKIE, '').
--define(DOP_LINK, 1).
--define(DOP_SEND, 2).
--define(DOP_EXIT, 3).
--define(DOP_UNLINK, 4).
--define(DOP_NODE_LINK, 5).
--define(DOP_REG_SEND, 6).
--define(DOP_GROUP_LEADER, 7).
--define(DOP_EXIT2, 8).
-
--define(DOP_SEND_TT, 12).
--define(DOP_EXIT_TT, 13).
--define(DOP_REG_SEND_TT, 16).
--define(DOP_EXIT2_TT, 18).
-
--define(DOP_MONITOR_P, 19).
--define(DOP_DEMONITOR_P, 20).
--define(DOP_MONITOR_P_EXIT, 21).
dport_reg_send(Node, Name, Msg) ->
DPrt = case dport(Node) of
@@ -1546,6 +1725,39 @@ dport_send(To, Msg) ->
?COOKIE,
To}),
dmsg_ext(Msg)]).
+send_bad_structure(Offender,Victim,Bad,WhereToPutSelf) ->
+ send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,[]).
+send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
+ Parent = self(),
+ Done = make_ref(),
+ spawn(Offender,
+ fun () ->
+ Node = node(Victim),
+ pong = net_adm:ping(Node),
+ DPrt = dport(Node),
+ Bad1 = case WhereToPutSelf of
+ 0 ->
+ Bad;
+ N when N > 0 ->
+ setelement(N,Bad,self())
+ end,
+ DData = [dmsg_hdr(),
+ dmsg_ext(Bad1)] ++
+ case PayLoad of
+ [] -> [];
+ _Other -> [dmsg_ext(PayLoad)]
+ end,
+ port_command(DPrt, DData),
+ Parent ! {DData,Done}
+ end),
+ receive
+ {WhatSent,Done} ->
+ io:format("Offender sent ~p~n",[WhatSent]),
+ ok
+ after 5000 ->
+ exit(unable_to_send)
+ end.
+
%% send_bad_msgs():
%% Send a valid distribution header and control message
@@ -1629,10 +1841,10 @@ dmsg_bad_hdr() ->
255]. % 255 atom references
-dmsg_fake_hdr1() ->
- A = <<"fake header atom 1">>,
- [131, % Version Magic
- $D, 1, 16#8, 0, size(A), A]. % Fake header
+%% dmsg_fake_hdr1() ->
+%% A = <<"fake header atom 1">>,
+%% [131, % Version Magic
+%% $D, 1, 16#8, 0, size(A), A]. % Fake header
dmsg_fake_hdr2() ->
A1 = <<"fake header atom 1">>,
@@ -1817,7 +2029,7 @@ flush_node_changes() ->
node_monitor_loop(Master) ->
receive
- {nodeup, Node, InfoList} = Msg ->
+ {nodeup, Node, _InfoList} = Msg ->
Master ! {nodeup, node(), Node},
?t:format("~p ~p: ~p~n", [node(), erlang:now(), Msg]),
node_monitor_loop(Master);
@@ -1854,9 +2066,9 @@ verify_no_down(A, B) ->
ok
end.
-verify_down(A, B) ->
- receive {nodedown, A, B, _} -> ok end,
- receive {nodedown, B, A, _} -> ok end.
+%% verify_down(A, B) ->
+%% receive {nodedown, A, B, _} -> ok end,
+%% receive {nodedown, B, A, _} -> ok end.
verify_down(A, ReasonA, B, ReasonB) ->
receive
@@ -1876,11 +2088,11 @@ from(H, [H | T]) -> T;
from(H, [_ | T]) -> from(H, T);
from(_, []) -> [].
-fun_spawn(Fun) ->
- fun_spawn(Fun, []).
+%% fun_spawn(Fun) ->
+%% fun_spawn(Fun, []).
-fun_spawn(Fun, Args) ->
- spawn_link(erlang, apply, [Fun, Args]).
+%% fun_spawn(Fun, Args) ->
+%% spawn_link(erlang, apply, [Fun, Args]).
long_or_short() ->
diff --git a/erts/emulator/test/erl_link_SUITE.erl b/erts/emulator/test/erl_link_SUITE.erl
index 542c8dffbe..11a7a61586 100644
--- a/erts/emulator/test/erl_link_SUITE.erl
+++ b/erts/emulator/test/erl_link_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% 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
@@ -1050,7 +1050,6 @@ stop_node(Node) ->
-define(DOP_SEND, 2).
-define(DOP_EXIT, 3).
-define(DOP_UNLINK, 4).
--define(DOP_NODE_LINK, 5).
-define(DOP_REG_SEND, 6).
-define(DOP_GROUP_LEADER, 7).
-define(DOP_EXIT2, 8).
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index 466d84bb99..0c72ab977a 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -84,7 +84,7 @@
#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
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 99ccba0686..53b0e0426b 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -938,7 +938,7 @@ int ei_do_receive_msg(int fd, int staticbuffer_p,
return ERL_ERROR;
}
x->index = x->buffsz;
- switch (msg->msgtype) { /* FIXME are these all? */
+ switch (msg->msgtype) { /* FIXME does not handle trace tokens and monitors */
case ERL_SEND:
case ERL_REG_SEND:
case ERL_LINK:
@@ -946,7 +946,6 @@ int ei_do_receive_msg(int fd, int staticbuffer_p,
case ERL_GROUP_LEADER:
case ERL_EXIT:
case ERL_EXIT2:
- case ERL_NODE_LINK:
return ERL_MSG;
default:
diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c
index 7d72ddeeae..86852f947d 100644
--- a/lib/erl_interface/src/connect/eirecv.c
+++ b/lib/erl_interface/src/connect/eirecv.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1998-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
@@ -196,10 +196,6 @@ ei_recv_internal (int fd,
ei_trace(1,&msg->token); /* turn on tracing */
break;
- case ERL_NODE_LINK: /* { NODE_LINK } */
- if (ei_tracelevel >= 4) show_this_msg = 1;
- break;
-
default:
/* unknown type, just put any remaining bytes into buffer */
break;
diff --git a/lib/erl_interface/src/misc/show_msg.c b/lib/erl_interface/src/misc/show_msg.c
index 14bea5e01f..194296798b 100644
--- a/lib/erl_interface/src/misc/show_msg.c
+++ b/lib/erl_interface/src/misc/show_msg.c
@@ -181,11 +181,6 @@ int ei_show_sendmsg(FILE *stream, const char *header, const char *msgbuf)
mbuf = header;
break;
- case ERL_NODE_LINK:
- /* nothing to do */
- mbuf = header;
- break;
-
default:
break;
}
@@ -241,10 +236,6 @@ static void show_msg(FILE *stream, int direction, const erlang_msg *msg,
show_pid(stream,&msg->to);
break;
- case ERL_NODE_LINK:
- fprintf(stream,"NODE_LINK");
- break;
-
case ERL_REG_SEND:
fprintf(stream,"REG_SEND From: ");
show_pid(stream,&msg->from);
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index ed5bf03804..eba95dc6af 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -48,6 +48,7 @@
t_boolean/0,
t_byte/0,
t_char/0,
+ t_charlist/0,
t_cons/0,
t_cons/2,
t_cons_hd/1,
@@ -4517,11 +4518,11 @@ arg_types(os, timestamp, 0) ->
arg_types(re, compile, 1) ->
[t_iodata()];
arg_types(re, compile, 2) ->
- [t_iodata(), t_list(t_re_compile_option())];
+ [t_sup(t_iodata(), t_charlist()), t_list(t_re_compile_option())];
arg_types(re, run, 2) ->
- [t_iodata(), t_re_RE()];
+ [t_sup(t_iodata(), t_charlist()), t_re_RE()];
arg_types(re, run, 3) ->
- [t_iodata(), t_re_RE(), t_list(t_re_run_option())];
+ [t_sup(t_iodata(), t_charlist()), t_re_RE(), t_list(t_re_run_option())];
%%------- string --------------------------------------------------------------
arg_types(string, chars, 2) ->
[t_char(), t_non_neg_integer()];
@@ -4978,8 +4979,7 @@ t_ets_info_items() ->
%% =====================================================================
t_prim_file_name() ->
- t_sup([t_string(),
- t_binary()]).
+ t_sup(t_string(), t_binary()).
%% =====================================================================
%% These are used for the built-in functions of 'gen_tcp'
@@ -5136,13 +5136,14 @@ t_re_MP() -> %% it's supposed to be an opaque data type
t_tuple([t_atom('re_pattern'), t_integer(), t_integer(), t_binary()]).
t_re_RE() ->
- t_sup(t_re_MP(), t_iodata()).
+ t_sup([t_re_MP(), t_iodata(), t_charlist()]).
t_re_compile_option() ->
- t_sup([t_atoms(['anchored', 'caseless', 'dollar_endonly', 'dotall',
- 'extended', 'firstline', 'multiline', 'no_auto_capture',
- 'dupnames', 'ungreedy']),
- t_tuple([t_atom('newline'), t_re_NLSpec()])]).
+ t_sup([t_atoms(['unicode', 'anchored', 'caseless', 'dollar_endonly',
+ 'dotall', 'extended', 'firstline', 'multiline',
+ 'no_auto_capture', 'dupnames', 'ungreedy']),
+ t_tuple([t_atom('newline'), t_re_NLSpec()]),
+ t_atoms(['bsr_anycrlf', 'bsr_unicode'])]).
t_re_run_option() ->
t_sup([t_atoms(['anchored', 'global', 'notbol', 'noteol', 'notempty']),
@@ -5159,7 +5160,7 @@ t_re_Type() ->
t_atoms(['index', 'list', 'binary']).
t_re_NLSpec() ->
- t_atoms(['cr', 'crlf', 'lf', 'anycrlf']).
+ t_atoms(['cr', 'crlf', 'lf', 'anycrlf', 'any']).
t_re_ValueSpec() ->
t_sup(t_atoms(['all', 'all_but_first', 'first', 'none']), t_re_ValueList()).
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 1ed85af172..c8dc162457 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -62,6 +62,7 @@
t_boolean/0,
t_byte/0,
t_char/0,
+ t_charlist/0,
t_collect_vars/1,
t_cons/0,
t_cons/2,
@@ -1455,6 +1456,21 @@ t_is_tuple(_) -> false.
%% Non-primitive types, including some handy syntactic sugar types
%%
+-spec t_charlist() -> erl_type().
+
+t_charlist() ->
+ t_charlist(1).
+
+-spec t_charlist(non_neg_integer()) -> erl_type().
+
+t_charlist(N) when N > 0 ->
+ t_maybe_improper_list(t_sup([t_unicode_char(),
+ t_unicode_binary(),
+ t_charlist(N-1)]),
+ t_sup(t_unicode_binary(), t_nil()));
+t_charlist(0) ->
+ t_maybe_improper_list(t_any(), t_sup(t_unicode_binary(), t_nil())).
+
-spec t_constant() -> erl_type().
t_constant() ->
@@ -1549,6 +1565,16 @@ t_parameterized_module() ->
t_timeout() ->
t_sup(t_non_neg_integer(), t_atom('infinity')).
+-spec t_unicode_binary() -> erl_type().
+
+t_unicode_binary() ->
+ t_binary(). % with characters encoded in UTF-8 coding standard
+
+-spec t_unicode_char() -> erl_type().
+
+t_unicode_char() ->
+ t_integer(). % representing a valid unicode codepoint
+
%%-----------------------------------------------------------------------------
%% Some built-in opaque types
%%
@@ -2825,7 +2851,7 @@ t_subtract(?list(Contents1, Termination1, Size1) = T,
true ->
case {Size1, Size2} of
{?nonempty_qual, ?unknown_qual} -> ?none;
- {?unknown_qual, ?nonempty_qual} -> Termination1;
+ {?unknown_qual, ?nonempty_qual} -> ?nil;
{S, S} -> ?none
end;
false ->
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index 6684547572..5f6c31069c 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -31,6 +31,26 @@
</header>
<section>
+ <title>IC 4.2.26</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Partial support for recursive structs and unions. Only available
+ for the erl_corba backend and requires that Light IFR is used.
+ I.e. the IC option {light_ifr, true} and that Orber is configured
+ in such a way that Light IFR is activated. Recursive TypeCode is
+ currently not supported.</p>
+ <p>
+ Own Id: OTP-8868 Aux Id: seq11633</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>IC 4.2.25</title>
<section>
diff --git a/lib/ic/src/ic_forms.erl b/lib/ic/src/ic_forms.erl
index 7409ddeb7b..fc46a2ed40 100644
--- a/lib/ic/src/ic_forms.erl
+++ b/lib/ic/src/ic_forms.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -65,6 +65,7 @@ get_line(X) when is_record(X, scoped_id) -> X#scoped_id.line;
get_line(X) when is_record(X, module) -> get_line(X#module.id);
get_line(X) when is_record(X, interface) -> get_line(X#interface.id);
get_line(X) when is_record(X, forward) -> get_line(X#forward.id);
+get_line(X) when is_record(X, constr_forward) -> get_line(X#constr_forward.id);
get_line(X) when is_record(X, const) -> get_line(X#const.id);
get_line(X) when is_record(X, typedef) -> get_line(X#typedef.id);
get_line(X) when is_record(X, struct) -> get_line(X#struct.id);
@@ -114,6 +115,7 @@ get_line(_) -> -1.
get_id2(X) when is_record(X, module) -> get_id(X#module.id);
get_id2(X) when is_record(X, interface) -> get_id(X#interface.id);
get_id2(X) when is_record(X, forward) -> get_id(X#forward.id);
+get_id2(X) when is_record(X, constr_forward) -> get_id(X#constr_forward.id);
get_id2(X) when is_record(X, const) -> get_id(X#const.id);
get_id2(X) when is_record(X, typedef) -> get_id(hd(X#typedef.id));
get_id2(X) when is_record(X, struct) -> get_id(X#struct.id);
@@ -156,6 +158,7 @@ get_type(X) when is_record(X, param) -> X#param.type.
%% Temporary place
get_tk(X) when is_record(X, interface) -> X#interface.tk;
get_tk(X) when is_record(X, forward) -> X#forward.tk;
+get_tk(X) when is_record(X, constr_forward) -> X#constr_forward.tk;
get_tk(X) when is_record(X, const) -> X#const.tk;
get_tk(X) when is_record(X, type_dcl) -> X#type_dcl.tk;
get_tk(X) when is_record(X, typedef) -> X#typedef.tk;
@@ -228,6 +231,7 @@ clean_up_scope([N|Ns],Found) ->
get_type_code2(_, _, X) when is_record(X, interface) -> X#interface.tk;
get_type_code2(_, _, X) when is_record(X, forward) -> X#forward.tk;
+get_type_code2(_, _, X) when is_record(X, constr_forward) -> X#constr_forward.tk;
get_type_code2(_, _, X) when is_record(X, const) -> X#const.tk;
get_type_code2(_, _, X) when is_record(X, type_dcl) -> X#type_dcl.tk;
get_type_code2(_, _, X) when is_record(X, typedef) ->
diff --git a/lib/ic/src/ic_pragma.erl b/lib/ic/src/ic_pragma.erl
index 9165e3b03b..45cb64c9c8 100644
--- a/lib/ic/src/ic_pragma.erl
+++ b/lib/ic/src/ic_pragma.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -60,7 +60,7 @@ pragma_reg(G,X) ->
init_pragma_status(S),
registerOptions(G,S),
pragma_reg_all(G, S, [], X),
- denote_specific_code_opts(G), %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ denote_specific_code_opts(G),
case get_pragma_compilation_status(S) of
true ->
%% Remove ugly pragmas from form
@@ -132,6 +132,7 @@ applyCodeOpt(G) ->
%% This removes all pragma records from the form.
%% When debugged, it can be enbodied in pragma_reg_all.
+cleanup(undefined,C) -> C;
cleanup([],C) -> C;
cleanup([X|Xs],CSF) ->
cleanup(Xs, CSF++cleanup(X)).
@@ -279,7 +280,12 @@ pragma_reg(G, S, N, X) when is_record(X, union) ->
pragma_reg(G, S, N, X) when is_record(X, struct) ->
mk_ref(G,[get_id2(X) | N],struct_ref),
mk_file_data(G,X,N,struct),
- pragma_reg_all(G, S, N, X#struct.body);
+ case X#struct.body of
+ undefined ->
+ ok;
+ _ ->
+ pragma_reg_all(G, S, N, X#struct.body)
+ end;
pragma_reg(G, _S, N, X) when is_record(X, attr) ->
XX = #id_of{type=X},
diff --git a/lib/ic/src/ic_symtab.erl b/lib/ic/src/ic_symtab.erl
index 889c75e3a2..d710154a5d 100644
--- a/lib/ic/src/ic_symtab.erl
+++ b/lib/ic/src/ic_symtab.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -69,6 +69,8 @@ store(G, N, X) ->
ets:insert(G#genobj.symtab, {Name, X});
{ok, Y} when is_record(Y, forward) ->
ets:insert(G#genobj.symtab, {Name, X});
+ {ok, Y} when is_record(Y, constr_forward) ->
+ ets:insert(G#genobj.symtab, {Name, X});
{ok, _Y} ->
ic_error:error(G, {multiply_defined, X})
end.
diff --git a/lib/ic/src/icforms.hrl b/lib/ic/src/icforms.hrl
index d1869e6330..1b394a11b4 100644
--- a/lib/ic/src/icforms.hrl
+++ b/lib/ic/src/icforms.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -34,6 +34,7 @@
-record(module, {id, body}).
-record(interface, {id, inherit, body, inherit_body, tk}).
-record(forward, {id, tk}).
+-record(constr_forward, {id, tk}).
-record(const, {type, id, val, tk}).
-record(type_dcl, {type, tk}).
-record(typedef, {type, id, tk}).
diff --git a/lib/ic/src/icparse.yrl b/lib/ic/src/icparse.yrl
index 25b0f452e7..d0dd6cde4c 100644
--- a/lib/ic/src/icparse.yrl
+++ b/lib/ic/src/icparse.yrl
@@ -1,21 +1,20 @@
-%%<copyright>
-%% <year>1997-2007</year>
-%% <holder>Ericsson AB, All Rights Reserved</holder>
-%%</copyright>
-%%<legalnotice>
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-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.
-%%
-%% The Initial Developer of the Original Code is Ericsson AB.
-%%</legalnotice>
+%%
+%% %CopyrightEnd%
%%
%%------------------------------------------------------------
%% Yecc spec for IDL
@@ -150,6 +149,7 @@ Nonterminals
'ZorM_<integer_literal>'
'<fixed_pt_type>'
'<fixed_pt_const_type>'
+ '<constr_forward_decl>'
.
@@ -473,6 +473,7 @@ OE_preproc -> '#' '<integer_literal>' '<string_literal>'
'<type_dcl>' -> '<struct_type>' : '$1' .
'<type_dcl>' -> '<union_type>' : '$1' .
'<type_dcl>' -> '<enum_type>' : '$1' .
+'<type_dcl>' -> '<constr_forward_decl>' : '$1' .
%% (28) NIY multiple declarators (FIXED)
'<type_declarator>' -> '<type_spec>' '<declarators>'
@@ -832,6 +833,9 @@ OE_preproc -> '#' '<integer_literal>' '<string_literal>'
'<fixed_pt_type>' -> 'fixed' '<' '<positive_int_const>' ',' '<positive_int_const>' '>'
: #fixed{digits='$3',scale='$5'} .
+%% (99)
+'<constr_forward_decl>' -> 'struct' '<identifier>' : #constr_forward{id='$2', tk=tk_struct} .
+'<constr_forward_decl>' -> 'union' '<identifier>' : #constr_forward{id='$2', tk=tk_union} .
%% Added clause
'ZorM_<string_literal>' -> '$empty' : [] .
diff --git a/lib/ic/src/ictype.erl b/lib/ic/src/ictype.erl
index 4704191bee..9e20801464 100644
--- a/lib/ic/src/ictype.erl
+++ b/lib/ic/src/ictype.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -407,6 +407,18 @@ check(G, S, N, X) when is_record(X, forward) ->
tktab_add(G, S, N, X, {tk_objref, ictk:get_IR_ID(G, N, X), ic_forms:get_id2(X)}),
X;
+check(G, S, N, #constr_forward{tk = tk_struct} = X) ->
+ ?STDDBG,
+ ID = ic_forms:get_id2(X),
+ Module = list_to_atom(string:join(lists:reverse([ID|N]), "_")),
+ tktab_add(G, S, N, X, {tk_struct, ictk:get_IR_ID(G, N, X), ID, Module}),
+ X;
+check(G, S, N, #constr_forward{tk = tk_union} = X) ->
+ ?STDDBG,
+ ID = ic_forms:get_id2(X),
+ Module = list_to_atom(string:join(lists:reverse([ID|N]), "_")),
+ tktab_add(G, S, N, X, {tk_union, ictk:get_IR_ID(G, N, X), ID, [], [], Module}),
+ X;
check(G, S, N, X) when is_record(X, const) ->
?STDDBG,
@@ -427,21 +439,6 @@ check(G, S, N, X) when is_record(X, const) ->
end
end;
-check(G, S, N, X) when is_record(X, const) ->
- ?STDDBG,
- case tk_base(G, S, N, ic_forms:get_type(X)) of
- Err when element(1, Err) == error -> X;
- TK ->
- check_const_tk(G, S, N, X, TK),
- case iceval:eval_const(G, S, N, TK, X#const.val) of
- Err when element(1, Err) == error -> X;
- Val ->
- V = iceval:get_val(Val),
- tktab_add(G, S, N, X, TK, V),
- X#const{val=V, tk=TK}
- end
- end;
-
check(G, S, N, X) when is_record(X, except) ->
?STDDBG,
TK = tk(G, S, N, X),
@@ -795,9 +792,15 @@ tktab_add_id(G, S, N, X, Id, TK, Aux) ->
Name = [Id | N],
UName = mk_uppercase(Name),
case ets:lookup(S, Name) of
- [{_, forward, _, _}] when is_record(X, interface) -> ok;
- [XX] when is_record(X, forward) andalso element(2, XX)==interface -> ok;
- [_] -> ic_error:error(G, {multiply_defined, X});
+ [{_, forward, _, _}] when is_record(X, interface) ->
+ ok;
+ [{_, constr_forward, _, _}] when is_record(X, union) orelse
+ is_record(X, struct) ->
+ ok;
+ [XX] when is_record(X, forward) andalso element(2, XX)==interface ->
+ ok;
+ [_] ->
+ ic_error:error(G, {multiply_defined, X});
[] ->
case ets:lookup(S, UName) of
[] -> ok;
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index 074d0b3d39..6d6c7fa625 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1 +1 @@
-IC_VSN = 4.2.25
+IC_VSN = 4.2.26
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
index ab0b299bf9..9ba6a4a0ab 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/AbstractConnection.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
+ * 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
@@ -68,7 +68,6 @@ public abstract class AbstractConnection extends Thread {
protected static final int sendTag = 2;
protected static final int exitTag = 3;
protected static final int unlinkTag = 4;
- protected static final int nodeLinkTag = 5;
protected static final int regSendTag = 6;
protected static final int groupLeaderTag = 7;
protected static final int exit2Tag = 8;
@@ -697,7 +696,6 @@ public abstract class AbstractConnection extends Thread {
// absolutely no idea what to do with these, so we ignore
// them...
case groupLeaderTag: // { GROUPLEADER, FromPid, ToPid}
- case nodeLinkTag: // { NODELINK }
// (just show trace)
if (traceLevel >= ctrlThreshold) {
System.out.println("<- " + headerType(head) + " "
@@ -880,9 +878,6 @@ public abstract class AbstractConnection extends Thread {
case unlinkTag:
return "UNLINK";
- case nodeLinkTag:
- return "NODELINK";
-
case regSendTag:
return "REG_SEND";
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
index 80d8a5ccae..6f507bf4bb 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMsg.java
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
+ * 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
@@ -54,7 +54,6 @@ public class OtpMsg {
public static final int sendTag = 2;
public static final int exitTag = 3;
public static final int unlinkTag = 4;
- /* public static final int nodeLinkTag = 5; */
public static final int regSendTag = 6;
/* public static final int groupLeaderTag = 7; */
public static final int exit2Tag = 8;
diff --git a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
index a97ad65f0e..964ae3e92d 100644
--- a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
+++ b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -445,7 +445,19 @@ void op(in myEnum a);</cell>
<section>
<title>Struct Data Type</title>
<p>A <c>struct</c> may have Basic, Template, Scoped Names and Constructed
- types as members.</p>
+ types as members. By using forward declaration we can define a recursive struct:</p>
+ <code type="none"><![CDATA[
+struct myStruct; // Forward declaration
+typedef sequence<myStruct> myStructSeq;
+struct myStruct {
+ myStructSeq chain;
+};
+
+// Deprecated definition (anonymous) not supported by IC
+struct myStruct {
+ sequence<myStruct> chain;
+};
+ ]]></code>
</section>
<section>
@@ -510,6 +522,25 @@ union LongUnion2 switch(long) {
default: boolean DefaultValue;
};
</code>
+ <p>In the same way as structs, unions can be recursive if forward
+ declaration is used (anonymous types is deprecated and not supported):</p>
+ <code type="none"><![CDATA[
+// Forward declaration
+union myUnion;
+typedef sequence<myUnion>myUnionSeq;
+union myUnion switch (long) {
+ case 1 : myUnionSeq chain;
+ default: boolean DefaultValue;
+};
+ ]]></code>
+
+ <note>
+ <p>Recursive types (union and struct) require Light IFR. I.e. the
+ IC option {light_ifr, true} is used and that Orber is configured in such a way that
+ Light IFR is activated. Recursive TypeCode is currently not supported, which is
+ why these cannot be encapsulated in an any data type.</p>
+ </note>
+
</section>
<warning>
<p>Every field in, for example, a struct must be initiated. Otherwise
@@ -890,7 +921,7 @@ attribute long RWAttribute;
object internal state with its object reference. The object internal state is
an Erlang term which has a format defined by the user.</p>
<note>
- <p>It is is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
+ <p>It is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
</note>
<p>A function call will invoke an operation. The first
parameter of the function should be the object reference and then
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 6eda16a517..ba16682f0b 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -33,6 +33,36 @@
</header>
<section>
+ <title>Orber 3.6.19</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Partial support for recursive structs and unions.
+ Only available for the erl_corba backend and requires
+ that Light IFR is used. I.e. the IC option {light_ifr, true}
+ and that Orber is configured in such a way that Light IFR
+ is activated. Recursive TypeCode is currently not supported.</p>
+ <p>
+ Own Id: OTP-8868 Aux Id: seq11633</p>
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The SSL option {ssl_imp, old} was not used if ssl_generation was
+ set to 2. Only R14B was affected by this.</p>
+ <p>Own Id: OTP-8994 Aux Id: seq11747</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>Orber 3.6.18</title>
<section>
<title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/orber/src/cdr_decode.erl b/lib/orber/src/cdr_decode.erl
index 9d30098940..36ef6ce02f 100644
--- a/lib/orber/src/cdr_decode.erl
+++ b/lib/orber/src/cdr_decode.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -898,9 +898,13 @@ dec_sequence_struct(Version, Message, N, TypeCodeList, Len, ByteOrder, Buff, C,
{Seq, Rest2, Len2, NewC2} = dec_sequence_struct(Version, Rest1, N - 1, TypeCodeList, Len1, ByteOrder,
Buff, NewC, Name),
{[list_to_tuple([Name |Struct]) | Seq], Rest2, Len2, NewC2}.
-dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList, Len, _ByteOrder, _Buff, C, _Name) ->
+
+
+dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList,
+ Len, _ByteOrder, _Buff, C, _Name) ->
{[], Message, Len, C};
-dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, Len, ByteOrder, Buff, C, Name) ->
+dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList,
+ Len, ByteOrder, Buff, C, Name) when is_list(ElementList) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Message, Len, ByteOrder, Buff, C),
Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default,
@@ -916,7 +920,20 @@ dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, Len, Byte
DiscrTC, Default, ElementList,
Len2, ByteOrder,
Buff, NewC3, Name),
- {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4}.
+ {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4};
+dec_sequence_union(Version, Message, N, _DiscrTC, _Default, Module,
+ Len, ByteOrder, Buff, C, Name) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, _, DiscrTC, Default, ElementList} ->
+ dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList,
+ Len, ByteOrder, Buff, C, Name);
+ What ->
+ orber:dbg("[~p] ~p:dec_sequence_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
+
+
%% A special case; when something is encapsulated (i.e. sent as octet-sequence)
%% we sometimes don not want the result to be converted to a list.
@@ -993,14 +1010,16 @@ dec_wstring(Version, Message, Len, ByteOrder, Buff, C) ->
%% Func: dec_union/9
%%-----------------------------------------------------------------
%% ## NEW IIOP 1.2 ##
-dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C) ->
+dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes,
+ Len, ByteOrder, Buff, C) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C),
{Value, Rest2, Len2, NewC3} = dec_union(Version, Label, ElementList, Default,
Rest1, Len1, ByteOrder, Buff, NewC),
{{Name, Label, Value}, Rest2, Len2, NewC3};
-dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C) ->
+dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len,
+ ByteOrder, Buff, C) when is_list(ElementList) ->
{Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C),
Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default,
Rest1, Len1, ByteOrder, Buff, NewC),
@@ -1012,7 +1031,20 @@ dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, ByteOrde
X
end,
Name = ifrid_to_name(IFRId, ?IFR_UnionDef),
- {{Name, Label, Value}, Rest2, Len2, NewC3}.
+ {{Name, Label, Value}, Rest2, Len2, NewC3};
+dec_union(Version, IFRId, _, _DiscrTC, _Default, Module, Bytes, Len,
+ ByteOrder, Buff, C) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, Name, DiscrTC, Default, ElementList} ->
+ dec_union(Version, IFRId, Name, DiscrTC, Default, ElementList, Bytes, Len,
+ ByteOrder, Buff, C);
+ What ->
+ orber:dbg("[~p] ~p:dec_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
+
+
dec_union(_, _, [], Default, Message, Len, _, _Buff, C) when Default < 0 ->
{undefined, Message, Len, C};
@@ -1047,7 +1079,16 @@ dec_struct1(_, [], Message, Len, _ByteOrder, _, C) ->
dec_struct1(Version, [{_ElemName, ElemType} | TypeCodeList], Message, Len, ByteOrder, Buff, C) ->
{Element, Rest, Len1, NewC} = dec_type(ElemType, Version, Message, Len, ByteOrder, Buff, C),
{Struct, Rest1, Len2, NewC2} = dec_struct1(Version, TypeCodeList, Rest, Len1, ByteOrder, Buff, NewC),
- {[Element |Struct], Rest1, Len2, NewC2}.
+ {[Element |Struct], Rest1, Len2, NewC2};
+dec_struct1(Version, Module, Message, Len, ByteOrder, Buff, C) ->
+ case catch Module:tc() of
+ {tk_struct, _, _, TypeCodeList} ->
+ dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C);
+ What ->
+ orber:dbg("[~p] ~p:dec_struct1(~p). Struct module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
ifrid_to_name([], Type) ->
orber:dbg("[~p] ~p:ifrid_to_name([], ~p). No Id supplied.",
@@ -1232,7 +1273,9 @@ get_user_exception_type(TypeId) ->
%%-----------------------------------------------------------------
dec_type_code(Version, Message, Len, ByteOrder, Buff, C) ->
{TypeNo, Message1, Len1, NewC} = dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C),
- dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC).
+ TC = dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC),
+ erase(orber_indirection),
+ TC.
%%-----------------------------------------------------------------
%% Func: dec_type_code/5
@@ -1441,13 +1484,22 @@ dec_type_code(33, Version, Message, Len, ByteOrder, Buff, C) ->
{"name", {'tk_string', 0}}]},
Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex),
{{'tk_local_interface', RepId, Name}, Message1, Len1, NewC};
-dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) -> %% placeholder
+dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) ->
{Indirection, Message1, Len1, NewC} =
dec_type('tk_long', Version, Message, Len, ByteOrder, Buff, C),
Position = C+Indirection,
- <<_:Position/binary, SubBuff/binary>> = Buff,
- {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position),
- {TC, Message1, Len1, NewC};
+ case put(orber_indirection, Position) of
+ Position ->
+%% {{'none', Indirection}, Message1, Len1, NewC};
+ %% Recursive TypeCode. Break the loop.
+ orber:dbg("[~p] cdr_decode:dec_type_code(~p); Recursive TC not supported.",
+ [?LINE,Position], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO});
+ _ ->
+ <<_:Position/binary, SubBuff/binary>> = Buff,
+ {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position),
+ {TC, Message1, Len1, NewC}
+ end;
dec_type_code(Type, _, _, _, _, _, _) ->
orber:dbg("[~p] cdr_decode:dec_type_code(~p); No match.",
[?LINE, Type], ?DEBUG_LEVEL),
diff --git a/lib/orber/src/cdr_encode.erl b/lib/orber/src/cdr_encode.erl
index 3ecb8833f5..eaf3c5b7dc 100644
--- a/lib/orber/src/cdr_encode.erl
+++ b/lib/orber/src/cdr_encode.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -815,11 +815,21 @@ enc_wstring(Env, String, MaxLength, Bytes, Len) ->
%%-----------------------------------------------------------------
%% Func: enc_union/5
%%-----------------------------------------------------------------
-enc_union(Env, {_, Label, Value}, DiscrTC, Default, TypeCodeList, Bytes, Len) ->
+enc_union(Env, {_, Label, Value}, DiscrTC, Default, TypeCodeList,
+ Bytes, Len) when is_list(TypeCodeList) ->
{ByteSequence, Len1} = enc_type(DiscrTC, Env, Label, Bytes, Len),
Label2 = stringify_enum(DiscrTC,Label),
enc_union2(Env, {Label2, Value},TypeCodeList, Default,
- ByteSequence, Len1, undefined).
+ ByteSequence, Len1, undefined);
+enc_union(Env, Value, _DiscrTC, _Default, Module, Bytes, Len) when is_atom(Module) ->
+ case catch Module:tc() of
+ {tk_union, _, _, DiscrTC, Default, ElementList} ->
+ enc_union(Env, Value, DiscrTC, Default, ElementList, Bytes, Len);
+ What ->
+ orber:dbg("[~p] ~p:enc_union(~p). Union module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
enc_union2(_Env, _What, [], Default, Bytes, Len, _) when Default < 0 ->
{Bytes, Len};
@@ -840,9 +850,19 @@ stringify_enum(_, Label) ->
%%-----------------------------------------------------------------
%% Func: enc_struct/4
%%-----------------------------------------------------------------
-enc_struct(Env, Struct, TypeCodeList, Bytes, Len) ->
+enc_struct(Env, Struct, TypeCodeList, Bytes, Len) when is_list(TypeCodeList) ->
[_Name | StructList] = tuple_to_list(Struct),
- enc_struct1(Env, StructList, TypeCodeList, Bytes, Len).
+ enc_struct1(Env, StructList, TypeCodeList, Bytes, Len);
+enc_struct(Env, Struct, Module, Bytes, Len) ->
+ [Module | StructList] = tuple_to_list(Struct),
+ case catch Module:tc() of
+ {tk_struct, _, _, TypeCodeList} ->
+ enc_struct1(Env, StructList, TypeCodeList, Bytes, Len);
+ What ->
+ orber:dbg("[~p] ~p:enc_struct([], ~p). Struct module doesn't exist or incorrect.",
+ [?LINE, ?MODULE, What], ?DEBUG_LEVEL),
+ corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE})
+ end.
enc_struct1(_Env, [], [], Bytes, Len) ->
{Bytes, Len};
diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl
index af6df01b7d..84ed193ebb 100644
--- a/lib/orber/src/orber_socket.erl
+++ b/lib/orber/src/orber_socket.erl
@@ -496,27 +496,17 @@ check_port(Port, _, _) ->
%%-----------------------------------------------------------------
%% Check Options.
-%% We need this as a work-around since the SSL-app doesn't allow us
-%% to pass 'inet' as an option. Also needed for R9B :-(
check_options(normal, Options, _Generation) ->
- case orber:ip_version() of
- inet ->
- Options;
- inet6 ->
- %% Necessary for R9B. Should be [orber:ip_version()|Options];
- [inet6|Options]
- end;
+ [orber:ip_version()|Options];
check_options(ssl, Options, Generation) ->
case orber:ip_version() of
inet when Generation > 2 ->
[{ssl_imp, new}|Options];
inet ->
- Options;
+ [{ssl_imp, old}|Options];
inet6 when Generation > 2 ->
[{ssl_imp, new}, inet6|Options];
inet6 ->
- %% Will fail until SSL supports this option.
- %% Note, we want this happen!
- [inet6|Options]
+ [{ssl_imp, old}, inet6|Options]
end.
diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile
index 4601e84d2c..5495735318 100644
--- a/lib/orber/test/Makefile
+++ b/lib/orber/test/Makefile
@@ -120,7 +120,11 @@ GEN_MOD_TEST_SERVER = \
orber_test_server_uni \
orber_test_server_uni_d \
orber_test_timeout_server \
- orber_parent_inherrit
+ orber_parent_inherrit \
+ orber_test_server_rec_struct \
+ orber_test_server_rec_struct_seq \
+ orber_test_server_rec_union \
+ orber_test_server_rec_union_seq
GEN_HRL_TEST_SERVER = \
oe_orber_test_server.hrl \
diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl
index a694dc58c4..b95cf4b0ec 100644
--- a/lib/orber/test/orber_test_lib.erl
+++ b/lib/orber/test/orber_test_lib.erl
@@ -1280,6 +1280,22 @@ test_coding(Obj, Local) ->
?match({'EXCEPTION',{'MARSHAL',_,_,_}},
orber_test_server:
testing_iiop_server_marshal(Obj, "string")),
+
+ RecS = #orber_test_server_rec_struct{chain = [#orber_test_server_rec_struct{chain = []}]},
+ ?match(RecS, orber_test_server:testing_iiop_rec_struct(Obj, RecS)),
+
+ RecU = #orber_test_server_rec_union{label = 'RecursiveType',
+ value = [#orber_test_server_rec_union{label = 'RecursiveType',
+ value = []}]},
+ ?match(RecU, orber_test_server:testing_iiop_rec_union(Obj, RecU)),
+
+%% RecA1 = #any{typecode = unsupported, value = RecS},
+%% RecA2 = #any{typecode = unsupported, value = RecU},
+%% ?match(RecA1,
+%% orber_test_server:testing_iiop_rec_any(Obj, RecA1)),
+%% ?match(RecA2,
+%% orber_test_server:testing_iiop_rec_any(Obj, RecA2)),
+
ok.
%%--------------- Testing Post- & Pre-cond -------------------
diff --git a/lib/orber/test/orber_test_server.idl b/lib/orber/test/orber_test_server.idl
index a88211c941..438c10e19b 100644
--- a/lib/orber/test/orber_test_server.idl
+++ b/lib/orber/test/orber_test_server.idl
@@ -28,7 +28,7 @@ module orber_parent {
};
module orber_test {
-
+
// interface server
interface server : orber_parent::inherrit {
typedef string array[2];
@@ -89,6 +89,23 @@ module orber_test {
const fixed52 fixed52negconst2 = -123.00d;
const fixed52 fixed52negconst3 = -023.00d;
+ struct rec_struct; // Forward declaration
+ typedef sequence<rec_struct> rec_struct_seq;
+ struct rec_struct {
+ rec_struct_seq chain;
+ };
+
+
+ union rec_union; // Forward declaration
+ typedef sequence<rec_union>rec_union_seq;
+
+ enum MyEnum {RecursiveType, NameType};
+
+ union rec_union switch (MyEnum) {
+ case RecursiveType : rec_union_seq chain;
+ case NameType : string aName;
+ };
+
void stop_normal();
void stop_brutal();
@@ -123,6 +140,12 @@ module orber_test {
void testing_iiop_context();
void testing_iiop_server_marshal(inout StrLength6 Str);
+ // Recursive types
+ any testing_iiop_rec_any(in any RecType);
+ rec_struct testing_iiop_rec_struct(in rec_struct RecS);
+ rec_union testing_iiop_rec_union(in rec_union RecU);
+
+
oneway void testing_iiop_oneway_delay(in long Time);
void testing_iiop_twoway_delay(in long Time);
diff --git a/lib/orber/test/orber_test_server_impl.erl b/lib/orber/test/orber_test_server_impl.erl
index 35296cb619..10a9caf242 100644
--- a/lib/orber/test/orber_test_server_impl.erl
+++ b/lib/orber/test/orber_test_server_impl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -55,6 +55,9 @@
testing_iiop_void/2,
testing_iiop_context/2,
testing_iiop_server_marshal/3,
+ testing_iiop_rec_any/3,
+ testing_iiop_rec_struct/3,
+ testing_iiop_rec_union/3,
relay_call/3,
relay_cast/3,
%% Testing pseudo calls.
@@ -197,6 +200,16 @@ testing_iiop_context(_Self, State) ->
testing_iiop_server_marshal(_Self, State, _String) ->
{reply, {ok, false}, State}.
+testing_iiop_rec_any(_Self, State, RAny) ->
+ {reply, RAny, State}.
+
+testing_iiop_rec_struct(_Self, State, RecS) ->
+ {reply, RecS, State}.
+
+testing_iiop_rec_union(_Self, State, RecU) ->
+ {reply, RecU, State}.
+
+
testing_iiop_oneway_delay(_Self, State, Time) ->
timer:sleep(Time),
{noreply, State}.
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index 584a52ab84..b0c5a253a2 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1 +1 @@
-ORBER_VSN = 3.6.18
+ORBER_VSN = 3.6.19