跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • C 语言_REENTRANT 这个宏
未分類
15 5 月 2020

C 语言_REENTRANT 这个宏

C 语言_REENTRANT 这个宏

資深大佬 : salamanderMH 3

问题

看了下这个库的源码,一个 FTP 的库,然后我看了下FtpConnect方法的实现,看到用到了_REENTRANT,不太清楚为什么要用这个宏,似乎是多线程有用

GLOBALDEF int FtpConnect(const char *host, netbuf **nControl) {     int sControl;     struct sockaddr_in sin;     int on=1;     netbuf *ctrl;     char *lhost;     char *pnum;      memset(&sin,0,sizeof(sin));     sin.sin_family = AF_INET;     lhost = strdup(host);     pnum = strchr(lhost,':');     if (pnum == NULL)  pnum = "ftp";     else  *pnum++ = '';     if (isdigit(*pnum))  sin.sin_port = htons(atoi(pnum));     else     {  struct servent *pse; #if _REENTRANT  struct servent se;  char tmpbuf[TMP_BUFSIZ];  int i;  if ( ( i = getservbyname_r(pnum,"tcp",&se,tmpbuf,TMP_BUFSIZ,&pse) ) != 0 )  {      errno = i;      if ( ftplib_debug )   perror("getservbyname_r");      free(lhost);      return 0;  } #else  if ((pse = getservbyname(pnum,"tcp") ) == NULL )  {      if ( ftplib_debug )   perror("getservbyname");      free(lhost);      return 0;  } #endif  sin.sin_port = pse->s_port;     }     if ((sin.sin_addr.s_addr = inet_addr(lhost)) == INADDR_NONE)     {  struct hostent *phe; #ifdef _REENTRANT  struct hostent he;  char tmpbuf[TMP_BUFSIZ];  int i, herr;  if ( ( ( i = gethostbyname_r( lhost, &he, tmpbuf, TMP_BUFSIZ, &phe, &herr ) ) != 0 ) ||       ( phe == NULL ) )  {      if ( ftplib_debug )   fprintf(stderr, "gethostbyname: %sn", hstrerror(herr));      free(lhost);      return 0;  } #else      if ((phe = gethostbyname(lhost)) == NULL)      {      if (ftplib_debug)   fprintf(stderr, "gethostbyname: %sn", hstrerror(h_errno));      free(lhost);      return 0;      } #endif      memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);     }     free(lhost);     sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);     if (sControl == -1)     {  if (ftplib_debug)      perror("socket");  return 0;     }     if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR,      SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1)     {  if (ftplib_debug)      perror("setsockopt");  net_close(sControl);  return 0;     }     if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1)     {  if (ftplib_debug)      perror("connect");  net_close(sControl);  return 0;     }     ctrl = calloc(1,sizeof(netbuf));     if (ctrl == NULL)     {  if (ftplib_debug)      perror("calloc");  net_close(sControl);  return 0;     }     ctrl->buf = malloc(FTPLIB_BUFSIZ);     if (ctrl->buf == NULL)     {  if (ftplib_debug)      perror("calloc");  net_close(sControl);  free(ctrl);  return 0;     }     ctrl->handle = sControl;     ctrl->dir = FTPLIB_CONTROL;     ctrl->ctrl = NULL;     ctrl->data = NULL;     ctrl->cmode = FTPLIB_DEFMODE;     ctrl->idlecb = NULL;     ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0;     ctrl->idlearg = NULL;     ctrl->xfered = 0;     ctrl->xfered1 = 0;     ctrl->cbbytes = 0;     if (readresp('2', ctrl) == 0)     {  net_close(sControl);  free(ctrl->buf);  free(ctrl);  return 0;     }     *nControl = ctrl;     return 1; } 

大佬有話說 (4)

  • 資深大佬 : codehz

    只是用作特性开关吧,某个地方定义之后就用可重入的那块,不然就普通的

  • 資深大佬 : shiny2017

    主要是区分比如: getservbyname_r 与 gethostbyname 之类的接口, 不带_r 后缀的就是不可重入的, 比如 gethostbyname 使用了全局变量或者静态变量, 如果进程的多个线程同时调用又不加锁的情况下, 都更新相同的全局变量会产生问题的.

  • 主 資深大佬 : salamanderMH

    @shiny2017 谢谢,那看起来`gethostbyname`和`getservbyname`有线程安全问题。

  • 主 資深大佬 : salamanderMH

    SO 上搜了下,确实有 thread safety 的问题:
    https://stackoverflow.com/questions/25951925/gethostbyname-processes-resolving-consistently-even-from-different-threads

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具