PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/components/ruby-2.1.0/ext/socket/extconf.rb

https://github.com/jhs/ruby-inabox
Ruby | 635 lines | 572 code | 32 blank | 31 comment | 76 complexity | a91e68d9dce3609fee09d40aed22d2ef MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0
  1. require 'mkmf'
  2. AF_INET6_SOCKET_CREATION_TEST = <<EOF
  3. #include <sys/types.h>
  4. #ifndef _WIN32
  5. #include <sys/socket.h>
  6. #endif
  7. int
  8. main(void)
  9. {
  10. socket(AF_INET6, SOCK_STREAM, 0);
  11. return 0;
  12. }
  13. EOF
  14. GETADDRINFO_GETNAMEINFO_TEST = <<EOF
  15. #include <stdlib.h>
  16. #ifndef EXIT_SUCCESS
  17. #define EXIT_SUCCESS 0
  18. #endif
  19. #ifndef EXIT_FAILURE
  20. #define EXIT_FAILURE 1
  21. #endif
  22. #ifndef AF_LOCAL
  23. #define AF_LOCAL AF_UNIX
  24. #endif
  25. int
  26. main(void)
  27. {
  28. int passive, gaierr, inet4 = 0, inet6 = 0;
  29. struct addrinfo hints, *ai, *aitop;
  30. char straddr[INET6_ADDRSTRLEN], strport[16];
  31. #ifdef _WIN32
  32. WSADATA retdata;
  33. WSAStartup(MAKEWORD(2, 0), &retdata);
  34. #endif
  35. for (passive = 0; passive <= 1; passive++) {
  36. memset(&hints, 0, sizeof(hints));
  37. hints.ai_family = AF_UNSPEC;
  38. hints.ai_protocol = IPPROTO_TCP;
  39. hints.ai_flags = passive ? AI_PASSIVE : 0;
  40. hints.ai_socktype = SOCK_STREAM;
  41. if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
  42. (void)gai_strerror(gaierr);
  43. goto bad;
  44. }
  45. for (ai = aitop; ai; ai = ai->ai_next) {
  46. if (ai->ai_family == AF_LOCAL) continue;
  47. if (ai->ai_addr == NULL)
  48. goto bad;
  49. #if defined(_AIX)
  50. if (ai->ai_family == AF_INET6 && passive) {
  51. inet6++;
  52. continue;
  53. }
  54. ai->ai_addr->sa_len = ai->ai_addrlen;
  55. ai->ai_addr->sa_family = ai->ai_family;
  56. #endif
  57. if (ai->ai_addrlen == 0 ||
  58. getnameinfo(ai->ai_addr, ai->ai_addrlen,
  59. straddr, sizeof(straddr), strport, sizeof(strport),
  60. NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
  61. goto bad;
  62. }
  63. if (strcmp(strport, "54321") != 0) {
  64. goto bad;
  65. }
  66. switch (ai->ai_family) {
  67. case AF_INET:
  68. if (passive) {
  69. if (strcmp(straddr, "0.0.0.0") != 0) {
  70. goto bad;
  71. }
  72. } else {
  73. if (strcmp(straddr, "127.0.0.1") != 0) {
  74. goto bad;
  75. }
  76. }
  77. inet4++;
  78. break;
  79. case AF_INET6:
  80. if (passive) {
  81. if (strcmp(straddr, "::") != 0) {
  82. goto bad;
  83. }
  84. } else {
  85. if (strcmp(straddr, "::1") != 0) {
  86. goto bad;
  87. }
  88. }
  89. inet6++;
  90. break;
  91. case AF_UNSPEC:
  92. goto bad;
  93. break;
  94. default:
  95. /* another family support? */
  96. break;
  97. }
  98. }
  99. }
  100. if (!(inet4 == 0 || inet4 == 2))
  101. goto bad;
  102. if (!(inet6 == 0 || inet6 == 2))
  103. goto bad;
  104. if (aitop)
  105. freeaddrinfo(aitop);
  106. return EXIT_SUCCESS;
  107. bad:
  108. if (aitop)
  109. freeaddrinfo(aitop);
  110. return EXIT_FAILURE;
  111. }
  112. EOF
  113. RECVMSG_WITH_MSG_PEEK_ALLOCATE_FD_TEST = <<'EOF'
  114. #include <stdlib.h>
  115. #include <stdio.h>
  116. #include <string.h>
  117. #include <sys/types.h>
  118. #include <sys/stat.h>
  119. #include <sys/socket.h>
  120. #include <sys/un.h>
  121. #include <unistd.h>
  122. int main(int argc, char *argv[])
  123. {
  124. int ps[2], sv[2];
  125. int ret;
  126. ssize_t ss;
  127. int s_fd, r_fd;
  128. struct msghdr s_msg, r_msg;
  129. union {
  130. struct cmsghdr hdr;
  131. char dummy[CMSG_SPACE(sizeof(int))];
  132. } s_cmsg, r_cmsg;
  133. struct iovec s_iov, r_iov;
  134. char s_buf[1], r_buf[1];
  135. struct stat s_statbuf, r_statbuf;
  136. ret = pipe(ps);
  137. if (ret == -1) { perror("pipe"); exit(EXIT_FAILURE); }
  138. s_fd = ps[0];
  139. ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sv);
  140. if (ret == -1) { perror("socketpair"); exit(EXIT_FAILURE); }
  141. s_msg.msg_name = NULL;
  142. s_msg.msg_namelen = 0;
  143. s_msg.msg_iov = &s_iov;
  144. s_msg.msg_iovlen = 1;
  145. s_msg.msg_control = &s_cmsg;
  146. s_msg.msg_controllen = CMSG_SPACE(sizeof(int));;
  147. s_msg.msg_flags = 0;
  148. s_iov.iov_base = &s_buf;
  149. s_iov.iov_len = sizeof(s_buf);
  150. s_buf[0] = 'a';
  151. s_cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));
  152. s_cmsg.hdr.cmsg_level = SOL_SOCKET;
  153. s_cmsg.hdr.cmsg_type = SCM_RIGHTS;
  154. memcpy(CMSG_DATA(&s_cmsg.hdr), (char *)&s_fd, sizeof(int));
  155. ss = sendmsg(sv[0], &s_msg, 0);
  156. if (ss == -1) { perror("sendmsg"); exit(EXIT_FAILURE); }
  157. r_msg.msg_name = NULL;
  158. r_msg.msg_namelen = 0;
  159. r_msg.msg_iov = &r_iov;
  160. r_msg.msg_iovlen = 1;
  161. r_msg.msg_control = &r_cmsg;
  162. r_msg.msg_controllen = CMSG_SPACE(sizeof(int));
  163. r_msg.msg_flags = 0;
  164. r_iov.iov_base = &r_buf;
  165. r_iov.iov_len = sizeof(r_buf);
  166. r_buf[0] = '0';
  167. memset(&r_cmsg, 0xff, CMSG_SPACE(sizeof(int)));
  168. ss = recvmsg(sv[1], &r_msg, MSG_PEEK);
  169. if (ss == -1) { perror("recvmsg"); exit(EXIT_FAILURE); }
  170. if (ss != 1) {
  171. fprintf(stderr, "unexpected return value from recvmsg: %ld\n", (long)ss);
  172. exit(EXIT_FAILURE);
  173. }
  174. if (r_buf[0] != 'a') {
  175. fprintf(stderr, "unexpected return data from recvmsg: 0x%02x\n", r_buf[0]);
  176. exit(EXIT_FAILURE);
  177. }
  178. if (r_msg.msg_controllen < CMSG_LEN(sizeof(int))) {
  179. fprintf(stderr, "unexpected: r_msg.msg_controllen < CMSG_LEN(sizeof(int)) not hold: %ld\n",
  180. (long)r_msg.msg_controllen);
  181. exit(EXIT_FAILURE);
  182. }
  183. if (r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int))) {
  184. fprintf(stderr, "unexpected: r_cmsg.hdr.cmsg_len < CMSG_LEN(sizeof(int)) not hold: %ld\n",
  185. (long)r_cmsg.hdr.cmsg_len);
  186. exit(EXIT_FAILURE);
  187. }
  188. memcpy((char *)&r_fd, CMSG_DATA(&r_cmsg.hdr), sizeof(int));
  189. if (r_fd < 0) {
  190. fprintf(stderr, "negative r_fd: %d\n", r_fd);
  191. exit(EXIT_FAILURE);
  192. }
  193. if (r_fd == s_fd) {
  194. fprintf(stderr, "r_fd and s_fd is same: %d\n", r_fd);
  195. exit(EXIT_FAILURE);
  196. }
  197. ret = fstat(s_fd, &s_statbuf);
  198. if (ret == -1) { perror("fstat(s_fd)"); exit(EXIT_FAILURE); }
  199. ret = fstat(r_fd, &r_statbuf);
  200. if (ret == -1) { perror("fstat(r_fd)"); exit(EXIT_FAILURE); }
  201. if (s_statbuf.st_dev != r_statbuf.st_dev ||
  202. s_statbuf.st_ino != r_statbuf.st_ino) {
  203. fprintf(stderr, "dev/ino doesn't match: s_fd:%ld/%ld r_fd:%ld/%ld\n",
  204. (long)s_statbuf.st_dev, (long)s_statbuf.st_ino,
  205. (long)r_statbuf.st_dev, (long)r_statbuf.st_ino);
  206. exit(EXIT_FAILURE);
  207. }
  208. return EXIT_SUCCESS;
  209. }
  210. EOF
  211. def test_recvmsg_with_msg_peek_creates_fds(headers)
  212. case RUBY_PLATFORM
  213. when /linux/
  214. # Linux 2.6.38 allocate fds by recvmsg with MSG_PEEK.
  215. close_fds = true
  216. when /bsd|darwin/
  217. # FreeBSD 8.2.0, NetBSD 5 and MacOS X Snow Leopard doesn't
  218. # allocate fds by recvmsg with MSG_PEEK.
  219. # [ruby-dev:44189]
  220. # http://bugs.ruby-lang.org/issues/5075
  221. close_fds = false
  222. when /cygwin/
  223. # Cygwin doesn't support fd passing.
  224. # http://cygwin.com/ml/cygwin/2003-09/msg01808.html
  225. close_fds = false
  226. else
  227. close_fds = nil
  228. end
  229. if !CROSS_COMPILING
  230. if checking_for("recvmsg() with MSG_PEEK allocate file descriptors") {
  231. try_run(cpp_include(headers) + RECVMSG_WITH_MSG_PEEK_ALLOCATE_FD_TEST)
  232. }
  233. if close_fds == false
  234. warn "unexpected fd-passing recvmsg() with MSG_PEEK behavor on #{RUBY_PLATFORM}: fd allocation unexpected."
  235. elsif close_fds == nil
  236. puts "info: #{RUBY_PLATFORM} recvmsg() with MSG_PEEK allocates fds on fd-passing."
  237. end
  238. close_fds = true
  239. else
  240. if close_fds == true
  241. warn "unexpected fd-passing recvmsg() with MSG_PEEK behavor on #{RUBY_PLATFORM}: fd allocation expected."
  242. elsif close_fds == nil
  243. puts "info: #{RUBY_PLATFORM}: recvmsg() with MSG_PEEK doesn't allocates fds on fd-passing."
  244. end
  245. close_fds = false
  246. end
  247. end
  248. if close_fds == nil
  249. abort <<EOS
  250. Fatal: cannot test fd-passing recvmsg() with MSG_PEEK behavor
  251. because cross-compilation for #{RUBY_PLATFORM}.
  252. If recvmsg() with MSG_PEEK allocates fds on fd passing:
  253. --enable-close-fds-by-recvmsg-with-peek
  254. If recvmsg() with MSG_PEEK doesn't allocate fds on fd passing:
  255. --disable-close-fds-by-recvmsg-with-peek
  256. EOS
  257. end
  258. close_fds
  259. end
  260. $INCFLAGS << " -I$(topdir) -I$(top_srcdir)"
  261. if /darwin/ =~ RUBY_PLATFORM
  262. # For IPv6 extension header access on OS X 10.7+ [Bug #8517]
  263. $CFLAGS << " -D__APPLE_USE_RFC_3542"
  264. end
  265. headers = []
  266. unless $mswin or $mingw
  267. headers = %w<sys/types.h netdb.h string.h sys/socket.h netinet/in.h>
  268. end
  269. %w[
  270. sys/uio.h
  271. xti.h
  272. netinet/in_systm.h
  273. netinet/tcp.h
  274. netinet/udp.h
  275. arpa/inet.h
  276. netpacket/packet.h
  277. net/ethernet.h
  278. sys/un.h
  279. ifaddrs.h
  280. sys/ioctl.h
  281. sys/sockio.h
  282. net/if.h
  283. sys/param.h
  284. sys/ucred.h
  285. ucred.h
  286. net/if_dl.h
  287. arpa/nameser.h
  288. resolv.h
  289. ].each {|h|
  290. if have_header(h, headers)
  291. headers << h
  292. end
  293. }
  294. have_struct_member("struct sockaddr", "sa_len", headers) # 4.4BSD
  295. have_struct_member("struct sockaddr_in", "sin_len", headers) # 4.4BSD
  296. if have_type("struct sockaddr_un", headers) # POSIX
  297. have_struct_member("struct sockaddr_un", "sun_len", headers) # 4.4BSD
  298. end
  299. have_type("struct sockaddr_dl", headers) # AF_LINK address. 4.4BSD since Net2
  300. have_type("struct sockaddr_storage", headers)
  301. have_type("struct addrinfo", headers)
  302. if have_type("socklen_t", headers)
  303. if try_static_assert("sizeof(socklen_t) >= sizeof(long)", headers)
  304. $defs << "-DRSTRING_SOCKLEN=(socklen_t)RSTRING_LEN"
  305. end
  306. end
  307. have_type("struct in_pktinfo", headers) {|src|
  308. src.sub(%r'^/\*top\*/', '\&'"\n#if defined(IPPROTO_IP) && defined(IP_PKTINFO)") <<
  309. "#else\n" << "#error\n" << ">>>>>> no in_pktinfo <<<<<<\n" << "#endif\n"
  310. } and have_struct_member("struct in_pktinfo", "ipi_spec_dst", headers)
  311. have_type("struct in6_pktinfo", headers) {|src|
  312. src.sub(%r'^/\*top\*/', '\&'"\n#if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)") <<
  313. "#else\n" << "#error\n" << ">>>>>> no in6_pktinfo <<<<<<\n" << "#endif\n"
  314. }
  315. have_type("struct sockcred", headers)
  316. have_type("struct cmsgcred", headers)
  317. have_type("struct ip_mreq", headers) # 4.4BSD
  318. have_type("struct ip_mreqn", headers) # Linux 2.4
  319. have_type("struct ipv6_mreq", headers) # RFC 3493
  320. have_msg_control = nil
  321. have_msg_control = have_struct_member('struct msghdr', 'msg_control', headers) unless $mswin or $mingw
  322. have_struct_member('struct msghdr', 'msg_accrights', headers)
  323. case RUBY_PLATFORM
  324. when /mswin(32|64)|mingw/
  325. test_func = "WSACleanup"
  326. have_library("ws2_32", "WSACleanup", headers)
  327. when /cygwin/
  328. test_func = "socket(0,0,0)"
  329. when /beos/
  330. test_func = "socket(0,0,0)"
  331. have_library("net", "socket(0,0,0)", headers)
  332. when /haiku/
  333. test_func = "socket(0,0,0)"
  334. have_library("network", "socket(0,0,0)", headers)
  335. when /i386-os2_emx/
  336. test_func = "socket(0,0,0)"
  337. have_library("socket", "socket(0,0,0)", headers)
  338. else
  339. test_func = "socket(0,0,0)"
  340. have_library("nsl", 't_open("", 0, (struct t_info *)NULL)', headers) # SunOS
  341. have_library("socket", "socket(0,0,0)", headers) # SunOS
  342. end
  343. if have_func(test_func, headers)
  344. have_func("sendmsg(0, (struct msghdr *)NULL, 0)", headers) # POSIX
  345. have_recvmsg = have_func("recvmsg(0, (struct msghdr *)NULL, 0)", headers) # POSIX
  346. have_func("freehostent((struct hostent *)NULL)", headers) # RFC 2553
  347. have_func("freeaddrinfo((struct addrinfo *)NULL)", headers) # RFC 2553
  348. if /haiku/ !~ RUBY_PLATFORM and
  349. have_func("gai_strerror(0)", headers) # POSIX
  350. if checking_for("gai_strerror() returns const pointer") {!try_compile(<<EOF)}
  351. #{cpp_include(headers)}
  352. #include <stdlib.h>
  353. void
  354. conftest_gai_strerror_is_const()
  355. {
  356. *gai_strerror(0) = 0;
  357. }
  358. EOF
  359. $defs << "-DGAI_STRERROR_CONST"
  360. end
  361. end
  362. have_func("accept4", headers)
  363. have_func('inet_ntop(0, (const void *)0, (char *)0, 0)', headers) or
  364. have_func("inet_ntoa(*(struct in_addr *)NULL)", headers)
  365. have_func('inet_pton(0, "", (void *)0)', headers) or
  366. have_func('inet_aton("", (struct in_addr *)0)', headers)
  367. have_func('getservbyport(0, "")', headers)
  368. have_func("getifaddrs((struct ifaddrs **)NULL)", headers)
  369. have_func("getpeereid", headers)
  370. have_func("getpeerucred(0, (ucred_t **)NULL)", headers) # SunOS
  371. have_func_decl = proc do |name, headers|
  372. if !checking_for("declaration of #{name}()") {!%w[int void].all? {|ret| try_compile(<<EOF)}}
  373. #{cpp_include(headers)}
  374. #{ret} #{name}(void);
  375. EOF
  376. $defs << "-DNEED_#{name.tr_cpp}_DECL"
  377. end
  378. end
  379. if have_func('if_indextoname(0, "")', headers)
  380. have_func_decl["if_indextoname"]
  381. end
  382. if have_func('if_nametoindex("")', headers)
  383. have_func_decl["if_nametoindex"]
  384. end
  385. have_func("hsterror", headers)
  386. have_func('getipnodebyname("", 0, 0, (int *)0)', headers) # RFC 2553
  387. have_func('gethostbyname2("", 0)', headers) # RFC 2133
  388. have_func("socketpair(0, 0, 0, 0)", headers)
  389. unless have_func("gethostname((char *)0, 0)", headers)
  390. have_func("uname((struct utsname *)NULL)", headers)
  391. end
  392. ipv6 = false
  393. default_ipv6 = /beos|haiku/ !~ RUBY_PLATFORM
  394. if enable_config("ipv6", default_ipv6)
  395. if checking_for("ipv6") {try_link(AF_INET6_SOCKET_CREATION_TEST)}
  396. $defs << "-DENABLE_IPV6" << "-DINET6"
  397. ipv6 = true
  398. end
  399. end
  400. if ipv6
  401. if $mingw
  402. $CPPFLAGS << " -D_WIN32_WINNT=0x501" unless $CPPFLAGS.include?("_WIN32_WINNT")
  403. end
  404. ipv6lib = nil
  405. class << (fmt = "unknown")
  406. def %(s) s || self end
  407. end
  408. idirs, ldirs = dir_config("inet6", %w[/usr/inet6 /usr/local/v6].find {|d| File.directory?(d)})
  409. checking_for("ipv6 type", fmt) do
  410. if have_macro("IPV6_INRIA_VERSION", "netinet/in.h")
  411. "inria"
  412. elsif have_macro("__KAME__", "netinet/in.h")
  413. have_library(ipv6lib = "inet6")
  414. "kame"
  415. elsif have_macro("_TOSHIBA_INET6", "sys/param.h")
  416. have_library(ipv6lib = "inet6") and "toshiba"
  417. elsif have_macro("__V6D__", "sys/v6config.h")
  418. have_library(ipv6lib = "v6") and "v6d"
  419. elsif have_macro("_ZETA_MINAMI_INET6", "sys/param.h")
  420. have_library(ipv6lib = "inet6") and "zeta"
  421. elsif have_library("inet6")
  422. "inet6"
  423. end
  424. end or not ipv6lib or abort <<EOS
  425. Fatal: no #{ipv6lib} library found. cannot continue.
  426. You need to fetch lib#{ipv6lib}.a from appropriate
  427. ipv6 kit and compile beforehand.
  428. EOS
  429. end
  430. if !have_macro("IPPROTO_IPV6", headers) && have_const("IPPROTO_IPV6", headers)
  431. IO.read(File.join(File.dirname(__FILE__), "mkconstants.rb")).sub(/\A.*^__END__$/m, '').split(/\r?\n/).grep(/\AIPPROTO_\w*/){$&}.each {|name|
  432. have_const(name, headers) unless $defs.include?("-DHAVE_CONST_#{name.upcase}")
  433. }
  434. end
  435. if enable_config("close-fds-by-recvmsg-with-peek") {
  436. have_msg_control && have_recvmsg &&
  437. have_const('AF_UNIX', headers) && have_const('SCM_RIGHTS', headers) &&
  438. test_recvmsg_with_msg_peek_creates_fds(headers)
  439. }
  440. $defs << "-DFD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK"
  441. end
  442. case enable_config("wide-getaddrinfo")
  443. when true
  444. getaddr_info_ok = :wide
  445. when nil
  446. if have_func("getnameinfo", headers) and have_func("getaddrinfo", headers)
  447. getaddr_info_ok = :os
  448. if !CROSS_COMPILING &&
  449. !checking_for("system getaddrinfo working") {
  450. try_run(cpp_include(headers) + GETADDRINFO_GETNAMEINFO_TEST)
  451. }
  452. getaddr_info_ok = :wide
  453. end
  454. else
  455. getaddr_info_ok = :wide
  456. end
  457. when false
  458. if have_func("getnameinfo", headers) and have_func("getaddrinfo", headers)
  459. getaddr_info_ok = :os
  460. if !CROSS_COMPILING &&
  461. !checking_for("system getaddrinfo working") {
  462. try_run(cpp_include(headers) + GETADDRINFO_GETNAMEINFO_TEST)
  463. }
  464. getaddr_info_ok = nil
  465. end
  466. else
  467. getaddr_info_ok = nil
  468. end
  469. else
  470. raise "unexpected enable_config() value"
  471. end
  472. if ipv6 and not getaddr_info_ok
  473. abort <<EOS
  474. Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature.
  475. But your getaddrinfo() and getnameinfo() are appeared to be broken. Sorry,
  476. you cannot compile IPv6 socket classes with broken these functions.
  477. You can try --enable-wide-getaddrinfo.
  478. EOS
  479. end
  480. case with_config("lookup-order-hack", "UNSPEC")
  481. when "INET"
  482. $defs << "-DLOOKUP_ORDER_HACK_INET"
  483. when "INET6"
  484. $defs << "-DLOOKUP_ORDER_HACK_INET6"
  485. when "UNSPEC"
  486. # nothing special
  487. else
  488. abort <<EOS
  489. Fatal: invalid value for --with-lookup-order-hack (expected INET, INET6 or UNSPEC)
  490. EOS
  491. end
  492. $objs = [
  493. "init.#{$OBJEXT}",
  494. "constants.#{$OBJEXT}",
  495. "basicsocket.#{$OBJEXT}",
  496. "socket.#{$OBJEXT}",
  497. "ipsocket.#{$OBJEXT}",
  498. "tcpsocket.#{$OBJEXT}",
  499. "tcpserver.#{$OBJEXT}",
  500. "sockssocket.#{$OBJEXT}",
  501. "udpsocket.#{$OBJEXT}",
  502. "unixsocket.#{$OBJEXT}",
  503. "unixserver.#{$OBJEXT}",
  504. "option.#{$OBJEXT}",
  505. "ancdata.#{$OBJEXT}",
  506. "raddrinfo.#{$OBJEXT}",
  507. "ifaddr.#{$OBJEXT}"
  508. ]
  509. if getaddr_info_ok == :wide
  510. if !have_type("struct in6_addr", headers) and have_type("struct in_addr6", headers)
  511. $defs.pop(2)
  512. $defs << "-Din_addr6=in6_addr"
  513. end
  514. if have_struct_member("struct in6_addr", "s6_addr8", headers)
  515. $defs[-1] = "-Ds6_addr=s6_addr8"
  516. end
  517. if ipv6 == "kame" && have_struct_member("struct in6_addr", "s6_addr32", headers)
  518. $defs[-1] = "-DFAITH"
  519. end
  520. $CPPFLAGS="-I. "+$CPPFLAGS
  521. $objs += ["getaddrinfo.#{$OBJEXT}"]
  522. $objs += ["getnameinfo.#{$OBJEXT}"]
  523. $defs << "-DGETADDRINFO_EMU"
  524. end
  525. # workaround for recent Windows SDK
  526. $defs << "-DIPPROTO_IPV6=IPPROTO_IPV6" if $defs.include?("-DHAVE_CONST_IPPROTO_IPV6") && !have_macro("IPPROTO_IPV6")
  527. $distcleanfiles << "constants.h" << "constdefs.*"
  528. if enable_config("socks", ENV["SOCKS_SERVER"])
  529. if have_library("socks5", "SOCKSinit")
  530. $defs << "-DSOCKS5" << "-DSOCKS"
  531. elsif have_library("socks", "Rconnect")
  532. $defs << "-DSOCKS"
  533. end
  534. end
  535. hdr = "netinet6/in6.h"
  536. if /darwin/ =~ RUBY_PLATFORM and !try_compile(<<"SRC", nil, :werror=>true)
  537. #include <netinet/in.h>
  538. int t(struct in6_addr *addr) {return IN6_IS_ADDR_UNSPECIFIED(addr);}
  539. SRC
  540. print "fixing apple's netinet6/in6.rb ..."; $stdout.flush
  541. in6 = File.read("/usr/include/#{hdr}")
  542. if in6.gsub!(/\*\(const\s+__uint32_t\s+\*\)\(const\s+void\s+\*\)\(&(\(\w+\))->s6_addr\[(\d+)\]\)/) do
  543. i, r = $2.to_i.divmod(4)
  544. if r.zero?
  545. "#$1->__u6_addr.__u6_addr32[#{i}]"
  546. else
  547. $&
  548. end
  549. end
  550. FileUtils.mkdir_p(File.dirname(hdr))
  551. open(hdr, "w") {|f| f.write(in6)}
  552. $distcleanfiles << hdr
  553. $distcleandirs << File.dirname(hdr)
  554. puts "done"
  555. else
  556. puts "not needed"
  557. end
  558. end
  559. create_makefile("socket")
  560. end