PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/ruby_1_8_7/ext/socket/extconf.rb

http://github.com/funkaster/shinycocos
Ruby | 301 lines | 255 code | 26 blank | 20 comment | 60 complexity | 4c96527f1afafa71d788f2c71eff1baa MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-3.0, LGPL-2.1, Apache-2.0, LGPL-3.0, GPL-2.0
  1. require 'mkmf'
  2. case RUBY_PLATFORM
  3. when /bccwin32/
  4. test_func = "WSACleanup"
  5. have_library("ws2_32", "WSACleanup")
  6. when /mswin32|mingw/
  7. test_func = "WSACleanup"
  8. if with_config("winsock2")
  9. have_library("ws2_32", "WSACleanup")
  10. else
  11. have_library("wsock32", "WSACleanup")
  12. end
  13. when /cygwin/
  14. test_func = "socket"
  15. when /beos/
  16. test_func = "socket"
  17. have_library("net", "socket")
  18. have_func("closesocket")
  19. when /i386-os2_emx/
  20. test_func = "socket"
  21. have_library("socket", "socket")
  22. else
  23. test_func = "socket"
  24. have_library("nsl", "t_open")
  25. have_library("socket", "socket")
  26. end
  27. unless $mswin or $bccwin or $mingw
  28. headers = %w<sys/types.h netdb.h string.h sys/socket.h netinet/in.h>
  29. end
  30. if /solaris/ =~ RUBY_PLATFORM and !try_compile("")
  31. # bug of gcc 3.0 on Solaris 8 ?
  32. headers << "sys/feature_tests.h"
  33. end
  34. if have_header("arpa/inet.h")
  35. headers << "arpa/inet.h"
  36. end
  37. ipv6 = false
  38. default_ipv6 = /cygwin/ !~ RUBY_PLATFORM
  39. if enable_config("ipv6", default_ipv6)
  40. if checking_for("ipv6") {try_link(<<EOF)}
  41. #include <sys/types.h>
  42. #include <sys/socket.h>
  43. main()
  44. {
  45. socket(AF_INET6, SOCK_STREAM, 0);
  46. }
  47. EOF
  48. $defs << "-DENABLE_IPV6" << "-DINET6"
  49. ipv6 = true
  50. end
  51. end
  52. if ipv6
  53. ipv6lib = nil
  54. class << (fmt = "unknown")
  55. def %(s) s || self end
  56. end
  57. idirs, ldirs = dir_config("inet6", %w[/usr/inet6 /usr/local/v6].find {|d| File.directory?(d)})
  58. checking_for("ipv6 type", fmt) do
  59. if have_macro("IPV6_INRIA_VERSION", "netinet/in.h")
  60. "inria"
  61. elsif have_macro("__KAME__", "netinet/in.h")
  62. have_library(ipv6lib = "inet6")
  63. "kame"
  64. elsif have_macro("_TOSHIBA_INET6", "sys/param.h")
  65. have_library(ipv6lib = "inet6") and "toshiba"
  66. elsif have_macro("__V6D__", "sys/v6config.h")
  67. have_library(ipv6lib = "v6") and "v6d"
  68. elsif have_macro("_ZETA_MINAMI_INET6", "sys/param.h")
  69. have_library(ipv6lib = "inet6") and "zeta"
  70. elsif ipv6lib = with_config("ipv6-lib")
  71. warn <<EOS
  72. --with-ipv6-lib and --with-ipv6-libdir option will be obsolete, use
  73. --with-inet6lib and --with-inet6-{include,lib} options instead.
  74. EOS
  75. find_library(ipv6lib, nil, with_config("ipv6-libdir", ldirs)) and
  76. ipv6lib
  77. elsif have_library("inet6")
  78. "inet6"
  79. end
  80. end or not ipv6lib or abort <<EOS
  81. Fatal: no #{ipv6lib} library found. cannot continue.
  82. You need to fetch lib#{ipv6lib}.a from appropriate
  83. ipv6 kit and compile beforehand.
  84. EOS
  85. end
  86. if have_struct_member("struct sockaddr_in", "sin_len", headers)
  87. $defs[-1] = "-DHAVE_SIN_LEN"
  88. end
  89. # doug's fix, NOW add -Dss_family... only if required!
  90. [nil, " -Dss_family=__ss_family -Dss_len=__ss_len"].each do |flags|
  91. if flags
  92. cppflags = $CPPFLAGS
  93. $CPPFLAGS += flags
  94. end
  95. if have_struct_member("struct sockaddr_storage", "ss_family", headers)
  96. $defs[-1] = "-DHAVE_SOCKADDR_STORAGE"
  97. break
  98. elsif flags
  99. $CPPFLAGS = cppflags
  100. end
  101. end
  102. if have_struct_member("struct sockaddr", "sa_len", headers)
  103. $defs[-1] = "-DHAVE_SA_LEN "
  104. end
  105. have_header("netinet/tcp.h") if not /cygwin/ =~ RUBY_PLATFORM # for cygwin 1.1.5
  106. have_header("netinet/udp.h")
  107. if have_func("sendmsg") | have_func("recvmsg")
  108. have_struct_member('struct msghdr', 'msg_control', ['sys/types.h', 'sys/socket.h'])
  109. have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])
  110. end
  111. getaddr_info_ok = enable_config("wide-getaddrinfo") do
  112. checking_for("wide getaddrinfo") {try_run(<<EOF)}
  113. #{cpp_include(headers)}
  114. #include <stdlib.h>
  115. #ifndef EXIT_SUCCESS
  116. #define EXIT_SUCCESS 0
  117. #endif
  118. #ifndef EXIT_FAILURE
  119. #define EXIT_FAILURE 1
  120. #endif
  121. #ifndef AF_LOCAL
  122. #define AF_LOCAL AF_UNIX
  123. #endif
  124. main()
  125. {
  126. int passive, gaierr, inet4 = 0, inet6 = 0;
  127. struct addrinfo hints, *ai, *aitop;
  128. char straddr[INET6_ADDRSTRLEN], strport[16];
  129. for (passive = 0; passive <= 1; passive++) {
  130. memset(&hints, 0, sizeof(hints));
  131. hints.ai_family = AF_UNSPEC;
  132. hints.ai_protocol = IPPROTO_TCP;
  133. hints.ai_flags = passive ? AI_PASSIVE : 0;
  134. hints.ai_socktype = SOCK_STREAM;
  135. if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
  136. (void)gai_strerror(gaierr);
  137. goto bad;
  138. }
  139. for (ai = aitop; ai; ai = ai->ai_next) {
  140. if (ai->ai_family == AF_LOCAL) continue;
  141. if (ai->ai_addr == NULL)
  142. goto bad;
  143. #if defined(_AIX)
  144. if (ai->ai_family == AF_INET6 && passive) {
  145. inet6++;
  146. continue;
  147. }
  148. ai->ai_addr->sa_len = ai->ai_addrlen;
  149. ai->ai_addr->sa_family = ai->ai_family;
  150. #endif
  151. if (ai->ai_addrlen == 0 ||
  152. getnameinfo(ai->ai_addr, ai->ai_addrlen,
  153. straddr, sizeof(straddr), strport, sizeof(strport),
  154. NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
  155. goto bad;
  156. }
  157. if (strcmp(strport, "54321") != 0) {
  158. goto bad;
  159. }
  160. switch (ai->ai_family) {
  161. case AF_INET:
  162. if (passive) {
  163. if (strcmp(straddr, "0.0.0.0") != 0) {
  164. goto bad;
  165. }
  166. } else {
  167. if (strcmp(straddr, "127.0.0.1") != 0) {
  168. goto bad;
  169. }
  170. }
  171. inet4++;
  172. break;
  173. case AF_INET6:
  174. if (passive) {
  175. if (strcmp(straddr, "::") != 0) {
  176. goto bad;
  177. }
  178. } else {
  179. if (strcmp(straddr, "::1") != 0) {
  180. goto bad;
  181. }
  182. }
  183. inet6++;
  184. break;
  185. case AF_UNSPEC:
  186. goto bad;
  187. break;
  188. default:
  189. /* another family support? */
  190. break;
  191. }
  192. }
  193. }
  194. if (!(inet4 == 0 || inet4 == 2))
  195. goto bad;
  196. if (!(inet6 == 0 || inet6 == 2))
  197. goto bad;
  198. if (aitop)
  199. freeaddrinfo(aitop);
  200. exit(EXIT_SUCCESS);
  201. bad:
  202. if (aitop)
  203. freeaddrinfo(aitop);
  204. exit(EXIT_FAILURE);
  205. }
  206. EOF
  207. end
  208. if ipv6 and not getaddr_info_ok
  209. abort <<EOS
  210. Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature.
  211. But your getaddrinfo() and getnameinfo() are appeared to be broken. Sorry,
  212. you cannot compile IPv6 socket classes with broken these functions.
  213. You can try --enable-wide-getaddrinfo.
  214. EOS
  215. end
  216. case with_config("lookup-order-hack", "UNSPEC")
  217. when "INET"
  218. $defs << "-DLOOKUP_ORDER_HACK_INET"
  219. when "INET6"
  220. $defs << "-DLOOKUP_ORDER_HACK_INET6"
  221. when "UNSPEC"
  222. # nothing special
  223. else
  224. abort <<EOS
  225. Fatal: invalid value for --with-lookup-order-hack (expected INET, INET6 or UNSPEC)
  226. EOS
  227. end
  228. $objs = ["socket.#{$OBJEXT}"]
  229. unless getaddr_info_ok and have_func("getnameinfo", "netdb.h") and have_func("getaddrinfo", "netdb.h")
  230. if have_struct_member("struct in6_addr", "s6_addr8", headers)
  231. $defs[-1] = "-DHAVE_ADDR8"
  232. end
  233. $CPPFLAGS="-I. "+$CPPFLAGS
  234. $objs += ["getaddrinfo.#{$OBJEXT}"]
  235. $objs += ["getnameinfo.#{$OBJEXT}"]
  236. have_func("inet_ntop") or have_func("inet_ntoa")
  237. have_func("inet_pton") or have_func("inet_aton")
  238. have_func("getservbyport")
  239. if have_func("gai_strerror")
  240. unless checking_for("gai_strerror() returns const pointer") {!try_compile(<<EOF)}
  241. #{cpp_include(headers)}
  242. #include <stdlib.h>
  243. void
  244. conftest_gai_strerror_is_const()
  245. {
  246. *gai_strerror(0) = 0;
  247. }
  248. EOF
  249. $defs << "-DGAI_STRERROR_CONST"
  250. end
  251. end
  252. have_header("arpa/nameser.h")
  253. have_header("resolv.h")
  254. end
  255. unless have_type("socklen_t", headers)
  256. $defs << "-Dsocklen_t=int"
  257. end
  258. have_header("sys/un.h")
  259. have_header("sys/uio.h")
  260. if have_func(test_func)
  261. have_func("hsterror")
  262. have_func("getipnodebyname") or have_func("gethostbyname2")
  263. have_func("socketpair")
  264. unless have_func("gethostname")
  265. have_func("uname")
  266. end
  267. if enable_config("socks", ENV["SOCKS_SERVER"])
  268. if have_library("socks5", "SOCKSinit")
  269. $defs << "-DSOCKS5" << "-DSOCKS"
  270. elsif have_library("socks", "Rconnect")
  271. $defs << "-DSOCKS"
  272. end
  273. end
  274. create_makefile("socket")
  275. end