mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-11-09 08:37:58 +08:00
2006-11-02 Steven Johnson <sjohnson@sakuraindustries.com>
* libnetworking/netdb.h, libnetworking/libc/gethostbyht.c, libnetworking/libc/gethostnamadr.c: This patch adds a functional gethostbyname_r to RTEMS. We were having problems with multiple threads calling gethostbyname, so we decided the best way to deal with it was to do it properly, rather than kludge up our code to make gethostbyname safe. We have found several slightly different parameter lists for this function, it does not seem to be standard. The one we used has the linux interface. In RTEMS there was an existing gethostbyname_r inside a #ifdef _THREAD_SAFE which was NOT Threadsafe, as this just called gethostbyname. So we have placed all of the additional code inside the #ifdef _THREAD_SAFE.
This commit is contained in:
1 parent
e1d578d8bc
commit
068c3ee1df
4 files changed
+349
-21
No files matched your search
@@ -1,3 +1,17 @@
|
||||
2006-11-02 Steven Johnson <sjohnson@sakuraindustries.com>
|
||||
|
||||
* libnetworking/netdb.h, libnetworking/libc/gethostbyht.c,
|
||||
libnetworking/libc/gethostnamadr.c: This patch adds a functional
|
||||
gethostbyname_r to RTEMS. We were having problems with multiple
|
||||
threads calling gethostbyname, so we decided the best way to deal
|
||||
with it was to do it properly, rather than kludge up our code to make
|
||||
gethostbyname safe. We have found several slightly different
|
||||
parameter lists for this function, it does not seem to be standard.
|
||||
The one we used has the linux interface. In RTEMS there was an
|
||||
existing gethostbyname_r inside a #ifdef _THREAD_SAFE which was NOT
|
||||
Threadsafe, as this just called gethostbyname. So we have placed all
|
||||
of the additional code inside the #ifdef _THREAD_SAFE.
|
||||
|
||||
2006-10-30 Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
PR 841/rtems
|
||||
|
||||
@@ -67,6 +67,7 @@ static char rcsid[] = "$Id$";
|
||||
#include <string.h>
|
||||
#include <arpa/nameser.h> /* XXX */
|
||||
#include <resolv.h> /* XXX */
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
@@ -78,6 +79,10 @@ static u_char host_addr[16]; /* IPv4 or IPv6 */
|
||||
static char *h_addr_ptrs[2];
|
||||
static int stayopen = 0;
|
||||
|
||||
static char* hostmap = NULL;
|
||||
static unsigned int hostlen = 0;
|
||||
static char *cur;
|
||||
|
||||
void
|
||||
_sethosthtent(f)
|
||||
int f;
|
||||
@@ -200,3 +205,115 @@ _gethostbyhtaddr(addr, len, af)
|
||||
endhostent();
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _THREAD_SAFE
|
||||
|
||||
static int isblank ( int ch )
|
||||
{
|
||||
return ch == ' ' || ch == '\t';
|
||||
}
|
||||
|
||||
struct hostent* gethostent_r(char* buf, int len)
|
||||
{
|
||||
char *dest;
|
||||
struct hostent* pe=(struct hostent*)buf;
|
||||
char* last;
|
||||
char* max=buf+len;
|
||||
int aliasidx;
|
||||
int curlen;
|
||||
|
||||
|
||||
if (hostf<0) return 0;
|
||||
fseek(hostf,0,SEEK_END);
|
||||
curlen=ftell(hostf);
|
||||
fseek(hostf,0,SEEK_SET);
|
||||
|
||||
if (curlen > hostlen) {
|
||||
if (hostmap) {
|
||||
hostmap = realloc(hostmap,curlen);
|
||||
}
|
||||
else {
|
||||
hostmap = malloc(curlen);
|
||||
}
|
||||
}
|
||||
hostlen = curlen;
|
||||
|
||||
if (hostmap) {
|
||||
if (fread(hostmap,hostlen,1,hostf) != hostlen) {
|
||||
hostmap=0; goto error;
|
||||
}
|
||||
cur=hostmap;
|
||||
}
|
||||
last=hostmap+hostlen;
|
||||
again:
|
||||
if ((size_t)len<sizeof(struct hostent)+11*sizeof(char*)) goto nospace;
|
||||
dest=buf+sizeof(struct hostent);
|
||||
pe->h_name=0;
|
||||
pe->h_aliases=(char**)dest; pe->h_aliases[0]=0; dest+=10*sizeof(char*);
|
||||
pe->h_addr_list=(char**)dest; dest+=2*sizeof(char**);
|
||||
if (cur>=last) return 0;
|
||||
if (*cur=='#' || *cur=='\n') goto parseerror;
|
||||
/* first, the ip number */
|
||||
pe->h_name=cur;
|
||||
while (cur<last && !isspace(*cur)) cur++;
|
||||
if (cur>=last) return 0;
|
||||
if (*cur=='\n') goto parseerror;
|
||||
{
|
||||
char save=*cur;
|
||||
*cur=0;
|
||||
pe->h_addr_list[0]=dest;
|
||||
pe->h_addr_list[1]=0;
|
||||
if (max-dest<16) goto nospace;
|
||||
if (inet_pton(AF_INET6,pe->h_name,dest)>0) {
|
||||
pe->h_addrtype=AF_INET6;
|
||||
pe->h_length=16;
|
||||
dest+=16;
|
||||
} else if (inet_pton(AF_INET,pe->h_name,dest)>0) {
|
||||
pe->h_addrtype=AF_INET;
|
||||
pe->h_length=4;
|
||||
dest+=4;
|
||||
} else {
|
||||
*cur=save;
|
||||
goto parseerror;
|
||||
}
|
||||
*cur=save;
|
||||
}
|
||||
++cur;
|
||||
/* now the aliases */
|
||||
for (aliasidx=0;aliasidx<9;++aliasidx) {
|
||||
while (cur<last && isblank(*cur)) ++cur;
|
||||
pe->h_aliases[aliasidx]=cur;
|
||||
while (cur<last && !isspace(*cur)) ++cur;
|
||||
{
|
||||
char *from=pe->h_aliases[aliasidx];
|
||||
int len=cur-from;
|
||||
if (max-dest<len+2) goto nospace;
|
||||
pe->h_aliases[aliasidx]=dest;
|
||||
memmove(dest,from,(size_t)(cur-from));
|
||||
dest+=len;
|
||||
*dest=0; ++dest;
|
||||
}
|
||||
if (*cur=='\n') { ++cur; ++aliasidx; break; }
|
||||
if (cur>=last || !isblank(*cur)) break;
|
||||
cur++;
|
||||
}
|
||||
pe->h_aliases[aliasidx]=0;
|
||||
pe->h_name=pe->h_aliases[0];
|
||||
pe->h_aliases++;
|
||||
return pe;
|
||||
parseerror:
|
||||
while (cur<last && *cur!='\n') cur++;
|
||||
cur++;
|
||||
goto again;
|
||||
nospace:
|
||||
errno=ERANGE;
|
||||
goto __error;
|
||||
error:
|
||||
errno=ENOMEM;
|
||||
__error:
|
||||
if (hostmap!=NULL) free(hostmap);
|
||||
hostmap=NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -160,6 +160,16 @@ void setnetent(int);
|
||||
void setprotoent(int);
|
||||
void setservent(int);
|
||||
|
||||
#ifdef _THREAD_SAFE
|
||||
struct hostent* gethostent_r(char* buf, int len);
|
||||
int gethostbyname_r(const char* name,
|
||||
struct hostent* result,
|
||||
char *buf,
|
||||
int buflen,
|
||||
struct hostent **RESULT,
|
||||
int *h_errnop) ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PRIVATE functions specific to the FreeBSD implementation
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user