/ext/socket/extconf.rb

http://github.com/MacRuby/MacRuby · Ruby · 291 lines · 156 code · 24 blank · 111 comment · 18 complexity · 42d8404f095642df9697dd5a29441382 MD5 · raw file

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