diff options
Diffstat (limited to 'lib/erl_interface/src')
27 files changed, 364 insertions, 401 deletions
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c index d2d0a7e7c1..99ccba0686 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 @@ -1323,7 +1331,8 @@ static int send_name_or_challenge(int fd, char *nodename, put32be(s, (DFLAG_EXTENDED_REFERENCES | 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..7d72ddeeae 100644 --- a/lib/erl_interface/src/connect/eirecv.c +++ b/lib/erl_interface/src/connect/eirecv.c @@ -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)) @@ -197,7 +197,7 @@ ei_recv_internal (int fd, break; case ERL_NODE_LINK: /* { NODE_LINK } */ - if (ei_tracelevel > 1) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; break; default: 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_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_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_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c index 4b5f28178f..a6c2f64dd0 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: @@ -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; @@ -1696,12 +1681,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 +1884,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/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c index 7b95ff232f..75c5dc9460 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,11 +45,8 @@ 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); memcpy(term->value.atom_name, s, len); diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c index 08235d0ebe..b35421d4b2 100644 --- a/lib/erl_interface/src/misc/ei_format.c +++ b/lib/erl_interface/src/misc/ei_format.c @@ -106,6 +106,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 +151,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)) 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..14bea5e01f 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% * @@ -400,6 +400,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; } |