⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getxxbyyy_r.c

📁 CFL是Unix下的通用抽象库,以简化Unix下的系统软件开发,CFL库中包含几个分组的函数和宏
💻 C
字号:
/* ----------------------------------------------------------------------------   CFL - A C Foundation Library   Copyright (C) 1994-2003  Mark A Lindner   This file is part of CFL.      This library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public   License as published by the Free Software Foundation; either   version 2 of the License, or (at your option) any later version.      This library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.      You should have received a copy of the GNU Library General Public   License along with this library; if not, write to the Free   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   ----------------------------------------------------------------------------   $Log: getXXbyYY_r.c,v $   Revision 1.2  2003/05/07 04:47:48  markl   fixed pad calculation   Revision 1.1  2003/03/14 09:02:30  markl   Code cleanup & bug fixes.   ----------------------------------------------------------------------------*//* gethostbyname_r, gethostbyaddr_r, getservbyname_r, and * getservbyport_r are particularly non-portable. As of this writing, * they are available on Solaris and Linux, but not on OS X. The Linux * versions have the POSIX-style parameter list while the Solaris * versions are slightly different (they have one less parameter). To * make things even more interesting, on Linux these functions live in * glibc while on Solaris the gethostby*_r functions are in the `nsl' * library and the getservby*_r functions are in the `socket' library * (even though they are all declared in `netdb.h'). * * To simplify the code that uses these functions, we declare our own * versions of them. If the host system has the POSIX-style functions, * we simply #define our functions to be aliases for the native * functions. If the host system has the Solaris-style functions * (presumably because the host system *is* Solaris) then our * functions are simple wrappers around the native functions to * provide a POSIX-style interface. Finally, if native functions are * not available at all, we emulate them by calling their * non-reentrant counterparts and doing a deep-copy of the results * into the user-specified buffers. In the multi-threaded version of * the library, we additionally wrap these calls in mutex locks to * provide thread-safety. *//* Feature test switches */#include "config.h"/* System headers */#include <string.h>#include <errno.h>#ifdef THREADED_LIBRARY#include <pthread.h>#endif/* Local headers */#include "getXXbyYY_r.h"/* File scope variables */#if !( defined(HAVE_GETxxxxBYyyyy_R_POSIX) || defined(HAVE_GETxxxxBYyyyy_R_SUN))#ifdef THREADED_LIBRARYstatic pthread_mutex_t __C_getXXbyYY_r_mutex = PTHREAD_MUTEX_INITIALIZER;#endif#endif/* File scope functions */#if !(defined(HAVE_GETxxxxBYyyyy_R_POSIX) || defined(HAVE_GETxxxxBYyyyy_R_SUN))static int __C_copy_array(char **src, char *buf, size_t bufsz)  {  char *p = buf, **q, **w;  int alen, left = bufsz, pos = 0, off, pad, hl;  // compute the length of the pointer array first    for(alen = 0, q = src; *q; alen++, q++);  off = sizeof(char *) * ++alen;    if(left < off)    return(0);  // copy strings after the end of the space reserved for the array,  // while storing pointers to the copied strings in successive slots in  // that reserved space  left -= off;  pos += off;  p += off;  for(w = &buf, q = src; *q; q++, w++)    {    hl = strlen(*q) + 1;    if(left < hl)      return(0);    strncpy(p, *q, hl);    *w = p;    p += hl;    left -= hl;    off += hl;    }  *w = NULL;  // skip enough bytes to word-align next write    pad = sizeof(void *) - (off % sizeof(void *));  if(left < pad)    return(0);  off += pad;  return(off);  }/* */static struct servent * __C_copy_struct_servent(struct servent *rse,                                                struct servent *result,                                                char *buffer, int buflen)  {  char *p = buffer, **q;  int left = buflen, hl, len = 0, r;  // copy the servent structure  memcpy((void *)result, (void *)rse, sizeof(struct servent));  // copy the canonical name  hl = strlen(rse->s_name) + 1;  if(left < hl)    return(NULL);  strncpy(p, rse->s_name, hl);  len += hl;  p += hl;  left -= hl;  // copy the array of aliases  r = __C_copy_array(rse->s_aliases, p, left);  if(r == 0)    return(NULL);  len += r;  p += r;  left -= r;  // copy the protocol name  hl = strlen(rse->s_proto) + 1;  if(left < hl)    return(NULL);  strncpy(p, rse->s_proto, hl);    return(result);  }/* */static struct hostent * __C_copy_struct_hostent(struct hostent *rhe,                                                struct hostent *result,                                                char *buffer, int buflen)  {  char *p = buffer, **q;  int left = buflen, hl, len = 0, r;  // copy the hostent structure    memcpy((void *)result, (void *)rhe, sizeof(struct hostent));    // copy the canonical name  hl = strlen(rhe->h_name) + 1;  if(left < hl)    return(NULL);  strncpy(p, rhe->h_name, hl);  len += hl;  p += hl;  left -= hl;  // copy the array of aliases  r = __C_copy_array(rhe->h_aliases, p, left);  if(r == 0)    return(NULL);  len += r;  p += r;  left -= r;  // copy the array of addresses  r = __C_copy_array(rhe->h_addr_list, p, left);  if(r == 0)    return(NULL);  return(result);  }#endif/* */#if defined(HAVE_GETxxxxBYyyyy_R_SUN)struct hostent *C_gethostbyname_r(const char *name, struct hostent *ret,                                  char *buffer, int buflen,                                  struct hostent **result, int *h_errnop)  {  struct hostent *r = gethostbyname_r(name, ret, buffer, buflen, h_errnop);  if(result != NULL)    *result = r;  return(r);  }/* */struct hostent *C_gethostbyaddr_r(const char *addr, int length, int type,                                  struct hostent *ret, char *buffer,                                  int buflen, struct hostent **result,                                  int *h_errnop)  {  struct hostent *r = gethostbyaddr_r(addr, length, type, ret, buffer, buflen,                                      h_errnop);  if(result != NULL)    *result = r;  return(r);  }/* */struct servent *C_getservbyname_r(const char *name, const char *proto,                                  struct servent *ret, char *buffer,                                  int buflen, struct servent **result)  {  struct servent *r = getservbyname_r(name, proto, ret, buffer, buflen);  if(result != NULL)    *result = r;  return(r);  }/* */struct servent *C_getservbyport_r(int port, const char *proto,                                  struct servent *ret, char *buffer,                                  int buflen, struct servent **result)  {  struct servent *r = getservbyport_r(port, proto, ret, buffer, buflen);  if(result != NULL)    *result = r;  return(r);  }#elif !defined(HAVE_GETxxxxBYyyyy_R_POSIX)/* */struct hostent *C_gethostbyname_r(const char *name, struct hostent *ret,                                  char *buffer, int buflen,                                  struct hostent **result, int *h_errnop)  {  struct hostent *rhe;#ifdef THREADED_LIBRARY  pthread_mutex_lock(&__C_getXXbyYY_r_mutex);#endif  rhe = gethostbyname(name);  if(! rhe)    {    *h_errnop = h_errno;    ret = NULL;    }  else if(! __C_copy_struct_hostent(rhe, ret, buffer, buflen))    {    errno = ERANGE;    ret = NULL;    }  if(result)    *result = ret;    #ifdef THREADED_LIBRARY  pthread_mutex_unlock(&__C_getXXbyYY_r_mutex);#endif  return(ret);  }/* */struct hostent *C_gethostbyaddr_r(const char *addr, int length, int type,                                  struct hostent *ret, char *buffer,                                  int buflen, struct hostent **result,                                  int *h_errnop)  {  struct hostent *rhe;#ifdef THREADED_LIBRARY  pthread_mutex_lock(&__C_getXXbyYY_r_mutex);#endif  rhe = gethostbyaddr(addr, length, type);  if(! rhe)    {    *h_errnop = h_errno;    ret = NULL;    }  else if(! __C_copy_struct_hostent(rhe, ret, buffer, buflen))    {    errno = ERANGE;    ret = NULL;    }  if(result)    *result = ret;#ifdef THREADED_LIBRARY  pthread_mutex_unlock(&__C_getXXbyYY_r_mutex);#endif  return(ret);  }/* */struct servent *C_getservbyname_r(const char *name, const char *proto,                                  struct servent *ret, char *buffer,                                  int buflen, struct servent **result)  {  struct servent *rse;#ifdef THREADED_LIBRARY  pthread_mutex_lock(&__C_getXXbyYY_r_mutex);#endif  rse = getservbyname(name, proto);  if(! rse)    ret = NULL;  else if(! __C_copy_struct_servent(rse, ret, buffer, buflen))    {    errno = ERANGE;    ret = NULL;    }  if(result)    *result = ret;  #ifdef THREADED_LIBRARY  pthread_mutex_unlock(&__C_getXXbyYY_r_mutex);#endif  return(ret);  }/* */struct servent *C_getservbyport_r(int port, const char *proto,                                  struct servent *ret, char *buffer,                                  int buflen, struct servent **result)  {  struct servent *rse;#ifdef THREADED_LIBRARY  pthread_mutex_lock(&__C_getXXbyYY_r_mutex);#endif  rse = getservbyport(port, proto);  if(! rse)    ret = NULL;  else if(! __C_copy_struct_servent(rse, ret, buffer, buflen))    {    errno = ERANGE;    ret = NULL;    }  if(result)    *result = ret;  #ifdef THREADED_LIBRARY  pthread_mutex_unlock(&__C_getXXbyYY_r_mutex);#endif  return(ret);  }#endif/* end of source file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -