ext/socket/extconf.rb


DEFINITIONS

This source file includes following functions.


   1  require 'mkmf'
   2  
   3  $CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len"
   4  
   5  case RUBY_PLATFORM
   6  when /bccwin32/
   7    test_func = "WSACleanup"
   8    have_library("ws2_32", "WSACleanup")
   9    have_func("closesocket")
  10  when /mswin32|mingw/
  11    test_func = "WSACleanup"
  12    have_library("wsock32", "WSACleanup")
  13    have_func("closesocket")
  14  when /cygwin/
  15    test_func = "socket"
  16  when /beos/
  17    test_func = "socket"
  18    have_library("net", "socket")
  19    have_func("closesocket")
  20  when /i386-os2_emx/
  21    test_func = "socket"
  22    have_library("socket", "socket")
  23  else
  24    test_func = "socket"
  25    have_library("nsl", "t_open")
  26    have_library("socket", "socket")
  27  end
  28  
  29  $ipv6 = false
  30  default_ipv6 = /cygwin/ !~ RUBY_PLATFORM
  31  if enable_config("ipv6", default_ipv6)
  32    if try_link(<<EOF)
  33  #include <sys/types.h>
  34  #include <sys/socket.h>
  35  main()
  36  {
  37    socket(AF_INET6, SOCK_STREAM, 0);
  38  }
  39  EOF
  40      $CFLAGS+=" -DENABLE_IPV6"
  41      $ipv6 = true
  42    end
  43  end
  44  
  45  $ipv6type = nil
  46  $ipv6lib = nil
  47  $ipv6libdir = nil
  48  $ipv6trylibc = nil
  49  if $ipv6
  50    if macro_defined?("IPV6_INRIA_VERSION", <<EOF)
  51  #include <netinet/in.h>
  52  EOF
  53      $ipv6type = "inria"
  54      $CFLAGS="-DINET6 "+$CFLAGS
  55    elsif macro_defined?("__KAME__", <<EOF)
  56  #include <netinet/in.h>
  57  EOF
  58      $ipv6type = "kame"
  59      $ipv6lib="inet6"
  60      $ipv6libdir="/usr/local/v6/lib"
  61      $ipv6trylibc=true
  62      $CFLAGS="-DINET6 "+$CFLAGS
  63    elsif File.directory? "/usr/inet6"
  64      $ipv6type = "linux"
  65      $ipv6lib="inet6"
  66      $ipv6libdir="/usr/inet6/lib"
  67      $CFLAGS="-DINET6 -I/usr/inet6/include "+$CFLAGS
  68    elsif macro_defined?("_TOSHIBA_INET6", <<EOF)
  69  #include <sys/param.h>
  70  EOF
  71      $ipv6type = "toshiba"
  72      $ipv6lib="inet6"
  73      $ipv6libdir="/usr/local/v6/lib"
  74      $CFLAGS="-DINET6 "+$CFLAGS
  75    elsif macro_defined?("__V6D__", <<EOF)
  76  #include </usr/local/v6/include/sys/v6config.h>
  77  EOF
  78      $ipv6type = "v6d"
  79      $ipv6lib="v6"
  80      $ipv6libdir="/usr/local/v6/lib"
  81      $CFLAGS="-DINET6 -I/usr/local/v6/include "+$CFLAGS
  82    elsif macro_defined?("_ZETA_MINAMI_INET6", <<EOF)
  83  #include <sys/param.h>
  84  EOF
  85      $ipv6type = "zeta"
  86      $ipv6lib="inet6"
  87      $ipv6libdir="/usr/local/v6/lib"
  88      $CFLAGS="-DINET6 "+$CFLAGS
  89    else
  90      $ipv6lib=with_config("ipv6-lib", nil)
  91      $ipv6libdir=with_config("ipv6-libdir", nil)
  92      $CFLAGS="-DINET6 "+$CFLAGS
  93    end
  94    
  95    if $ipv6lib
  96      if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/lib#{$ipv6lib}.a"
  97        $LOCAL_LIBS = " -L#$ipv6libdir -l#$ipv6lib"
  98      elsif !$ipv6trylibc
  99        print <<EOS
 100  
 101  Fatal: no #$ipv6lib library found.  cannot continue.
 102  You need to fetch lib#{$ipv6lib}.a from appropriate
 103  ipv6 kit and compile beforehand.
 104  EOS
 105        exit
 106      end
 107    end
 108  end
 109  
 110    if try_link(<<EOF)
 111  #ifdef _WIN32
 112  # include <windows.h>
 113  # include <winsock.h>
 114  #else
 115  # include <sys/types.h>
 116  # include <netdb.h>
 117  # include <string.h>
 118  # include <sys/socket.h>
 119  # include <netinet/in.h>
 120  #endif
 121  int
 122  main()
 123  {
 124     struct sockaddr_in sin;
 125  
 126     sin.sin_len;
 127     return 0;
 128  }
 129  EOF
 130      $CFLAGS="-DHAVE_SIN_LEN "+$CFLAGS
 131  end
 132  
 133    if try_link(<<EOF)
 134  #ifdef _WIN32
 135  # include <windows.h>
 136  # include <winsock.h>
 137  #else
 138  # include <sys/types.h>
 139  # include <netdb.h>
 140  # include <string.h>
 141  # include <sys/socket.h>
 142  #endif
 143  int
 144  main()
 145  {
 146     struct sockaddr_storage ss;
 147  
 148     ss.ss_family;
 149     return 0;
 150  }
 151  EOF
 152      $CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS
 153  end
 154  
 155    if try_link(<<EOF)
 156  #include <sys/types.h>
 157  #include <netdb.h>
 158  #include <string.h>
 159  #include <sys/socket.h>
 160  #include <netinet/in.h>
 161  int
 162  main()
 163  {
 164     struct sockaddr sa;
 165  
 166     sa.sa_len;
 167     return 0;
 168  }
 169  EOF
 170      $CFLAGS="-DHAVE_SA_LEN "+$CFLAGS
 171  end
 172  
 173  have_header("netinet/tcp.h") if not /cygwin/ =~ RUBY_PLATFORM # for cygwin 1.1.5
 174  have_header("netinet/udp.h")
 175  
 176  have_struct_member('struct msghdr', 'msg_control', header=['sys/types.h', 'sys/socket.h'])
 177  have_struct_member('struct msghdr', 'msg_accrights', header=['sys/types.h', 'sys/socket.h'])
 178  
 179  $getaddr_info_ok = false
 180  if !enable_config("wide-getaddrinfo", false) and try_run(<<EOF)
 181  #include <sys/types.h>
 182  #include <netdb.h>
 183  #include <string.h>
 184  #include <sys/socket.h>
 185  #include <netinet/in.h>
 186  
 187  #ifndef AF_LOCAL
 188  #define AF_LOCAL AF_UNIX
 189  #endif
 190  
 191  main()
 192  {
 193    int passive, gaierr, inet4 = 0, inet6 = 0;
 194    struct addrinfo hints, *ai, *aitop;
 195    char straddr[INET6_ADDRSTRLEN], strport[16];
 196  
 197    for (passive = 0; passive <= 1; passive++) {
 198      memset(&hints, 0, sizeof(hints));
 199      hints.ai_family = AF_UNSPEC;
 200      hints.ai_flags = passive ? AI_PASSIVE : 0;
 201      hints.ai_socktype = SOCK_STREAM;
 202      if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
 203        (void)gai_strerror(gaierr);
 204        goto bad;
 205      }
 206      for (ai = aitop; ai; ai = ai->ai_next) {
 207        if (ai->ai_family == AF_LOCAL) continue;
 208        if (ai->ai_addr == NULL ||
 209            ai->ai_addrlen == 0 ||
 210            getnameinfo(ai->ai_addr, ai->ai_addrlen,
 211                        straddr, sizeof(straddr), strport, sizeof(strport),
 212                        NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
 213          goto bad;
 214        }
 215        if (strcmp(strport, "54321") != 0) {
 216          goto bad;
 217        }
 218        switch (ai->ai_family) {
 219        case AF_INET:
 220          if (passive) {
 221            if (strcmp(straddr, "0.0.0.0") != 0) {
 222              goto bad;
 223            }
 224          } else {
 225            if (strcmp(straddr, "127.0.0.1") != 0) {
 226              goto bad;
 227            }
 228          }
 229          inet4++;
 230          break;
 231        case AF_INET6:
 232          if (passive) {
 233            if (strcmp(straddr, "::") != 0) {
 234              goto bad;
 235            }
 236          } else {
 237            if (strcmp(straddr, "::1") != 0) {
 238              goto bad;
 239            }
 240          }
 241          inet6++;
 242          break;
 243        case AF_UNSPEC:
 244          goto bad;
 245          break;
 246        default:
 247          /* another family support? */
 248          break;
 249        }
 250      }
 251    }
 252  
 253    if (!(inet4 == 0 || inet4 == 2))
 254      goto bad;
 255    if (!(inet6 == 0 || inet6 == 2))
 256      goto bad;
 257  
 258    if (aitop)
 259      freeaddrinfo(aitop);
 260    exit(0);
 261  
 262   bad:
 263    if (aitop)
 264      freeaddrinfo(aitop);
 265    exit(1);
 266  }
 267  EOF
 268    $getaddr_info_ok = true
 269  end
 270  if $ipv6 and not $getaddr_info_ok
 271        print <<EOS
 272  
 273  Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature.
 274  But your getaddrinfo() and getnameinfo() are appeared to be broken.  Sorry,
 275  you cannot compile IPv6 socket classes with broken these functions.
 276  You can try --enable-wide-getaddrinfo.
 277  EOS
 278    exit
 279  end
 280        
 281  case with_config("lookup-order-hack", "UNSPEC")
 282  when "INET"
 283    $CFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CFLAGS
 284  when "INET6"
 285    $CFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CFLAGS
 286  when "UNSPEC"
 287    # nothing special
 288  else
 289    print <<EOS
 290  
 291  Fatal: invalid value for --with-lookup-order-hack (expected INET, INET6 or UNSPEC)
 292  EOS
 293    exit
 294  end
 295  
 296  $objs = ["socket.#{$OBJEXT}"]
 297      
 298  if $getaddr_info_ok and have_func("getaddrinfo") and have_func("getnameinfo")
 299    have_getaddrinfo = true
 300  end
 301  
 302  if have_getaddrinfo
 303    $CFLAGS="-DHAVE_GETADDRINFO "+$CFLAGS
 304  else
 305    $CFLAGS="-I. "+$CFLAGS
 306    $objs += ["getaddrinfo.#{$OBJEXT}"]
 307    $objs += ["getnameinfo.#{$OBJEXT}"]
 308    have_func("inet_ntop") or have_func("inet_ntoa")
 309    have_func("inet_pton") or have_func("inet_aton")
 310    have_func("getservbyport")
 311    have_header("arpa/inet.h")
 312    have_header("arpa/nameser.h")
 313    have_header("resolv.h")
 314  end
 315  
 316  if !try_link(<<EOF)
 317  #include <sys/types.h>
 318  #include <netdb.h>
 319  #include <string.h>
 320  #include <sys/socket.h>
 321  #include <netinet/in.h>
 322  int
 323  main()
 324  {
 325     socklen_t len;
 326     return 0;
 327  }
 328  EOF
 329    $CFLAGS="-Dsocklen_t=int "+$CFLAGS
 330  end
 331  
 332  have_header("sys/un.h")
 333  have_header("sys/uio.h")
 334  
 335  if have_func(test_func)
 336    have_func("hsterror")
 337    unless have_func("gethostname")
 338      have_func("uname")
 339    end
 340    if ENV["SOCKS_SERVER"] or enable_config("socks", false)
 341      if have_library("socks5", "SOCKSinit")
 342        $CFLAGS+=" -DSOCKS5 -DSOCKS"
 343      elsif have_library("socks", "Rconnect")
 344        $CFLAGS+=" -DSOCKS"
 345      end
 346    end
 347    create_makefile("socket")
 348  end