Added thread-safe function gethostbyname_r (as in glibc)

This commit is contained in:
goldsimon 2007-11-18 16:36:34 +00:00
parent 4e398e2aa9
commit 9dd4ad6c1f
3 changed files with 68 additions and 1 deletions

View File

@ -28,7 +28,7 @@ HISTORY
2007-11-16 Simon Goldschmidt
* api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential
dns resolver function for netconn api (netconn_gethostbyname) and socket api
(gethostbyname).
(gethostbyname/gethostbyname_r).
2007-11-15 Jim Pettinato, Frédéric Bernon
* opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name

View File

@ -86,6 +86,14 @@ struct lwip_setgetsockopt_data {
err_t err;
};
#if LWIP_DNS
struct gethostbyname_r_helper {
struct ip_addr *addrs;
struct ip_addr addr;
char *aliases;
};
#endif /* LWIP_DNS */
static struct lwip_socket sockets[NUM_SOCKETS];
static struct lwip_select_cb *select_cb_list;
@ -1860,6 +1868,62 @@ lwip_gethostbyname(const char *name)
return &s_hostent;
}
int
lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop)
{
err_t err;
struct gethostbyname_r_helper *h;
char *hostname;
size_t namelen;
if (result == NULL) {
/* not all arguments given */
return EINVAL;
}
/* first thing to do: set *result to nothing */
*result = NULL;
if ((name == NULL) || (ret == NULL) || (buf == 0)) {
/* not all arguments given */
return EINVAL;
}
namelen = strlen(name);
if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) {
/* buf can't hold the data needed + a copy of name */
return ERANGE;
}
h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf);
hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper);
/* query host IP address */
err = netconn_gethostbyname(name, &(h->addr));
if (err != ERR_OK) {
LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err));
return ENSRNOTFOUND;
}
/* copy the hostname into buf */
memcpy(hostname, name, namelen);
hostname[namelen] = 0;
/* fill hostent */
h->addrs = &(h->addr);
h->aliases = NULL;
ret->h_name = (char*)hostname;
ret->h_aliases = &(h->aliases);
ret->h_addrtype = AF_INET;
ret->h_length = sizeof(struct ip_addr);
ret->h_addr_list = (char**)&(h->addrs);
/* set result != NULL */
*result = ret;
/* return success */
return 0;
}
#endif /* LWIP_DNS*/
#endif /* LWIP_SOCKET */

View File

@ -315,6 +315,8 @@ int lwip_ioctl(int s, long cmd, void *argp);
#if LWIP_DNS
struct hostent *lwip_gethostbyname(const char *name);
int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop);
#endif /* LWIP_DNS */
#if LWIP_COMPAT_SOCKETS
@ -336,6 +338,7 @@ struct hostent *lwip_gethostbyname(const char *name);
#define select(a,b,c,d,e) lwip_select(a,b,c,d,e)
#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c)
#define gethostbyname(a) lwip_gethostbyname(a)
#define gethostbyname_r(a,b,c,d,e,f) lwip_gethostbyname_r(a,b,c,d,e,f)
#if LWIP_POSIX_SOCKETS_IO_NAMES
#define read(a,b,c) lwip_read(a,b,c)