Ignore:
Timestamp:
Nov 2, 2006, 9:48:41 PM (15 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
918b7a9
Parents:
e1d578d8
Message:

2006-11-02 Steven Johnson <sjohnson@…>

  • 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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libnetworking/libc/gethostbyht.c

    re1d578d8 r068c3ee1  
    6868#include <arpa/nameser.h>       /* XXX */
    6969#include <resolv.h>             /* XXX */
     70#include <sys/fcntl.h>
    7071
    7172#define MAXALIASES      35
     
    7879static char *h_addr_ptrs[2];
    7980static int stayopen = 0;
     81
     82static char* hostmap = NULL;
     83static unsigned int hostlen = 0;
     84static char *cur;
    8085
    8186void
     
    201206        return (p);
    202207}
     208
     209
     210#ifdef _THREAD_SAFE
     211
     212static int isblank ( int ch )
     213{
     214    return ch == ' '  ||  ch == '\t';
     215}
     216
     217struct hostent* gethostent_r(char* buf, int len)
     218{
     219  char  *dest;
     220  struct hostent* pe=(struct hostent*)buf;
     221  char*  last;
     222  char*  max=buf+len;
     223  int    aliasidx;
     224  int    curlen;
     225 
     226   
     227  if (hostf<0) return 0;
     228  fseek(hostf,0,SEEK_END);
     229  curlen=ftell(hostf);
     230  fseek(hostf,0,SEEK_SET);
     231 
     232  if (curlen > hostlen) {
     233    if (hostmap) {
     234      hostmap = realloc(hostmap,curlen);
     235    }
     236    else {
     237      hostmap = malloc(curlen);
     238    }
     239  }
     240  hostlen = curlen;
     241 
     242  if (hostmap) {
     243    if (fread(hostmap,hostlen,1,hostf) != hostlen) {
     244        hostmap=0; goto error;
     245    }
     246    cur=hostmap;
     247  }
     248  last=hostmap+hostlen;
     249again:
     250  if ((size_t)len<sizeof(struct hostent)+11*sizeof(char*)) goto nospace;
     251  dest=buf+sizeof(struct hostent);
     252  pe->h_name=0;
     253  pe->h_aliases=(char**)dest; pe->h_aliases[0]=0; dest+=10*sizeof(char*);
     254  pe->h_addr_list=(char**)dest; dest+=2*sizeof(char**);
     255  if (cur>=last) return 0;
     256  if (*cur=='#' || *cur=='\n') goto parseerror;
     257  /* first, the ip number */
     258  pe->h_name=cur;
     259  while (cur<last && !isspace(*cur)) cur++;
     260  if (cur>=last) return 0;
     261  if (*cur=='\n') goto parseerror;
     262  {
     263    char save=*cur;
     264    *cur=0;
     265    pe->h_addr_list[0]=dest;
     266    pe->h_addr_list[1]=0;
     267    if (max-dest<16) goto nospace;
     268    if (inet_pton(AF_INET6,pe->h_name,dest)>0) {
     269      pe->h_addrtype=AF_INET6;
     270      pe->h_length=16;
     271      dest+=16;
     272    } else if (inet_pton(AF_INET,pe->h_name,dest)>0) {
     273      pe->h_addrtype=AF_INET;
     274      pe->h_length=4;
     275      dest+=4;
     276    } else {
     277      *cur=save;
     278      goto parseerror;
     279    }
     280    *cur=save;
     281  }
     282  ++cur;
     283  /* now the aliases */
     284  for (aliasidx=0;aliasidx<9;++aliasidx) {
     285    while (cur<last && isblank(*cur)) ++cur;
     286    pe->h_aliases[aliasidx]=cur;
     287    while (cur<last && !isspace(*cur)) ++cur;
     288    {
     289      char *from=pe->h_aliases[aliasidx];
     290      int len=cur-from;
     291      if (max-dest<len+2) goto nospace;
     292      pe->h_aliases[aliasidx]=dest;
     293      memmove(dest,from,(size_t)(cur-from));
     294      dest+=len;
     295      *dest=0; ++dest;
     296    }
     297    if (*cur=='\n') { ++cur; ++aliasidx; break; }
     298    if (cur>=last || !isblank(*cur)) break;
     299    cur++;
     300  }
     301  pe->h_aliases[aliasidx]=0;
     302  pe->h_name=pe->h_aliases[0];
     303  pe->h_aliases++;
     304  return pe;
     305parseerror:
     306  while (cur<last && *cur!='\n') cur++;
     307  cur++;
     308  goto again;
     309nospace:
     310  errno=ERANGE;
     311  goto __error;
     312error:
     313  errno=ENOMEM;
     314__error:
     315  if (hostmap!=NULL) free(hostmap);
     316  hostmap=NULL;
     317  return 0;
     318}
     319#endif
Note: See TracChangeset for help on using the changeset viewer.