aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/erl_interface/src')
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c44
-rw-r--r--lib/erl_interface/src/connect/ei_connect_int.h11
-rw-r--r--lib/erl_interface/src/connect/ei_resolve.c4
-rw-r--r--lib/erl_interface/src/connect/eirecv.c20
-rw-r--r--lib/erl_interface/src/connect/send.c3
-rw-r--r--lib/erl_interface/src/connect/send_exit.c3
-rw-r--r--lib/erl_interface/src/connect/send_reg.c3
-rw-r--r--lib/erl_interface/src/decode/decode_atom.c2
-rw-r--r--lib/erl_interface/src/decode/decode_big.c2
-rw-r--r--lib/erl_interface/src/decode/decode_double.c30
-rw-r--r--lib/erl_interface/src/decode/decode_pid.c2
-rw-r--r--lib/erl_interface/src/decode/decode_port.c2
-rw-r--r--lib/erl_interface/src/decode/decode_ref.c3
-rw-r--r--lib/erl_interface/src/decode/decode_skip.c11
-rw-r--r--lib/erl_interface/src/encode/encode_double.c20
-rw-r--r--lib/erl_interface/src/epmd/ei_epmd.h11
-rw-r--r--lib/erl_interface/src/epmd/epmd_port.c77
-rw-r--r--lib/erl_interface/src/epmd/epmd_publish.c74
-rw-r--r--lib/erl_interface/src/epmd/epmd_unpublish.c5
-rw-r--r--lib/erl_interface/src/legacy/decode_term.c11
-rw-r--r--lib/erl_interface/src/legacy/erl_connect.c7
-rw-r--r--lib/erl_interface/src/legacy/erl_format.c2
-rw-r--r--lib/erl_interface/src/legacy/erl_marshal.c174
-rw-r--r--lib/erl_interface/src/legacy/erl_timeout.c2
-rw-r--r--lib/erl_interface/src/legacy/global_register.c12
-rw-r--r--lib/erl_interface/src/legacy/global_unregister.c12
-rw-r--r--lib/erl_interface/src/misc/ei_decode_term.c29
-rw-r--r--lib/erl_interface/src/misc/ei_format.c22
-rw-r--r--lib/erl_interface/src/misc/ei_portio.c5
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c14
-rw-r--r--lib/erl_interface/src/misc/get_type.c17
-rw-r--r--lib/erl_interface/src/misc/putget.h38
-rw-r--r--lib/erl_interface/src/misc/show_msg.c20
-rw-r--r--lib/erl_interface/src/prog/erl_call.c168
-rw-r--r--lib/erl_interface/src/registry/reg_dump.c4
-rw-r--r--lib/erl_interface/src/registry/reg_restore.c2
36 files changed, 431 insertions, 435 deletions
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index d2d0a7e7c1..6dc6ebb348 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
/*
@@ -366,16 +366,16 @@ static int initWinSock(void)
WORD wVersionRequested;
WSADATA wsaData;
int i;
- /* FIXME problem for threaded ? */
- static int initialized = 0;
+
+ static LONG volatile initialized = 0;
wVersionRequested = MAKEWORD(1, 1);
- if (!initialized) {
- initialized = 1;
+ if (InterlockedCompareExchange((LPLONG) &initialized,1L,0L) == 0L) {
/* FIXME not terminate, just a message?! */
if ((i = WSAStartup(wVersionRequested, &wsaData))) {
EI_TRACE_ERR1("ei_connect_init",
"ERROR: can't initialize windows sockets: %d",i);
+ initialized = 2L;
return 0;
}
@@ -383,10 +383,14 @@ static int initWinSock(void)
EI_TRACE_ERR0("initWinSock","ERROR: this version of windows "
"sockets not supported");
WSACleanup();
+ initialized = 2L;
return 0;
}
+ initialized = 3L;
+ } else while (initialized < 2) {
+ SwitchToThread();
}
- return 1;
+ return (int) (initialized - 2);
}
#endif
@@ -502,10 +506,14 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name,
return ERL_ERROR;
}
- if (this_node_name == NULL)
+ if (this_node_name == NULL) {
sprintf(thisalivename, "c%d", (int) getpid());
- else
+ } else if (strlen(this_node_name) >= sizeof(thisalivename)) {
+ EI_TRACE_ERR0("ei_connect_init","ERROR: this_node_name too long");
+ return ERL_ERROR;
+ } else {
strcpy(thisalivename, this_node_name);
+ }
if ((hp = ei_gethostbyname(thishostname)) == 0) {
/* Looking up IP given hostname fails. We must be on a standalone
@@ -930,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:
@@ -938,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:
@@ -1321,9 +1328,11 @@ 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));
+ | DFLAG_NEW_FUN_TAGS
+ | DFLAG_NEW_FLOATS));
if (f_chall)
put32be(s, challenge);
memcpy(s, nodename, strlen(nodename));
@@ -1393,6 +1402,11 @@ static int recv_challenge(int fd, unsigned *challenge,
goto error;
}
+ if (!(*flags & DFLAG_NEW_FLOATS)) {
+ EI_TRACE_ERR0("recv_challenge","<- RECV_CHALLENGE peer cannot "
+ "handle binary float encoding");
+ goto error;
+ }
if (getpeername(fd, (struct sockaddr *) &sin, &sin_len) < 0) {
EI_TRACE_ERR0("recv_challenge","<- RECV_CHALLENGE can't get peername");
diff --git a/lib/erl_interface/src/connect/ei_connect_int.h b/lib/erl_interface/src/connect/ei_connect_int.h
index 9926f799df..3c42b49b82 100644
--- a/lib/erl_interface/src/connect/ei_connect_int.h
+++ b/lib/erl_interface/src/connect/ei_connect_int.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*/
/*
@@ -101,6 +101,7 @@ extern int h_errno;
#define DFLAG_FUN_TAGS 16
#define DFLAG_NEW_FUN_TAGS 0x80
#define DFLAG_EXTENDED_PIDS_PORTS 0x100
+#define DFLAG_NEW_FLOATS 0x800
ei_cnode *ei_fd_to_cnode(int fd);
int ei_distversion(int fd);
diff --git a/lib/erl_interface/src/connect/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c
index 42aeab22b1..24a030c468 100644
--- a/lib/erl_interface/src/connect/ei_resolve.c
+++ b/lib/erl_interface/src/connect/ei_resolve.c
@@ -601,7 +601,7 @@ struct hostent *ei_gethostbyaddr_r(const char *addr,
#ifndef HAVE_GETHOSTBYNAME_R
return my_gethostbyaddr_r(addr,length,type,hostp,buffer,buflen,h_errnop);
#else
-#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000))
+#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__))
struct hostent *result;
gethostbyaddr_r(addr, length, type, hostp, buffer, buflen, &result,
@@ -628,7 +628,7 @@ struct hostent *ei_gethostbyname_r(const char *name,
#ifndef HAVE_GETHOSTBYNAME_R
return my_gethostbyname_r(name,hostp,buffer,buflen,h_errnop);
#else
-#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000))
+#if (defined(__GLIBC__) || (__FreeBSD_version >= 602000) || defined(__DragonFly__))
struct hostent *result;
gethostbyname_r(name, hostp, buffer, buflen, &result, h_errnop);
diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c
index 51fc32d65c..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
@@ -107,7 +107,7 @@ ei_recv_internal (int fd,
switch (msg->msgtype) {
case ERL_SEND: /* { SEND, Cookie, ToPid } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_pid(header,&index,&msg->to))
{
@@ -118,7 +118,7 @@ ei_recv_internal (int fd,
break;
case ERL_REG_SEND: /* { REG_SEND, From, Cookie, ToName } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_atom(header,&index,msg->toname))
@@ -133,7 +133,7 @@ ei_recv_internal (int fd,
case ERL_LINK: /* { LINK, From, To } */
case ERL_UNLINK: /* { UNLINK, From, To } */
case ERL_GROUP_LEADER: /* { GROUP_LEADER, From, To } */
- if (ei_tracelevel > 1) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_pid(header,&index,&msg->to))
{
@@ -145,7 +145,7 @@ ei_recv_internal (int fd,
case ERL_EXIT: /* { EXIT, From, To, Reason } */
case ERL_EXIT2: /* { EXIT2, From, To, Reason } */
- if (ei_tracelevel > 1) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_pid(header,&index,&msg->to))
{
@@ -156,7 +156,7 @@ ei_recv_internal (int fd,
break;
case ERL_SEND_TT: /* { SEND_TT, Cookie, ToPid, TraceToken } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_pid(header,&index,&msg->to)
|| ei_decode_trace(header,&index,&msg->token))
@@ -169,7 +169,7 @@ ei_recv_internal (int fd,
break;
case ERL_REG_SEND_TT: /* { REG_SEND_TT, From, Cookie, ToName, TraceToken } */
- if (ei_tracelevel > 0) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_atom(header,&index,msg->cookie)
|| ei_decode_atom(header,&index,msg->toname)
@@ -184,7 +184,7 @@ ei_recv_internal (int fd,
case ERL_EXIT_TT: /* { EXIT_TT, From, To, TraceToken, Reason } */
case ERL_EXIT2_TT: /* { EXIT2_TT, From, To, TraceToken, Reason } */
- if (ei_tracelevel > 1) show_this_msg = 1;
+ if (ei_tracelevel >= 4) show_this_msg = 1;
if (ei_decode_pid(header,&index,&msg->from)
|| ei_decode_pid(header,&index,&msg->to)
|| ei_decode_trace(header,&index,&msg->token))
@@ -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 > 1) show_this_msg = 1;
- break;
-
default:
/* unknown type, just put any remaining bytes into buffer */
break;
diff --git a/lib/erl_interface/src/connect/send.c b/lib/erl_interface/src/connect/send.c
index cd832db4ea..57e32903cf 100644
--- a/lib/erl_interface/src/connect/send.c
+++ b/lib/erl_interface/src/connect/send.c
@@ -87,8 +87,7 @@ int ei_send_encoded_tmo(int fd, const erlang_pid *to,
put8(s, ERL_PASS_THROUGH); /* 1 */
/*** sum: 1070 */
- /* FIXME incorrect level */
- if (ei_tracelevel > 0)
+ if (ei_tracelevel >= 4)
ei_show_sendmsg(stderr,header,msg);
#ifdef HAVE_WRITEV
diff --git a/lib/erl_interface/src/connect/send_exit.c b/lib/erl_interface/src/connect/send_exit.c
index 098797c96d..d4e6605a2c 100644
--- a/lib/erl_interface/src/connect/send_exit.c
+++ b/lib/erl_interface/src/connect/send_exit.c
@@ -88,8 +88,7 @@ int ei_send_exit_tmo(int fd, const erlang_pid *from, const erlang_pid *to,
put32be(s, index - 4); /* 4 */
put8(s, ERL_PASS_THROUGH); /* 1 */
/*** sum: len + 1080 */
- /* FIXME incorrect level */
- if (ei_tracelevel > 1)
+ if (ei_tracelevel >= 4)
ei_show_sendmsg(stderr,msgbuf,NULL);
ei_write_fill_t(fd,msgbuf,index,ms);
diff --git a/lib/erl_interface/src/connect/send_reg.c b/lib/erl_interface/src/connect/send_reg.c
index 8f0e40309c..779b1b8359 100644
--- a/lib/erl_interface/src/connect/send_reg.c
+++ b/lib/erl_interface/src/connect/send_reg.c
@@ -82,8 +82,7 @@ int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from,
put32be(s, index + msglen - 4); /* 4 */
put8(s, ERL_PASS_THROUGH); /* 1 */
/*** sum: 1336 */
- /* FIXME incorrect level.... */
- if (ei_tracelevel > 0)
+ if (ei_tracelevel >= 4)
ei_show_sendmsg(stderr,header,msg);
#ifdef HAVE_WRITEV
diff --git a/lib/erl_interface/src/decode/decode_atom.c b/lib/erl_interface/src/decode/decode_atom.c
index b247bd4e17..ef28838b79 100644
--- a/lib/erl_interface/src/decode/decode_atom.c
+++ b/lib/erl_interface/src/decode/decode_atom.c
@@ -31,6 +31,8 @@ int ei_decode_atom(const char *buf, int *index, char *p)
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
+
if (p) {
memmove(p,s,len);
p[len] = (char)0;
diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c
index efe9c6e5d9..b5e9b45a3b 100644
--- a/lib/erl_interface/src/decode/decode_big.c
+++ b/lib/erl_interface/src/decode/decode_big.c
@@ -74,7 +74,7 @@ erlang_big *ei_alloc_big(unsigned int digit_bytes) {
memset(b,(char)0,sizeof(erlang_big));
if ( (b->digits = malloc(2*n)) == NULL) {
free(b);
- return 0;
+ return NULL;
}
b->arity = digit_bytes;
diff --git a/lib/erl_interface/src/decode/decode_double.c b/lib/erl_interface/src/decode/decode_double.c
index 66dbe474ec..ed6e39655e 100644
--- a/lib/erl_interface/src/decode/decode_double.c
+++ b/lib/erl_interface/src/decode/decode_double.c
@@ -1,19 +1,19 @@
/*
* %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
* 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 <stdio.h>
@@ -26,14 +26,22 @@ int ei_decode_double(const char *buf, int *index, double *p)
{
const char *s = buf + *index;
const char *s0 = s;
- double f;
+ FloatExt f;
- if (get8(s) != ERL_FLOAT_EXT) return -1;
-
- if (sscanf(s, "%lf", &f) != 1) return -1;
+ switch (get8(s)) {
+ case ERL_FLOAT_EXT:
+ if (sscanf(s, "%lf", &f.d) != 1) return -1;
+ s += 31;
+ break;
+ case NEW_FLOAT_EXT:
+ /* IEEE 754 format */
+ f.val = get64be(s);
+ break;
+ default:
+ return -1;
+ }
- s += 31;
- if (p) *p = f;
+ if (p) *p = f.d;
*index += s-s0;
return 0;
}
diff --git a/lib/erl_interface/src/decode/decode_pid.c b/lib/erl_interface/src/decode/decode_pid.c
index 5f2aec3b44..48a0c68240 100644
--- a/lib/erl_interface/src/decode/decode_pid.c
+++ b/lib/erl_interface/src/decode/decode_pid.c
@@ -33,6 +33,8 @@ int ei_decode_pid(const char *buf, int *index, erlang_pid *p)
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+
+ if (len > MAXATOMLEN) return -1;
if (p) {
memmove(p->node, s, len);
diff --git a/lib/erl_interface/src/decode/decode_port.c b/lib/erl_interface/src/decode/decode_port.c
index 7fb7d8d414..296ebae024 100644
--- a/lib/erl_interface/src/decode/decode_port.c
+++ b/lib/erl_interface/src/decode/decode_port.c
@@ -34,6 +34,8 @@ int ei_decode_port(const char *buf, int *index, erlang_port *p)
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
+
if (p) {
memmove(p->node, s, len);
p->node[len] = (char)0;
diff --git a/lib/erl_interface/src/decode/decode_ref.c b/lib/erl_interface/src/decode/decode_ref.c
index 6fc2cd6533..691b51fe2d 100644
--- a/lib/erl_interface/src/decode/decode_ref.c
+++ b/lib/erl_interface/src/decode/decode_ref.c
@@ -35,6 +35,8 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
+
if (p) {
memmove(p->node, s, len);
p->node[len] = (char)0;
@@ -62,6 +64,7 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
/* then the nodename */
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
if (p) {
memmove(p->node, s, len);
diff --git a/lib/erl_interface/src/decode/decode_skip.c b/lib/erl_interface/src/decode/decode_skip.c
index 316b5bee98..f6c5d861ab 100644
--- a/lib/erl_interface/src/decode/decode_skip.c
+++ b/lib/erl_interface/src/decode/decode_skip.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-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 "eidef.h"
@@ -77,6 +77,7 @@ int ei_skip_term(const char* buf, int* index)
if (ei_decode_big(buf, index, NULL) < 0) return -1;
break;
case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
if (ei_decode_double(buf, index, NULL) < 0) return -1;
break;
case ERL_FUN_EXT:
diff --git a/lib/erl_interface/src/encode/encode_double.c b/lib/erl_interface/src/encode/encode_double.c
index 53f3d52ba6..148a49f73a 100644
--- a/lib/erl_interface/src/encode/encode_double.c
+++ b/lib/erl_interface/src/encode/encode_double.c
@@ -1,19 +1,19 @@
/*
* %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
* 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 <stdio.h>
@@ -27,13 +27,13 @@ int ei_encode_double(char *buf, int *index, double p)
char *s = buf + *index;
char *s0 = s;
- if (!buf) s ++;
+ if (!buf)
+ s += 9;
else {
- put8(s,ERL_FLOAT_EXT);
- memset(s, 0, 31);
- sprintf(s, "%.20e", p);
+ /* IEEE 754 format */
+ put8(s, NEW_FLOAT_EXT);
+ put64be(s, ((FloatExt*)&p)->val);
}
- s += 31;
*index += s-s0;
diff --git a/lib/erl_interface/src/epmd/ei_epmd.h b/lib/erl_interface/src/epmd/ei_epmd.h
index 40e5ece572..ccacfed244 100644
--- a/lib/erl_interface/src/epmd/ei_epmd.h
+++ b/lib/erl_interface/src/epmd/ei_epmd.h
@@ -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
@@ -40,20 +40,13 @@
#define EI_MYPROTO 0 /* tcp/ip */
#endif
-/* epmd r3 protocol */
-#ifndef EI_EPMD_ALIVE_REQ
-#define EI_EPMD_ALIVE_REQ 'a'
-#define EI_EPMD_ALIVE_OK_RESP 'Y'
-#define EI_EPMD_PORT_REQ 'p'
-#define EI_EPMD_STOP_REQ 's'
-#endif
-
/* epmd r4 */
#ifndef EI_EPMD_ALIVE2_REQ
#define EI_EPMD_ALIVE2_REQ 120
#define EI_EPMD_ALIVE2_RESP 121
#define EI_EPMD_PORT2_REQ 122
#define EI_EPMD_PORT2_RESP 119
+#define EI_EPMD_STOP_REQ 's'
#endif
/* internal functions */
diff --git a/lib/erl_interface/src/epmd/epmd_port.c b/lib/erl_interface/src/epmd/epmd_port.c
index 663b38d2d4..698c75c217 100644
--- a/lib/erl_interface/src/epmd/epmd_port.c
+++ b/lib/erl_interface/src/epmd/epmd_port.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
@@ -92,64 +92,6 @@ int ei_epmd_connect_tmo(struct in_addr *inaddr, unsigned ms)
return sd;
}
-/* get the given node's listen port using old epmd protocol */
-static int ei_epmd_r3_port (struct in_addr *addr, const char *alive,
- unsigned ms)
-{
- char buf[EPMDBUF];
- char *s = buf;
- int len = strlen(alive) + 1;
- int fd;
- int port;
- int res;
-#if defined(VXWORKS)
- char ntoabuf[32];
-#endif
-
- put16be(s,len);
- put8(s,EI_EPMD_PORT_REQ);
- strcpy(s,alive);
-
- /* connect to epmd */
- if ((fd = ei_epmd_connect_tmo(addr,ms)) < 0)
- {
- /* ei_epmd_connect_tmo() sets erl_errno */
- return -1;
- }
-
- if ((res = ei_write_fill_t(fd, buf, len+2, ms)) != len+2) {
- closesocket(fd);
- erl_errno = (res == -2) ? ETIMEDOUT : EIO;
- return -1;
- }
-
-#ifdef VXWORKS
- /* FIXME use union/macro for level. Correct level? */
- if (ei_tracelevel > 2) {
- inet_ntoa_b(*addr,ntoabuf);
- EI_TRACE_CONN2("ei_epmd_r3_port",
- "-> PORT_REQ alive=%s ip=%s",alive,ntoabuf);
- }
-#else
- EI_TRACE_CONN2("ei_epmd_r3_port",
- "-> PORT_REQ alive=%s ip=%s",alive,inet_ntoa(*addr));
-#endif
-
- if ((res = ei_read_fill_t(fd, buf, 2, ms)) != 2) {
- EI_TRACE_ERR0("ei_epmd_r3_port","<- CLOSE");
- closesocket(fd);
- erl_errno = (res == -2) ? ETIMEDOUT : EIO;
- return -1;
- }
- closesocket(fd);
- s = buf;
- port = get16be(s);
-
- EI_TRACE_CONN1("ei_epmd_r3_port","<- PORT_RESP port=%d",port);
-
- return port;
-}
-
static int ei_epmd_r4_port (struct in_addr *addr, const char *alive,
int *dist, unsigned ms)
{
@@ -164,6 +106,12 @@ static int ei_epmd_r4_port (struct in_addr *addr, const char *alive,
#if defined(VXWORKS)
char ntoabuf[32];
#endif
+
+ if (len > sizeof(buf) - 3)
+ {
+ erl_errno = ERANGE;
+ return -1;
+ }
put16be(s,len);
put8(s,EI_EPMD_PORT2_REQ);
@@ -285,15 +233,6 @@ int ei_epmd_port_tmo (struct in_addr *addr, const char *alive, int *dist,
{
int i;
- /* try the new one first, then the old one */
- i = ei_epmd_r4_port(addr,alive,dist,ms);
-
- /* -2: new protocol not understood */
- if (i == -2) {
- *dist = 0;
- i = ei_epmd_r3_port(addr,alive,ms);
- }
-
- return i;
+ return ei_epmd_r4_port(addr,alive,dist,ms);
}
diff --git a/lib/erl_interface/src/epmd/epmd_publish.c b/lib/erl_interface/src/epmd/epmd_publish.c
index 09b3dce43b..d45fe644c0 100644
--- a/lib/erl_interface/src/epmd/epmd_publish.c
+++ b/lib/erl_interface/src/epmd/epmd_publish.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
@@ -55,62 +55,6 @@
/* publish our listen port and alive name */
/* return the (useless) creation number */
-static int ei_epmd_r3_publish (int port, const char *alive, unsigned ms)
-{
- char buf[EPMDBUF];
- char *s = buf;
- int fd;
- int len = strlen(alive) + 3;
- int res,creation;
-
- s = buf;
- put16be(s,len);
- put8(s,EI_EPMD_ALIVE_REQ);
- put16be(s,port);
- strcpy(s, alive);
-
- if ((fd = ei_epmd_connect_tmo(NULL,ms)) < 0) return fd;
-
- if ((res = ei_write_fill_t(fd, buf, len+2, ms)) != len+2) {
- closesocket(fd);
- erl_errno = (res == -2) ? ETIMEDOUT : EIO;
- return -1;
- }
-
- EI_TRACE_CONN2("ei_epmd_r3_publish",
- "-> ALIVE_REQ alive=%s port=%d",alive,port);
-
- if ((res = ei_read_fill_t(fd, buf, 3, ms)) != 3) {
- closesocket(fd);
- erl_errno = (res == -2) ? ETIMEDOUT : EIO;
- return -1;
- }
-
- s = buf;
- if ((res=get8(s)) != EI_EPMD_ALIVE_OK_RESP) {
- EI_TRACE_ERR1("ei_epmd_r3_publish",
- "<- ALIVE_NOK result=%d (failure)",res);
- closesocket(fd);
- erl_errno = EIO;
- return -1;
- }
-
- creation = get16be(s);
-
- EI_TRACE_CONN1("ei_epmd_r3_publish","<- ALIVE_OK creation=%d",creation);
-
- /* Don't close fd here! It keeps us registered with epmd */
-
- /* probably should save fd so we can close it later... */
- /* epmd_saveconn(OPEN,fd,alive); */
-
- /* return the creation number, for no good reason */
- /* return creation; */
-
- /* no! return the descriptor */
- return fd;
-}
-
/* publish our listen port and alive name */
/* return the (useless) creation number */
/* this protocol is a lot more complex than the old one */
@@ -125,6 +69,12 @@ static int ei_epmd_r4_publish (int port, const char *alive, unsigned ms)
int n;
int res, creation;
+ if (len > sizeof(buf)-2)
+ {
+ erl_errno = ERANGE;
+ return -1;
+ }
+
s = buf;
put16be(s,len);
@@ -200,15 +150,7 @@ int ei_epmd_publish(int port, const char *alive)
int ei_epmd_publish_tmo(int port, const char *alive, unsigned ms)
{
- int i;
-
- /* try the new one first, then the old one */
- i = ei_epmd_r4_publish(port,alive, ms);
-
- /* -2: new protocol not understood */
- if (i == -2) i = ei_epmd_r3_publish(port,alive, ms);
-
- return i;
+ return ei_epmd_r4_publish(port,alive, ms);;
}
diff --git a/lib/erl_interface/src/epmd/epmd_unpublish.c b/lib/erl_interface/src/epmd/epmd_unpublish.c
index 08662fe1ec..495cbab44c 100644
--- a/lib/erl_interface/src/epmd/epmd_unpublish.c
+++ b/lib/erl_interface/src/epmd/epmd_unpublish.c
@@ -59,6 +59,11 @@ int ei_unpublish_tmo(const char *alive, unsigned ms)
int len = 1 + strlen(alive);
int fd, res;
+ if (len > sizeof(buf)-3) {
+ erl_errno = ERANGE;
+ return -1;
+ }
+
put16be(s,len);
put8(s,EI_EPMD_STOP_REQ);
strcpy(s, alive);
diff --git a/lib/erl_interface/src/legacy/decode_term.c b/lib/erl_interface/src/legacy/decode_term.c
index ef29d6f57d..796cebdfef 100644
--- a/lib/erl_interface/src/legacy/decode_term.c
+++ b/lib/erl_interface/src/legacy/decode_term.c
@@ -1,19 +1,19 @@
/*
* %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
* 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 "eidef.h"
@@ -59,6 +59,7 @@ int ei_decode_term(const char *buf, int *index, void *t)
return ei_decode_long(buf,index,NULL);
case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
return ei_decode_double(buf,index,NULL);
case ERL_ATOM_EXT:
diff --git a/lib/erl_interface/src/legacy/erl_connect.c b/lib/erl_interface/src/legacy/erl_connect.c
index 3c8c946506..e77bd5db37 100644
--- a/lib/erl_interface/src/legacy/erl_connect.c
+++ b/lib/erl_interface/src/legacy/erl_connect.c
@@ -180,9 +180,7 @@ int erl_xconnect(Erl_IpAddr addr, char *alivename)
*
* Close a connection. FIXME call ei_close_connection() later.
*
- * Returns valid file descriptor on success and < 0 on failure.
- * Set erl_errno to EHOSTUNREACH, ENOMEM, EIO or errno from socket(2)
- * or connect(2).
+ * Returns 0 on success and -1 on failure.
*
***************************************************************************/
@@ -250,7 +248,8 @@ int erl_send(int fd, ETERM *to ,ETERM *msg)
return -1;
}
- strcpy(topid.node, (char *)ERL_PID_NODE(to));
+ strncpy(topid.node, (char *)ERL_PID_NODE(to), sizeof(topid.node));
+ topid.node[sizeof(topid.node)-1] = '\0';
topid.num = ERL_PID_NUMBER(to);
topid.serial = ERL_PID_SERIAL(to);
topid.creation = ERL_PID_CREATION(to);
diff --git a/lib/erl_interface/src/legacy/erl_format.c b/lib/erl_interface/src/legacy/erl_format.c
index 9848e9296a..b17269213f 100644
--- a/lib/erl_interface/src/legacy/erl_format.c
+++ b/lib/erl_interface/src/legacy/erl_format.c
@@ -116,7 +116,7 @@ static lvar *lvar_alloc(void)
lvar *tmp;
if ((tmp = ef.idle) == NULL) {
- tmp = (lvar *) malloc(sizeof(lvar)); /* FIXME check result */
+ tmp = (lvar *) erl_malloc(sizeof(lvar));
}
else {
tmp = ef.idle;
diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c
index 4b5f28178f..5cfb5e2124 100644
--- a/lib/erl_interface/src/legacy/erl_marshal.c
+++ b/lib/erl_interface/src/legacy/erl_marshal.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-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%
*/
/*
@@ -26,6 +26,7 @@
#include <ctype.h>
#include <sys/types.h>
#include <string.h>
+#include <limits.h>
#include "erl_interface.h"
#include "erl_marshal.h"
@@ -102,6 +103,7 @@ void erl_init_marshal(void)
cmp_array[ERL_SMALL_INTEGER_EXT] = 1;
cmp_array[ERL_INTEGER_EXT] = 1;
cmp_array[ERL_FLOAT_EXT] = 1;
+ cmp_array[NEW_FLOAT_EXT] = 1;
cmp_array[ERL_SMALL_BIG_EXT] = 1;
cmp_array[ERL_LARGE_BIG_EXT] = 1;
cmp_array[ERL_ATOM_EXT] = 2;
@@ -124,6 +126,7 @@ void erl_init_marshal(void)
cmp_num_class[ERL_SMALL_INTEGER_EXT] = SMALL;
cmp_num_class[ERL_INTEGER_EXT] = SMALL;
cmp_num_class[ERL_FLOAT_EXT] = FLOAT;
+ cmp_num_class[NEW_FLOAT_EXT] = FLOAT;
cmp_num_class[ERL_SMALL_BIG_EXT] = BIG;
cmp_num_class[ERL_LARGE_BIG_EXT] = BIG;
init_cmp_num_class_p = 0;
@@ -176,26 +179,14 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
return 0;
case ERL_INTEGER:
- i = ep->uval.ival.i;
- /* ERL_SMALL_BIG */
- if ((i > ERL_MAX) || (i < ERL_MIN)) {
- *(*ext)++ = ERL_SMALL_BIG_EXT;
- *(*ext)++ = 4; /* four bytes */
- if ((*(*ext)++ = ((i>>31) & 0x01))) /* sign byte */
- i = -i;
- *(*ext)++ = i & 0xff; /* LSB first */
- *(*ext)++ = (i >> 8) & 0xff;
- *(*ext)++ = (i >> 16) & 0xff;
- *(*ext)++ = (i >> 24) & 0x7f; /* Don't include the sign bit */
- return 0;
- }
+ i = ep->uval.ival.i;
/* SMALL_INTEGER */
if ((i < 256) && (i >= 0)) {
*(*ext)++ = ERL_SMALL_INTEGER_EXT;
*(*ext)++ = i & 0xff;
return 0;
}
- /* INTEGER */
+ /* R14B: Use all 32 bits of INTEGER_EXT */
*(*ext)++ = ERL_INTEGER_EXT;
*(*ext)++ = (i >> 24) & 0xff;
*(*ext)++ = (i >> 16) & 0xff;
@@ -206,23 +197,23 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
case ERL_U_INTEGER:
u = ep->uval.uival.u;
/* ERL_U_SMALL_BIG */
- if (u > ERL_MAX) {
- *(*ext)++ = ERL_SMALL_BIG_EXT;
- *(*ext)++ = 4; /* four bytes */
- *(*ext)++ = 0; /* sign byte */
- *(*ext)++ = u & 0xff; /* LSB first */
- *(*ext)++ = (u >> 8) & 0xff;
- *(*ext)++ = (u >> 16) & 0xff;
- *(*ext)++ = (u >> 24) & 0xff;
- return 0;
+ if ((int)u < 0) {
+ *(*ext)++ = ERL_SMALL_BIG_EXT;
+ *(*ext)++ = 4; /* four bytes */
+ *(*ext)++ = 0; /* sign byte */
+ *(*ext)++ = u & 0xff; /* LSB first */
+ *(*ext)++ = (u >> 8) & 0xff;
+ *(*ext)++ = (u >> 16) & 0xff;
+ *(*ext)++ = (u >> 24) & 0xff;
+ return 0;
}
/* SMALL_INTEGER */
- if ((u < 256) && (u >= 0)) {
+ if (u < 256) {
*(*ext)++ = ERL_SMALL_INTEGER_EXT;
*(*ext)++ = u & 0xff;
return 0;
}
- /* INTEGER */
+ /* R14B: Use all 32 bits of INTEGER_EXT */
*(*ext)++ = ERL_INTEGER_EXT;
*(*ext)++ = (u >> 24) & 0xff;
*(*ext)++ = (u >> 16) & 0xff;
@@ -232,29 +223,28 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
case ERL_LONGLONG:
l = ep->uval.llval.i;
/* ERL_SMALL_BIG */
- if ((l > ((long long) ERL_MAX)) ||
- (l < ((long long) ERL_MIN))) {
- *(*ext)++ = ERL_SMALL_BIG_EXT;
- *(*ext)++ = 8; /* eight bytes */
- if ((*(*ext)++ = ((l>>63) & 0x01))) /* sign byte */
+ if (l > ((long long) INT_MAX) || l < ((long long) INT_MIN)) {
+ *(*ext)++ = ERL_SMALL_BIG_EXT;
+ *(*ext)++ = 8;
+ if ((*(*ext)++ = (l<0))) /* sign byte */
l = -l;
- *(*ext)++ = l & 0xff; /* LSB first */
+ *(*ext)++ = l & 0xff; /* LSB first */
*(*ext)++ = (l >> 8) & 0xff;
*(*ext)++ = (l >> 16) & 0xff;
- *(*ext)++ = (l >> 24) & 0xff;
- *(*ext)++ = (l >> 32) & 0xff;
- *(*ext)++ = (l >> 40) & 0xff;
- *(*ext)++ = (l >> 48) & 0xff;
- *(*ext)++ = (l >> 56) & 0x7f; /* Don't include the sign bit */
+ *(*ext)++ = (l >> 24) & 0xff;
+ *(*ext)++ = (l >> 32) & 0xff;
+ *(*ext)++ = (l >> 40) & 0xff;
+ *(*ext)++ = (l >> 48) & 0xff;
+ *(*ext)++ = (l >> 56) & 0xff;
return 0;
}
/* SMALL_INTEGER */
if ((l < 256) && (l >= 0)) {
- *(*ext)++ = ERL_SMALL_INTEGER_EXT;
- *(*ext)++ = l & 0xff;
- return 0;
+ *(*ext)++ = ERL_SMALL_INTEGER_EXT;
+ *(*ext)++ = l & 0xff;
+ return 0;
}
- /* INTEGER */
+ /* R14B: Use all 32 bits of INTEGER_EXT */
*(*ext)++ = ERL_INTEGER_EXT;
*(*ext)++ = (l >> 24) & 0xff;
*(*ext)++ = (l >> 16) & 0xff;
@@ -265,7 +255,7 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
case ERL_U_LONGLONG:
ul = ep->uval.ullval.u;
/* ERL_U_SMALL_BIG */
- if (ul > ((unsigned long long) ERL_MAX)) {
+ if (ul > ((unsigned long long) INT_MAX)) {
*(*ext)++ = ERL_SMALL_BIG_EXT;
*(*ext)++ = 8; /* eight bytes */
*(*ext)++ = 0; /* sign byte */
@@ -285,7 +275,7 @@ int erl_encode_it(ETERM *ep, unsigned char **ext, int dist)
*(*ext)++ = ul & 0xff;
return 0;
}
- /* INTEGER */
+ /* R14B: Use all 32 bits of INTEGER_EXT */
*(*ext)++ = ERL_INTEGER_EXT;
*(*ext)++ = (ul >> 24) & 0xff;
*(*ext)++ = (ul >> 16) & 0xff;
@@ -521,29 +511,28 @@ static int erl_term_len_helper(ETERM *ep, int dist)
case ERL_INTEGER:
i = ep->uval.ival.i;
- if ((i > ERL_MAX) || (i < ERL_MIN)) len = 7;
- else if ((i < 256) && (i >= 0)) len = 2;
+ if ((i < 256) && (i >= 0)) len = 2;
else len = 5;
break;
case ERL_U_INTEGER:
u = ep->uval.uival.u;
- if (u > ERL_MAX) len = 7;
+ if ((int)u < 0) len = 7;
else if (u < 256) len = 2;
else len = 5;
break;
case ERL_LONGLONG:
l = ep->uval.llval.i;
- if ((l > ((long long) ERL_MAX)) ||
- (l < ((long long) ERL_MIN))) len = 11;
+ if ((l > ((long long) INT_MAX)) ||
+ (l < ((long long) INT_MIN))) len = 11;
else if ((l < 256) && (l >= 0)) len = 2;
else len = 5;
break;
case ERL_U_LONGLONG:
ul = ep->uval.ullval.u;
- if (ul > ((unsigned long long) ERL_MAX)) len = 11;
+ if (ul > ((unsigned long long) INT_MAX)) len = 11;
else if (ul < 256) len = 2;
else len = 5;
break;
@@ -556,12 +545,7 @@ static int erl_term_len_helper(ETERM *ep, int dist)
case ERL_REF:
i = strlen((char *)ERL_REF_NODE(ep));
- if (dist >= 4 && ERL_REF_LEN(ep) > 1) {
- len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4;
- } else {
- /* 1 + N + 4 + 1 where N = 3 + strlen */
- len = 9 + i;
- }
+ len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4;
break;
case ERL_PORT:
@@ -678,7 +662,7 @@ len = i
#define STATIC_NODE_BUF_SZ 30
#define SET_NODE(node,node_buf,cp,len) \
-if (len >= STATIC_NODE_BUF_SZ) node = malloc(len+1); \
+if (len >= STATIC_NODE_BUF_SZ) node = erl_malloc(len+1); \
else node = node_buf; \
memcpy(node, cp, len); \
node[len] = '\0'
@@ -730,11 +714,6 @@ static ETERM *erl_decode_it(unsigned char **ext)
if (arity > 8)
goto big_truncate;
- if (arity == 8 && ((*ext)[7] & 0x80) && sign) {
- /* MSB already occupied ! */
- goto big_truncate;
- }
-
if (arity == 4 && ((*ext)[3] & 0x80) && !sign) {
/* It will fit into an unsigned int !! */
u = (((*ext)[3] << 24)|((*ext)[2])<< 16|((*ext)[1]) << 8 |(**ext));
@@ -745,14 +724,10 @@ static ETERM *erl_decode_it(unsigned char **ext)
return ep;
} else if (arity == 4 && !((*ext)[3] & 0x80)) {
/* It will fit into an int !!
- * Note: It comes in "one's-complement notation"
*/
- if (sign)
- i = (int) (~(((*ext)[3] << 24) | ((*ext)[2])<< 16 |
- ((*ext)[1]) << 8 | (**ext)) | (unsigned int) sign);
- else
- i = (int) (((*ext)[3] << 24) | ((*ext)[2])<< 16 |
- ((*ext)[1]) << 8 | (**ext));
+ i = (int) (((*ext)[3] << 24) | ((*ext)[2])<< 16 |
+ ((*ext)[1]) << 8 | (**ext));
+ if (sign) i = -i;
ERL_TYPE(ep) = ERL_INTEGER;
ep->uval.ival.i = i;
*ext += arity;
@@ -778,8 +753,10 @@ static ETERM *erl_decode_it(unsigned char **ext)
for(x = 0 ; x < arity ; x++) {
l |= ((long long)(*ext)[x]) << ((long long)(8*x));
}
-
- if (sign) l = (long long) (~l | (unsigned long long) sign);
+ if (sign) {
+ l = -l;
+ if (l > 0) goto big_truncate;
+ }
ERL_TYPE(ep) = ERL_LONGLONG;
ep->uval.llval.i = l;
@@ -1008,10 +985,13 @@ static ETERM *erl_decode_it(unsigned char **ext)
return ep;
case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
ERL_TYPE(ep) = ERL_FLOAT;
- if (sscanf((char *) *ext, "%lf", &ff) != 1)
+ cp = (char *) *ext;
+ i = -1;
+ if (ei_decode_double(cp, &i, &ff) == -1)
goto failure;
- *ext += 31;
+ *ext += i;
ep->uval.fval.f = ff;
return ep;
@@ -1176,6 +1156,7 @@ unsigned char erl_ext_type(unsigned char *ext)
case ERL_LARGE_TUPLE_EXT:
return ERL_TUPLE;
case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
return ERL_FLOAT;
case ERL_BINARY_EXT:
return ERL_BINARY;
@@ -1218,6 +1199,7 @@ int erl_ext_size(unsigned char *t)
case ERL_BINARY_EXT:
case ERL_STRING_EXT:
case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
case ERL_SMALL_BIG_EXT:
case ERL_LARGE_BIG_EXT:
return 0;
@@ -1332,6 +1314,9 @@ static int jump(unsigned char **ext)
case ERL_FLOAT_EXT:
*ext += 31;
break;
+ case NEW_FLOAT_EXT:
+ *ext += 8;
+ break;
case ERL_BINARY_EXT:
i = (**ext << 24) | ((*ext)[1] << 16) |((*ext)[2] << 8) | (*ext)[3];
*ext += 4+i;
@@ -1549,7 +1534,7 @@ static int cmp_string_list(unsigned char **e1, unsigned char **e2) {
if ( e1_len < 256 ) {
bp = buf;
} else {
- bp = malloc(5+(2*e1_len)+1);
+ bp = erl_malloc(5+(2*e1_len)+1);
}
bp[0] = ERL_LIST_EXT;
@@ -1661,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]);
@@ -1696,12 +1684,15 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2)
}
return 0;
case ERL_FLOAT_EXT:
- if (sscanf((char *) *e1, "%lf", &ff1) != 1)
- return -1;
- *e1 += 31;
- if (sscanf((char *) *e2, "%lf", &ff2) != 1)
- return -1;
- *e2 += 31;
+ case NEW_FLOAT_EXT:
+ i = -1;
+ if (ei_decode_double((char *) *e1, &i, &ff1) != 0)
+ return -1;
+ *e1 += i;
+ j = -1;
+ if (ei_decode_double((char *) *e2, &j, &ff2) != 0)
+ return -1;
+ *e2 += j;
return cmp_floats(ff1,ff2);
case ERL_BINARY_EXT:
@@ -1896,8 +1887,11 @@ static int cmp_big_big(unsigned char**e1, unsigned char **e2)
ei_get_type((char *)*e1,&i1,&t1,&n1);
ei_get_type((char *)*e2,&i2,&t2,&n2);
- b1 = ei_alloc_big(n1);
- b2 = ei_alloc_big(n2);
+ if ( (b1 = ei_alloc_big(n1)) == NULL) return -1;
+ if ( (b2 = ei_alloc_big(n2)) == NULL) {
+ ei_free_big(b1);
+ return 1;
+ }
ei_decode_big((char *)*e1,&i1,b1);
ei_decode_big((char *)*e2,&i2,b2);
diff --git a/lib/erl_interface/src/legacy/erl_timeout.c b/lib/erl_interface/src/legacy/erl_timeout.c
index af1a4a1f3a..6ef5d258ed 100644
--- a/lib/erl_interface/src/legacy/erl_timeout.c
+++ b/lib/erl_interface/src/legacy/erl_timeout.c
@@ -74,7 +74,7 @@ jmp_buf *timeout_setup(int ms)
t.it_value.tv_usec = (ms % 1000) * 1000;
/* get a jump buffer and save it */
- j = malloc(sizeof(*j)); /* FIXME check result */
+ j = erl_malloc(sizeof(*j));
j->siginfo = s;
push(j);
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/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c
index 7b95ff232f..9b238c1e90 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.c
+++ b/lib/erl_interface/src/misc/ei_decode_term.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*
@@ -25,16 +25,15 @@
#include "ei_decode_term.h"
#include "putget.h"
-/* Returns 1 if term is decoded, 0 if term is OK, but not decoded here
- and -1 if something is wrong.
- ONLY changes index if term is decoded (return value 1)! */
+/* Returns 0 on successful encoding, -1 on error, and 1 if the term seems
+ alright, but does not fit in the term structure. If it returns 0, the
+ index will be incremented, and the term contains the decoded term. */
int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
{
const char* s = buf + *index, * s0 = s;
int len, i, n, sign;
char c;
- double f;
if (term == NULL) return -1;
c = term->ei_type = get8(s);
@@ -46,13 +45,11 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
term->value.i_val = get32be(s);
break;
case ERL_FLOAT_EXT:
- if (s[30]) return -1;
- if (sscanf(s, "%lf", &f) != 1) return -1;
- s += 31;
- term->value.d_val = f;
- break;
+ case NEW_FLOAT_EXT:
+ return ei_decode_double(buf, index, &term->value.d_val);
case ERL_ATOM_EXT:
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.atom_name, s, len);
term->value.atom_name[len] = '\0';
s += len;
@@ -61,6 +58,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
/* first the nodename */
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.ref.node, s, len);
term->value.ref.node[len] = '\0';
s += len;
@@ -75,6 +73,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
/* then the nodename */
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.ref.node, s, len);
term->value.ref.node[len] = '\0';
s += len;
@@ -91,6 +90,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
case ERL_PORT_EXT:
if (get8(s) != ERL_ATOM_EXT) return -1;
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.port.node, s, len);
term->value.port.node[len] = '\0';
term->value.port.id = get32be(s) & 0x0fffffff; /* 28 bits */;
@@ -100,6 +100,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
if (get8(s) != ERL_ATOM_EXT) return -1;
/* name first */
len = get16be(s);
+ if (len > MAXATOMLEN) return -1;
memcpy(term->value.pid.node, s, len);
term->value.pid.node[len] = '\0';
s += len;
diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c
index 08235d0ebe..dbd7a4479a 100644
--- a/lib/erl_interface/src/misc/ei_format.c
+++ b/lib/erl_interface/src/misc/ei_format.c
@@ -47,10 +47,12 @@
* array of unions.
*/
union arg {
+ char c;
char* s;
long l;
unsigned long u;
double d;
+ erlang_pid* pid;
};
static int eiformat(const char** s, union arg** args, ei_x_buff* x);
@@ -106,6 +108,8 @@ static int eiformat(const char** fmt, union arg** args, ei_x_buff* x)
default:
if (isdigit((int)*p))
res = pdigit(&p, x);
+ else if ((*p == '-' || *p == '+') && isdigit((int)*(p+1)))
+ res = pdigit(&p, x);
else if (islower((int)*p))
res = patom(&p, x);
else
@@ -149,6 +153,8 @@ static int pdigit(const char** fmt, ei_x_buff* x)
double d;
long l;
+ if (**fmt == '-' || **fmt == '+')
+ (*fmt)++;
for (;;) {
c = *(*fmt)++;
if (isdigit((int)c))
@@ -220,12 +226,14 @@ 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
* 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)
{
@@ -236,6 +244,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)++;
@@ -257,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;
@@ -392,6 +408,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*);
@@ -411,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/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c
index b73ebebbe1..a3f6f63fff 100644
--- a/lib/erl_interface/src/misc/ei_portio.c
+++ b/lib/erl_interface/src/misc/ei_portio.c
@@ -166,11 +166,16 @@ int ei_writev_fill_t(int fd, const struct iovec *iov, int iovcnt, unsigned
if (done < sum) {
if (iov_base == NULL) {
iov_base = malloc(sizeof(struct iovec) * iovcnt);
+ if (iov_base == NULL) {
+ return -1;
+ }
memcpy(iov_base, iov, sizeof(struct iovec) * iovcnt);
current_iov = iov_base;
}
while (i > 0) {
if (i < current_iov[0].iov_len) {
+ char *p = (char*)current_iov[0].iov_base;
+ current_iov[0].iov_base = p + i;
current_iov[0].iov_len -= i;
i = 0;
} else {
diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c
index 8d0eef5e79..5fc6b3542c 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*
@@ -253,7 +253,8 @@ static int print_term(FILE* fp, ei_x_buff* x,
erlang_big *b;
char *ds;
- b = ei_alloc_big(n);
+ if ( (b = ei_alloc_big(n)) == NULL) goto err;
+
if (ei_decode_big(buf, index, b) < 0) {
ei_free_big(b);
goto err;
@@ -272,6 +273,7 @@ static int print_term(FILE* fp, ei_x_buff* x,
break;
case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
if (ei_decode_double(buf, index, &d) < 0) goto err;
ch_written += xprintf(fp, x, "%f", d);
break;
diff --git a/lib/erl_interface/src/misc/get_type.c b/lib/erl_interface/src/misc/get_type.c
index d67a6a80d3..2a680d0f94 100644
--- a/lib/erl_interface/src/misc/get_type.c
+++ b/lib/erl_interface/src/misc/get_type.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*
@@ -122,7 +122,12 @@ int ei_get_type_internal(const char *buf, const int *index,
case ERL_STRING_EXT:
*len = get16be(s);
break;
-
+
+ case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
+ *type = ERL_FLOAT_EXT;
+ break;
+
case ERL_LARGE_TUPLE_EXT:
case ERL_LIST_EXT:
case ERL_BINARY_EXT:
diff --git a/lib/erl_interface/src/misc/putget.h b/lib/erl_interface/src/misc/putget.h
index 98d9ebb64c..7a43de324b 100644
--- a/lib/erl_interface/src/misc/putget.h
+++ b/lib/erl_interface/src/misc/putget.h
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*
@@ -54,6 +54,18 @@
(s) += 4; \
} while (0)
+#define put64be(s,n) do { \
+ (s)[0] = ((n) >> 56) & 0xff; \
+ (s)[1] = ((n) >> 48) & 0xff; \
+ (s)[2] = ((n) >> 40) & 0xff; \
+ (s)[3] = ((n) >> 32) & 0xff; \
+ (s)[4] = ((n) >> 24) & 0xff; \
+ (s)[5] = ((n) >> 16) & 0xff; \
+ (s)[6] = ((n) >> 8) & 0xff; \
+ (s)[7] = (n) & 0xff; \
+ (s) += 8; \
+} while (0)
+
#define get8(s) \
((s) += 1, \
((unsigned char *)(s))[-1] & 0xff)
@@ -82,4 +94,20 @@
(((unsigned char *)(s))[-2] << 8) | \
((unsigned char *)(s))[-1]))
+#define get64be(s) \
+ ((s) += 8, \
+ (((EI_ULONGLONG)((unsigned char *)(s))[-8] << 56) | \
+ ((EI_ULONGLONG)((unsigned char *)(s))[-7] << 48) | \
+ ((EI_ULONGLONG)((unsigned char *)(s))[-6] << 40) | \
+ ((EI_ULONGLONG)((unsigned char *)(s))[-5] << 32) | \
+ ((EI_ULONGLONG)((unsigned char *)(s))[-4] << 24) | \
+ ((EI_ULONGLONG)((unsigned char *)(s))[-3] << 16) | \
+ ((EI_ULONGLONG)((unsigned char *)(s))[-2] << 8) | \
+ (EI_ULONGLONG)((unsigned char *)(s))[-1]))
+
+typedef union float_ext {
+ double d;
+ EI_ULONGLONG val;
+} FloatExt;
+
#endif /* _PUTGET_H */
diff --git a/lib/erl_interface/src/misc/show_msg.c b/lib/erl_interface/src/misc/show_msg.c
index 25865d6f8e..194296798b 100644
--- a/lib/erl_interface/src/misc/show_msg.c
+++ b/lib/erl_interface/src/misc/show_msg.c
@@ -1,19 +1,19 @@
/*
* %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
* 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%
*
@@ -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);
@@ -400,6 +391,7 @@ static void show_term(const char *termbuf, int *index, FILE *stream)
break;
case ERL_FLOAT_EXT:
+ case NEW_FLOAT_EXT:
ei_decode_double(termbuf,index,&fnum);
fprintf(stream,"%f",fnum);
break;
diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c
index f0d638324d..33ff6da7c9 100644
--- a/lib/erl_interface/src/prog/erl_call.c
+++ b/lib/erl_interface/src/prog/erl_call.c
@@ -118,11 +118,14 @@ static void usage_arg(const char *progname, const char *switchname);
static void usage_error(const char *progname, const char *switchname);
static void usage(const char *progname);
static int get_module(char **mbuf, char **mname);
-static struct hostent* get_hostent(char *host);
static int do_connect(ei_cnode *ec, char *nodename, struct call_flags *flags);
static int read_stdin(char **buf);
static void split_apply_string(char *str, char **mod,
char **fun, char **args);
+static void* ei_chk_malloc(size_t size);
+static void* ei_chk_calloc(size_t nmemb, size_t size);
+static void* ei_chk_realloc(void *old, size_t size);
+static char* ei_chk_strdup(char *s);
/***************************************************************************
@@ -132,7 +135,6 @@ static void split_apply_string(char *str, char **mod,
***************************************************************************/
/* FIXME isn't VxWorks to handle arguments differently? */
-/* FIXME check errors from malloc */
#if !defined(VXWORKS)
int main(int argc, char *argv[])
@@ -165,8 +167,7 @@ int erl_call(int argc, char **argv)
usage_arg(progname, "-sname ");
}
- flags.node = (char *) malloc(strlen(argv[i+1]) + 1);
- strcpy(flags.node, argv[i+1]);
+ flags.node = ei_chk_strdup(argv[i+1]);
i++;
flags.use_long_name = 0;
} else if (strcmp(argv[i], "-name") == 0) { /* -name NAME */
@@ -174,8 +175,7 @@ int erl_call(int argc, char **argv)
usage_arg(progname, "-name ");
}
- flags.node = (char *) malloc(strlen(argv[i+1]) + 1);
- strcpy(flags.node, argv[i+1]);
+ flags.node = ei_chk_strdup(argv[i+1]);
i++;
flags.use_long_name = 1;
} else {
@@ -210,16 +210,14 @@ int erl_call(int argc, char **argv)
usage_arg(progname, "-c ");
}
flags.cookiep = 1;
- flags.cookie = (char *) malloc(strlen(argv[i+1]) + 1);
- strcpy(flags.cookie, argv[i+1]);
+ flags.cookie = ei_chk_strdup(argv[i+1]);
i++;
break;
case 'n':
if (i+1 >= argc) {
usage_arg(progname, "-n ");
}
- flags.node = (char *) malloc(strlen(argv[i+1]) + 1);
- strcpy(flags.node, argv[i+1]);
+ flags.node = ei_chk_strdup(argv[i+1]);
flags.use_long_name = 1;
i++;
break;
@@ -227,24 +225,21 @@ int erl_call(int argc, char **argv)
if (i+1 >= argc) {
usage_arg(progname, "-h ");
}
- flags.hidden = (char *) malloc(strlen(argv[i+1]) + 1);
- strcpy(flags.hidden, argv[i+1]);
+ flags.hidden = ei_chk_strdup(argv[i+1]);
i++;
break;
case 'x':
if (i+1 >= argc) {
usage_arg(progname, "-x ");
}
- flags.script = (char *) malloc(strlen(argv[i+1]) + 1);
- strcpy(flags.script, argv[i+1]);
+ flags.script = ei_chk_strdup(argv[i+1]);
i++;
break;
case 'a':
if (i+1 >= argc) {
usage_arg(progname, "-a ");
}
- flags.apply = (char *) malloc(strlen(argv[i+1]) + 1);
- strcpy(flags.apply, argv[i+1]);
+ flags.apply = ei_chk_strdup(argv[i+1]);
i++;
break;
case '?':
@@ -304,8 +299,7 @@ int erl_call(int argc, char **argv)
if (flags.hidden == NULL) {
/* As default we are c17@gethostname */
i = flags.randomp ? (time(NULL) % 997) : 17;
- /* FIXME allocates to small !!! */
- flags.hidden = (char *) malloc(3 + 2 ); /* c17 or cXYZ */
+ flags.hidden = (char *) ei_chk_malloc(10 + 2 ); /* c17 or cXYZ */
#if defined(VXWORKS)
sprintf(flags.hidden, "c%d",
i < 0 ? (int) taskIdSelf() : i);
@@ -330,17 +324,25 @@ int erl_call(int argc, char **argv)
initWinSock();
#endif
- gethostname(h_hostname, EI_MAXHOSTNAMELEN);
+ if (gethostname(h_hostname, EI_MAXHOSTNAMELEN) < 0) {
+ fprintf(stderr,"erl_call: failed to get host name: %d\n", errno);
+ exit(1);
+ }
if ((hp = ei_gethostbyname(h_hostname)) == 0) {
fprintf(stderr,"erl_call: can't resolve hostname %s\n", h_hostname);
exit(1);
}
- /* If shortnames cut of the name at first '.' */
+ /* If shortnames, cut off the name at first '.' */
if (flags.use_long_name == 0 && (ct = strchr(hp->h_name, '.')) != NULL) {
*ct = '\0';
}
- strcpy(h_hostname, hp->h_name);
+ strncpy(h_hostname, hp->h_name, EI_MAXHOSTNAMELEN);
+ h_hostname[EI_MAXHOSTNAMELEN] = '\0';
memcpy(&h_ipadr.s_addr, *hp->h_addr_list, sizeof(struct in_addr));
+ if (strlen(h_alivename) + strlen(h_hostname) + 2 > sizeof(h_nodename)) {
+ fprintf(stderr,"erl_call: hostname too long: %s\n", h_hostname);
+ exit(1);
+ }
sprintf(h_nodename, "%s@%s", h_alivename, h_hostname);
if (ei_connect_xinit(&ec, h_hostname, h_alivename, h_nodename,
@@ -364,15 +366,20 @@ int erl_call(int argc, char **argv)
* Expand name to a real name (may be ip-address)
*/
/* FIXME better error string */
- if ((hp = get_hostent(host)) == 0) {
- fprintf(stderr,"erl_call: can't get_hostent(%s)\n", host);
+ if ((hp = ei_gethostbyname(host)) == 0) {
+ fprintf(stderr,"erl_call: can't ei_gethostbyname(%s)\n", host);
exit(1);
}
- /* If shortnames cut of the name at first '.' */
+ /* If shortnames, cut off the name at first '.' */
if (flags.use_long_name == 0 && (ct = strchr(hp->h_name, '.')) != NULL) {
*ct = '\0';
}
- strcpy(host_name, hp->h_name);
+ strncpy(host_name, hp->h_name, EI_MAXHOSTNAMELEN);
+ host_name[EI_MAXHOSTNAMELEN] = '\0';
+ if (strlen(flags.node) + strlen(host_name) + 2 > sizeof(nodename)) {
+ fprintf(stderr,"erl_call: nodename too long: %s\n", flags.node);
+ exit(1);
+ }
sprintf(nodename, "%s@%s", flags.node, host_name);
/*
@@ -401,7 +408,7 @@ int erl_call(int argc, char **argv)
ei_encode_empty_list(NULL, &i);
- p = (char *)malloc(i);
+ p = (char *)ei_chk_malloc(i);
i = 0; /* Reset */
ei_encode_empty_list(p, &i);
@@ -426,6 +433,10 @@ int erl_call(int argc, char **argv)
if (flags.modp && (modname != NULL)) {
char fname[256];
+ if (strlen(modname) + 4 + 1 > sizeof(fname)) {
+ fprintf(stderr,"erl_call: module name too long: %s\n", modname);
+ exit(1);
+ }
strcpy(fname, modname);
strcat(fname, ".erl");
@@ -443,7 +454,7 @@ int erl_call(int argc, char **argv)
ei_encode_binary(NULL, &i, module, modsize);
ei_encode_empty_list(NULL, &i);
- p = (char *)malloc(i);
+ p = (char *)ei_chk_malloc(i);
i = 0; /* Reset */
ei_encode_list_header(p, &i, 2);
@@ -476,7 +487,7 @@ int erl_call(int argc, char **argv)
ei_encode_empty_list(NULL, &i);
ei_encode_empty_list(NULL, &i);
- p = (char *)malloc(i);
+ p = (char *)ei_chk_malloc(i);
i = 0; /* Reset */
ei_encode_list_header(p, &i, 2);
@@ -521,7 +532,7 @@ int erl_call(int argc, char **argv)
ei_encode_binary(NULL, &i, evalbuf, len);
ei_encode_empty_list(NULL, &i);
- p = (char *)malloc(i);
+ p = (char *)ei_chk_malloc(i);
i = 0; /* Reset */
ei_encode_list_header(p, &i, 1);
@@ -592,32 +603,6 @@ int erl_call(int argc, char **argv)
*
***************************************************************************/
-/*
- * Get host entry (by address or name)
- */
-/* FIXME: will fail on names like '2fun4you'. */
-static struct hostent* get_hostent(char *host)
-{
- if (isdigit((int)*host)) {
- struct in_addr ip_addr;
- int b1, b2, b3, b4;
- long addr;
-
- /* FIXME: Use inet_aton() (or inet_pton() and get v6 for free). */
- if (sscanf(host, "%d.%d.%d.%d", &b1, &b2, &b3, &b4) != 4) {
- return NULL;
- }
- addr = inet_addr(host);
- ip_addr.s_addr = htonl(addr);
-
- return ei_gethostbyaddr((char *)&ip_addr,sizeof(struct in_addr), AF_INET);
- }
-
- return ei_gethostbyname(host);
-} /* get_hostent */
-
-
-
/*
* This function does only return on success.
@@ -719,32 +704,28 @@ static void split_apply_string(char *str,
EAT(str);
len = str-begin;
- *mod = (char *) calloc(len + 1, sizeof(char));
+ *mod = (char *) ei_chk_calloc(len + 1, sizeof(char));
memcpy(*mod, begin, len);
SKIP_SPACE(str);
if (*str == '\0') {
- *fun = (char *) calloc(strlen(start)+1, sizeof(char));
- strcpy(*fun, start);
- *args = (char *) calloc(strlen(empty_list)+1, sizeof(char));
- strcpy(*args, empty_list);
+ *fun = ei_chk_strdup(start);
+ *args = ei_chk_strdup(empty_list);
return;
}
begin = str;
EAT(str);
len = str-begin;
- *fun = (char *) calloc(len + 1, sizeof(char));
+ *fun = (char *) ei_chk_calloc(len + 1, sizeof(char));
memcpy(*fun, begin, len);
SKIP_SPACE(str);
if (*str == '\0') {
- *args = (char *) calloc(strlen(empty_list)+1, sizeof(char));
- strcpy(*args, empty_list);
+ *args = ei_chk_strdup(empty_list);
return;
}
- *args = (char *) calloc(strlen(str) + 1, sizeof(char));
- strcpy(*args, str);
+ *args = ei_chk_strdup(str);
return;
@@ -760,7 +741,7 @@ static int read_stdin(char **buf)
int bsize = BUFSIZ;
int len = 0;
int i;
- char *tmp = (char *) malloc(bsize);
+ char *tmp = (char *) ei_chk_malloc(bsize);
while (1) {
if ((i = read(0, &tmp[len], bsize-len)) < 0) {
@@ -772,7 +753,7 @@ static int read_stdin(char **buf)
len += i;
if ((len+50) > bsize) {
bsize = len * 2;
- tmp = (char *) realloc(tmp, bsize);
+ tmp = (char *) ei_chk_realloc(tmp, bsize);
} else {
continue;
}
@@ -809,10 +790,11 @@ static int get_module(char **mbuf, char **mname)
}
} /* while */
i = tmp - start;
- *mname = (char *) calloc(i+1, sizeof(char));
+ *mname = (char *) ei_chk_calloc(i+1, sizeof(char));
memcpy(*mname, start, i);
}
- free(mbuf); /* Allocated in read_stdin() */
+ if (*mbuf)
+ free(*mbuf); /* Allocated in read_stdin() */
return len;
@@ -904,3 +886,51 @@ static void initWinSock(void)
}
}
#endif
+
+
+/***************************************************************************
+ *
+ * Utility functions
+ *
+ ***************************************************************************/
+
+static void* ei_chk_malloc(size_t size)
+{
+ void *p = malloc(size);
+ if (p == NULL) {
+ fprintf(stderr,"erl_call: insufficient memory\n");
+ exit(1);
+ }
+ return p;
+}
+
+static void* ei_chk_calloc(size_t nmemb, size_t size)
+{
+ void *p = calloc(nmemb, size);
+ if (p == NULL) {
+ fprintf(stderr,"erl_call: insufficient memory\n");
+ exit(1);
+ }
+ return p;
+}
+
+static void* ei_chk_realloc(void *old, size_t size)
+{
+ void *p = realloc(old, size);
+ if (!p) {
+ fprintf(stderr, "erl_call: cannot reallocate %u bytes of memory from %p\n",
+ (unsigned) size, old);
+ exit (1);
+ }
+ return p;
+}
+
+static char* ei_chk_strdup(char *s)
+{
+ char *p = strdup(s);
+ if (p == NULL) {
+ fprintf(stderr,"erl_call: insufficient memory\n");
+ exit(1);
+ }
+ return p;
+}
diff --git a/lib/erl_interface/src/registry/reg_dump.c b/lib/erl_interface/src/registry/reg_dump.c
index 50a6949177..dfec96b43c 100644
--- a/lib/erl_interface/src/registry/reg_dump.c
+++ b/lib/erl_interface/src/registry/reg_dump.c
@@ -157,7 +157,7 @@ static int mn_send_delete(int fd, erlang_pid *mnesia, const char *key)
int len = strlen(key) + 32; /* 32 is a slight overestimate */
if (len > EISMALLBUF)
- if (!(dbuf = malloc(index)))
+ if (!(dbuf = malloc(len)))
return -1;
msgbuf = (dbuf ? dbuf : sbuf);
@@ -187,7 +187,7 @@ static int mn_send_write(int fd, erlang_pid *mnesia, const char *key, ei_reg_obj
int len = 32 + keylen + obj->size;
if (len > EISMALLBUF)
- if (!(dbuf = malloc(index)))
+ if (!(dbuf = malloc(len)))
return -1;
msgbuf = (dbuf ? dbuf : sbuf);
diff --git a/lib/erl_interface/src/registry/reg_restore.c b/lib/erl_interface/src/registry/reg_restore.c
index 27918d2364..aeb33c784a 100644
--- a/lib/erl_interface/src/registry/reg_restore.c
+++ b/lib/erl_interface/src/registry/reg_restore.c
@@ -266,7 +266,7 @@ int ei_reg_restore(int fd, ei_reg *reg, const char *mntab)
/* make sure receive buffer can handle largest expected message */
len = maxkey + maxobj + 512;
if (len > EISMALLBUF)
- if (!(dbuf = malloc(index))) {
+ if (!(dbuf = malloc(len))) {
ei_send_exit(fd,&self,&mnesia,"cannot allocate space for incoming data");
return -1;
}