diff options
Diffstat (limited to 'lib/erl_interface/src/connect/ei_connect.c')
| -rw-r--r-- | lib/erl_interface/src/connect/ei_connect.c | 44 | 
1 files changed, 35 insertions, 9 deletions
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c index f5034ca3e8..9df4fa3b6c 100644 --- a/lib/erl_interface/src/connect/ei_connect.c +++ b/lib/erl_interface/src/connect/ei_connect.c @@ -138,6 +138,11 @@ static int recv_name(int fd,  		     unsigned *version,  		     unsigned *flags, ErlConnect *namebuf, unsigned ms); +static struct hostent* +dyn_gethostbyname_r(const char *name, struct hostent *hostp, char **buffer_p, +                    int buflen, int *h_errnop); + +  /***************************************************************************   * @@ -480,10 +485,14 @@ int ei_connect_xinit(ei_cnode* ec, const char *thishostname,  int ei_connect_init(ei_cnode* ec, const char* this_node_name,  		    const char *cookie, short creation)  { -    struct hostent *hp;      char thishostname[EI_MAXHOSTNAMELEN+1];      char thisnodename[MAXNODELEN+1];      char thisalivename[EI_MAXALIVELEN+1]; +    struct hostent host, *hp; +    char buffer[1024]; +    char *buf = buffer; +    int ei_h_errno; +    int res;  #ifdef __WIN32__      if (!initWinSock()) { @@ -517,10 +526,13 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name,  	strcpy(thisalivename, this_node_name);      } -    if ((hp = ei_gethostbyname(thishostname)) == 0) { +    hp = dyn_gethostbyname_r(thishostname,&host,&buf,sizeof(buffer),&ei_h_errno); +    if (hp == NULL) {  	/* Looking up IP given hostname fails. We must be on a standalone  	   host so let's use loopback for communication instead. */ -	if ((hp = ei_gethostbyname("localhost")) == 0) { +	hp = dyn_gethostbyname_r("localhost", &host, &buf, sizeof(buffer), +                                 &ei_h_errno); +        if (hp == NULL) {  #ifdef __WIN32__  	    char reason[1024]; @@ -549,8 +561,11 @@ int ei_connect_init(ei_cnode* ec, const char* this_node_name,  	    sprintf(thisnodename, "%s@%s", this_node_name, hp->h_name);  	}      } -    return ei_connect_xinit(ec, thishostname, thisalivename, thisnodename, -			    (struct in_addr *)*hp->h_addr_list, cookie, creation); +    res = ei_connect_xinit(ec, thishostname, thisalivename, thisnodename, +                           (struct in_addr *)*hp->h_addr_list, cookie, creation); +    if (buf != buffer) +        free(buf); +    return res;  } @@ -595,6 +610,13 @@ struct hostent *dyn_gethostbyname_r(const char *name,  				    int buflen,  				    int *h_errnop)  { +#ifdef __WIN32__ +    /* +     * Apparently ei_gethostbyname_r not implemented for Windows (?) +     * Fall back on ei_gethostbyname like before. +     */ +    return ei_gethostbyname(name); +#else      char* buf = *buffer_p;      struct hostent *hp; @@ -629,6 +651,7 @@ struct hostent *dyn_gethostbyname_r(const char *name,          }      }      return hp; +#endif  }    /*  @@ -999,7 +1022,7 @@ int ei_do_receive_msg(int fd, int staticbuffer_p,  	erl_errno = EMSGSIZE;  	return ERL_ERROR;      } -    x->index = x->buffsz; +    x->index = msglen;      switch (msg->msgtype) {	/* FIXME does not handle trace tokens and monitors */      case ERL_SEND:      case ERL_REG_SEND: @@ -1357,11 +1380,14 @@ static int recv_status(int fd, unsigned ms)  		      "<- RECV_STATUS socket read failed (%d)", rlen);  	goto error;      } -    if (rlen == 3 && buf[0] == 's' && buf[1] == 'o' &&  -	buf[2] == 'k') { + +    EI_TRACE_CONN2("recv_status", +                   "<- RECV_STATUS (%.*s)", (rlen>20 ? 20 : rlen), buf); + +    if (rlen >= 3 && buf[0] == 's' && buf[1] == 'o' && buf[2] == 'k') { +        /* Expecting "sok" or "sok_simultaneous" */  	if (!is_static)  	    free(buf); -	EI_TRACE_CONN0("recv_status","<- RECV_STATUS (ok)");  	return 0;      }  error:  | 
