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

📄 sockctl.c

📁 CFL是Unix下的通用抽象库,以简化Unix下的系统软件开发,CFL库中包含几个分组的函数和宏
💻 C
📖 第 1 页 / 共 2 页
字号:
    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  if(s->sfp)    {    fclose(s->sfp);    s->sfp = NULL;    }    return(TRUE);  }/* */static c_bool_t __C_socket_reopen(c_socket_t *s, int sd)  {  int flags, i, type, sz;  if(sd < 0)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }    if((flags = fcntl(sd, F_GETFL, 0)) == -1)    {    C_error_set_errno(C_EFCNTL);    return(FALSE);    }  /* get socket type */  sz = (int)sizeof(int);  if(getsockopt(sd, SOL_SOCKET, SO_TYPE, (char *)&type, &sz))    {    C_error_set_errno(C_ESOCKINFO);    return(FALSE);    }    for(i = 0; i < C_NET_MAXTYPE; i++)    if(type == __C_net_socktypes[i]) break;  if(i == C_NET_MAXTYPE)    {    C_error_set_errno(C_EBADTYPE);    return(FALSE);    }  s->sd = sd;  s->type = i;  s->state = C_NET_CONNECTED;  /* get socket's local address */  i = sizeof(struct sockaddr_in);  if(getsockname(s->sd, (struct sockaddr *)&(s->laddr), &i) < 0)    {    C_error_set_errno(C_ESOCKINFO);    return(FALSE);    }  /* get socket's remote address */  i = sizeof(struct sockaddr_in);  if(getpeername(sd, (struct sockaddr *)&(s->raddr), &i) < 0)    {    switch(errno)      {      case ENOTCONN:        s->state = C_NET_CREATED;        break;              default:	C_error_set_errno(C_ESOCKINFO);	return(FALSE);      }    }  /* get flags */  if(flags & O_NONBLOCK)    s->flags |= C_NET_MUNBLOCK;  return(TRUE);  }/* */c_socket_t *C_socket_reopen(int sd)  {  c_socket_t *s = C_new(c_socket_t);  if(!__C_socket_reopen(s, sd))    return(C_free(s));  return(s);  }/* */c_bool_t C_socket_reopen_s(c_socket_t *s, int sd)  {  if(!s)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  C_zero(s, c_socket_t);  return(__C_socket_reopen(s, sd));  }/* */c_bool_t C_socket_set_option(c_socket_t *s, uint_t option, c_bool_t flag,                             uint_t value)  {  if(! s)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  switch(option)    {    // block    case C_NET_OPT_BLOCK:      {      int flags;      if(s->state == C_NET_SHUTDOWN)	{	C_error_set_errno(C_EBADSTATE);	return(FALSE);	}            if((flags = fcntl(s->sd, F_GETFL, 0)) == -1)	{	C_error_set_errno(C_EFCNTL);	return(FALSE);	}            flag ? (flags &= ~O_NONBLOCK) : (flags |= O_NONBLOCK);      flag ? (s->flags &= ~C_NET_MUNBLOCK) : (s->flags |= C_NET_MUNBLOCK);      if(fcntl(s->sd, F_SETFL, flags) == -1)	{	C_error_set_errno(C_EFCNTL);	return(FALSE);	}      return(TRUE);      }    // linger          case C_NET_OPT_LINGER:      {      struct linger l;      l.l_onoff = (flag ? 1 : 0);      l.l_linger = value;      if(setsockopt(s->sd, SOL_SOCKET, SO_LINGER, (char *)&l,		    sizeof(struct linger)) != 0)	{	C_error_set_errno(C_ESOCKINFO);	return(FALSE);	}      return(TRUE);      }    // reuse address          case C_NET_OPT_REUSEADDR:      {      int v = flag;            if(setsockopt(s->sd, SOL_SOCKET, SO_REUSEADDR, (char *)&v, sizeof(int))         != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);        }            return(TRUE);      }      // oob data inline    case C_NET_OPT_OOBINLINE:      {      int v = flag;      if(setsockopt(s->sd, SOL_SOCKET, SO_OOBINLINE, (char *)&v, sizeof(int))         != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);        }            return(TRUE);            }    // keepalive    case C_NET_OPT_KEEPALIVE:      {      int v = flag;      if(setsockopt(s->sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, sizeof(int))         != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);        }            return(TRUE);            }    // recv buffer    case C_NET_OPT_RECVBUF:      {      int v = (int)value;      if(setsockopt(s->sd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(int))         != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);        }            return(TRUE);            }    // send buffer    case C_NET_OPT_SENDBUF:      {      int v = (int)value;      if(setsockopt(s->sd, SOL_SOCKET, SO_SNDBUF, (char *)&v, sizeof(int))         != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);        }            return(TRUE);            }    // unknown          default:      C_error_set_errno(C_EINVAL);      return(FALSE);    }  }/* */c_bool_t C_socket_get_option(c_socket_t *s, uint_t option, c_bool_t *flag,                             uint_t *value)  {  if(!s || !flag || !value)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  switch(option)    {    // block    case C_NET_OPT_BLOCK:      {      return(!(s->flags & C_NET_MUNBLOCK));      }    // linger    case C_NET_OPT_LINGER:      {      int sz = sizeof(struct linger);      struct linger l;      if(getsockopt(s->sd, SOL_SOCKET, SO_LINGER, (char *)&l, &sz) != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);                }      *flag = l.l_onoff ? TRUE : FALSE;      *value = (uint_t)l.l_linger;      return(TRUE);      }    // reuse address          case C_NET_OPT_REUSEADDR:      {      int sz = sizeof(int);      int v;            if(getsockopt(s->sd, SOL_SOCKET, SO_REUSEADDR, (char *)&v, &sz) != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);                }            *flag = v ? TRUE : FALSE;            return(TRUE);      }    // oob data inline          case C_NET_OPT_OOBINLINE:      {      int sz = sizeof(int);      int v;            if(getsockopt(s->sd, SOL_SOCKET, SO_OOBINLINE, (char *)&v, &sz) != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);                }            *flag = v ? TRUE : FALSE;            return(TRUE);      }    // keepalive    case C_NET_OPT_KEEPALIVE:      {      int sz = sizeof(int);      int v;            if(getsockopt(s->sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, &sz) != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);                }            *flag = v ? TRUE : FALSE;            return(TRUE);      }    // recv buffer    case C_NET_OPT_RECVBUF:      {      int sz = sizeof(int);      int v;      if(getsockopt(s->sd, SOL_SOCKET, SO_RCVBUF, (char *)&v, &sz) != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);        }      *value = (uint_t)v;            return(TRUE);            }    // send buffer    case C_NET_OPT_SENDBUF:      {      int sz = sizeof(int);      int v;      if(getsockopt(s->sd, SOL_SOCKET, SO_SNDBUF, (char *)&v, &sz) != 0)        {	C_error_set_errno(C_ESOCKINFO);        return(FALSE);        }      *value = (uint_t)v;            return(TRUE);            }    // unknown    default:      C_error_set_errno(C_EINVAL);      return(FALSE);    }  }/* */c_bool_t C_socket_mcast_join(c_socket_t *s, const char *addr)  {  struct ip_mreq mreq;  struct sockaddr_in saddr;  if(! s || !addr)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  if(!*addr)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  if(s->type != C_NET_UDP)    {    C_error_set_errno(C_EBADTYPE);    return(FALSE);    }    if(! __C_socket_addr2sock(&saddr, addr))    {    C_error_set_errno(C_EADDRINFO);    return(FALSE);    }    memcpy(&mreq.imr_multiaddr, &(saddr.sin_addr), sizeof(struct in_addr));  mreq.imr_interface.s_addr = htonl(INADDR_ANY);  if(setsockopt(s->sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)    {    C_error_set_errno(C_ESOCKINFO);    return(FALSE);    }    return(TRUE);  }/* */c_bool_t C_socket_mcast_leave(c_socket_t *s, const char *addr)  {  struct ip_mreq mreq;  struct sockaddr_in saddr;  if(! s || !addr)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  if(!*addr)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  if(s->type != C_NET_UDP)    {    C_error_set_errno(C_EBADTYPE);    return(FALSE);    }    if(! __C_socket_addr2sock(&saddr, addr))    {    C_error_set_errno(C_EADDRINFO);    return(FALSE);    }    memcpy(&mreq.imr_multiaddr, &(saddr.sin_addr), sizeof(struct in_addr));  mreq.imr_interface.s_addr = htonl(INADDR_ANY);  if(setsockopt(s->sd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))     < 0)    {    C_error_set_errno(C_ESOCKINFO);    return(FALSE);    }    return(TRUE);  }/* */c_bool_t C_socket_mcast_set_ttl(c_socket_t *s, c_byte_t ttl)  {  if(!s)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  if(s->type != C_NET_UDP)    {    C_error_set_errno(C_EBADTYPE);    return(FALSE);    }  if(setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)    {    C_error_set_errno(C_ESOCKINFO);    return(FALSE);    }  return(TRUE);  }/* */c_bool_t C_socket_mcast_set_loop(c_socket_t *s, c_bool_t loop)  {  u_char flag = (u_char)loop;    if(!s)    {    C_error_set_errno(C_EINVAL);    return(FALSE);    }  if(s->type != C_NET_UDP)    {    C_error_set_errno(C_EBADTYPE);    return(FALSE);    }  if(setsockopt(s->sd, IPPROTO_IP, IP_MULTICAST_LOOP, &flag, sizeof(flag)) < 0)    {    C_error_set_errno(C_ESOCKINFO);    return(FALSE);    }  return(TRUE);  }/* end of source file */

⌨️ 快捷键说明

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