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