Added non-blocking sockets test
[platform/upstream/curl.git] / acinclude.m4
1 dnl Check for how to set a socket to non-blocking state. There seems to exist
2 dnl four known different ways, with the one used almost everywhere being POSIX
3 dnl and XPG3, while the other different ways for different systems (old BSD,
4 dnl Windows and Amiga).
5 dnl
6 dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
7 dnl O_NONBLOCK define is found but does not work. This condition is attempted
8 dnl to get caught in this script by using an excessive number of #ifdefs...
9 dnl
10 AC_DEFUN(CURL_CHECK_NONBLOCKING_SOCKET,
11 [
12   AC_MSG_CHECKING([non-blocking sockets style])
13
14   AC_TRY_COMPILE([
15 /* headers for O_NONBLOCK test */
16 #include <sys/types.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 ],[
20 /* try to compile O_NONBLOCK */
21
22 #if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
23 # if defined(__SVR4) || defined(__srv4__)
24 #  define PLATFORM_SOLARIS
25 # else
26 #  define PLATFORM_SUNOS4
27 # endif
28 #endif
29 #if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4)
30 # define PLATFORM_AIX_V3
31 #endif
32
33 #if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3)
34 #error "O_NONBLOCK does not work on this platform"
35 #endif
36   int socket;
37   int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
38 ],[
39 dnl the O_NONBLOCK test was fine
40 nonblock="O_NONBLOCK"
41 AC_DEFINE(HAVE_O_NONBLOCK)
42 ],[
43 dnl the code was bad, try a different program now, test 2
44
45   AC_TRY_COMPILE([
46 /* headers for FIONBIO test */
47 #include <unistd.h>
48 #include <stropts.h>
49 ],[
50 /* FIONBIO source test */
51  int flags = ioctl(socket, FIONBIO, &flags);
52 ],[
53 dnl FIONBIO test was good
54 nonblock="FIONBIO"
55 AC_DEFINE(HAVE_FIONBIO)
56 ],[
57 dnl FIONBIO test was also bad
58 dnl the code was bad, try a different program now, test 3
59
60   AC_TRY_COMPILE([
61 /* headers for ioctlsocket test (cygwin?) */
62 #include <windows.h>
63 ],[
64 /* ioctlsocket source code */
65  int flags = ioctlsocket(socket, FIONBIO, &flags);
66 ],[
67 dnl ioctlsocket test was good
68 nonblock="ioctlsocket"
69 AC_DEFINE(HAVE_IOCTLSOCKET)
70 ],[
71 dnl ioctlsocket didnt compile!
72
73   AC_TRY_COMPILE([
74 /* headers for IoctlSocket test (Amiga?) */
75 #include <sys/ioctl.h>
76 ],[
77 /* IoctlSocket source code */
78  int flags = IoctlSocket(socket, FIONBIO, (long)1);
79 ],[
80 dnl ioctlsocket test was good
81 nonblock="IoctlSocket"
82 AC_DEFINE(HAVE_IOCTLSOCKET_CASE)
83 ],[
84 dnl ioctlsocket didnt compile!
85 nonblock="nada"
86 AC_DEFINE(HAVE_DISABLED_NONBLOCKING)
87 ])
88 dnl end of forth test
89
90 ])
91 dnl end of third test
92
93 ])
94 dnl end of second test
95
96 ])
97 dnl end of non-blocking try-compile test
98   AC_MSG_RESULT($nonblock)
99
100   if test "$nonblock" = "nada"; then
101     AC_MSG_WARN([non-block sockets disabled])
102   fi
103 ])
104
105 dnl Check for socklen_t: historically on BSD it is an int, and in
106 dnl POSIX 1g it is a type of its own, but some platforms use different
107 dnl types for the argument to getsockopt, getpeername, etc.  So we
108 dnl have to test to find something that will work.
109 AC_DEFUN([TYPE_SOCKLEN_T],
110 [
111    AC_CHECK_TYPE([socklen_t], ,[
112       AC_MSG_CHECKING([for socklen_t equivalent])
113       AC_CACHE_VAL([curl_cv_socklen_t_equiv],
114       [
115          # Systems have either "struct sockaddr *" or
116          # "void *" as the second argument to getpeername
117          curl_cv_socklen_t_equiv=
118          for arg2 in "struct sockaddr" void; do
119             for t in int size_t unsigned long "unsigned long"; do
120                AC_TRY_COMPILE([
121                   #include <sys/types.h>
122                   #include <sys/socket.h>
123
124                   int getpeername (int, $arg2 *, $t *);
125                ],[
126                   $t len;
127                   getpeername(0,0,&len);
128                ],[
129                   curl_cv_socklen_t_equiv="$t"
130                   break
131                ])
132             done
133          done
134
135          if test "x$curl_cv_socklen_t_equiv" = x; then
136             AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
137          fi
138       ])
139       AC_MSG_RESULT($curl_cv_socklen_t_equiv)
140       AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
141                         [type to use in place of socklen_t if not defined])],
142       [#include <sys/types.h>
143 #include <sys/socket.h>])
144 ])
145
146 dnl ************************************************************
147 dnl check for "localhost", if it doesn't exist, we can't do the
148 dnl gethostbyname_r tests!
149 dnl 
150
151 AC_DEFUN(CURL_CHECK_WORKING_RESOLVER,[
152 AC_MSG_CHECKING([if "localhost" resolves])
153 AC_TRY_RUN([
154 #include <string.h>
155 #include <sys/types.h>
156 #include <netdb.h>
157
158 int
159 main () {
160 struct hostent *h;
161 h = gethostbyname("localhost");
162 exit (h == NULL ? 1 : 0); }],[
163       AC_MSG_RESULT(yes)],[
164       AC_MSG_RESULT(no)
165       AC_MSG_ERROR([can't figure out gethostbyname_r() since localhost doesn't resolve])
166
167       ]
168 )
169 ])
170
171 dnl ************************************************************
172 dnl check for working getaddrinfo()
173 dnl
174 AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[
175   AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
176   AC_TRY_RUN( [
177 #include <netdb.h>
178 #include <sys/types.h>
179 #include <sys/socket.h>
180
181 void main(void) {
182     struct addrinfo hints, *ai;
183     int error;
184
185     memset(&hints, 0, sizeof(hints));
186     hints.ai_family = AF_UNSPEC;
187     hints.ai_socktype = SOCK_STREAM;
188     error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
189     if (error) {
190         exit(1);
191     }
192     else {
193         exit(0);
194     }
195 }
196 ],[
197   ac_cv_working_getaddrinfo="yes"
198 ],[
199   ac_cv_working_getaddrinfo="no"
200 ],[
201   ac_cv_working_getaddrinfo="yes"
202 ])])
203 if test "$ac_cv_working_getaddrinfo" = "yes"; then
204   AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if getaddrinfo exists and works])
205   AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support])
206
207   IPV6_ENABLED=1
208   AC_SUBST(IPV6_ENABLED)
209 fi
210 ])
211
212
213 AC_DEFUN(CURL_CHECK_LOCALTIME_R,
214 [
215   dnl check for a few thread-safe functions
216   AC_CHECK_FUNCS(localtime_r,[
217     AC_MSG_CHECKING(whether localtime_r is declared)
218     AC_EGREP_CPP(localtime_r,[
219 #include <time.h>],[
220       AC_MSG_RESULT(yes)],[
221       AC_MSG_RESULT(no)
222       AC_MSG_CHECKING(whether localtime_r with -D_REENTRANT is declared)
223       AC_EGREP_CPP(localtime_r,[
224 #define _REENTRANT
225 #include <time.h>],[
226         AC_DEFINE(NEED_REENTRANT)
227         AC_MSG_RESULT(yes)],
228         AC_MSG_RESULT(no))])])
229 ])
230
231 AC_DEFUN(CURL_CHECK_INET_NTOA_R,
232 [
233   dnl determine if function definition for inet_ntoa_r exists.
234   AC_CHECK_FUNCS(inet_ntoa_r,[
235     AC_MSG_CHECKING(whether inet_ntoa_r is declared)
236     AC_EGREP_CPP(inet_ntoa_r,[
237 #include <arpa/inet.h>],[
238       AC_DEFINE(HAVE_INET_NTOA_R_DECL)
239       AC_MSG_RESULT(yes)],[
240       AC_MSG_RESULT(no)
241       AC_MSG_CHECKING(whether inet_ntoa_r with -D_REENTRANT is declared)
242       AC_EGREP_CPP(inet_ntoa_r,[
243 #define _REENTRANT
244 #include <arpa/inet.h>],[
245         AC_DEFINE(HAVE_INET_NTOA_R_DECL)
246         AC_DEFINE(NEED_REENTRANT)
247         AC_MSG_RESULT(yes)],
248         AC_MSG_RESULT(no))])])
249
250 ])
251
252 AC_DEFUN(CURL_CHECK_GETHOSTBYADDR_R,
253 [
254   dnl check for number of arguments to gethostbyaddr_r. it might take
255   dnl either 5, 7, or 8 arguments.
256   AC_CHECK_FUNCS(gethostbyaddr_r,[
257     AC_MSG_CHECKING(if gethostbyaddr_r takes 5 arguments)
258     AC_TRY_COMPILE([
259 #include <sys/types.h>
260 #include <netdb.h>],[
261 char * address;
262 int length;
263 int type;
264 struct hostent h;
265 struct hostent_data hdata;
266 int rc;
267 rc = gethostbyaddr_r(address, length, type, &h, &hdata);],[
268       AC_MSG_RESULT(yes)
269       AC_DEFINE(HAVE_GETHOSTBYADDR_R_5)
270       ac_cv_gethostbyaddr_args=5],[
271       AC_MSG_RESULT(no)
272       AC_MSG_CHECKING(if gethostbyaddr_r with -D_REENTRANT takes 5 arguments)
273       AC_TRY_COMPILE([
274 #define _REENTRANT
275 #include <sys/types.h>
276 #include <netdb.h>],[
277 char * address;
278 int length;
279 int type;
280 struct hostent h;
281 struct hostent_data hdata;
282 int rc;
283 rc = gethostbyaddr_r(address, length, type, &h, &hdata);],[
284         AC_MSG_RESULT(yes)
285         AC_DEFINE(HAVE_GETHOSTBYADDR_R_5)
286         AC_DEFINE(NEED_REENTRANT)
287         ac_cv_gethostbyaddr_args=5],[
288         AC_MSG_RESULT(no)
289         AC_MSG_CHECKING(if gethostbyaddr_r takes 7 arguments)
290         AC_TRY_COMPILE([
291 #include <sys/types.h>
292 #include <netdb.h>],[
293 char * address;
294 int length;
295 int type;
296 struct hostent h;
297 char buffer[8192];
298 int h_errnop;
299 struct hostent * hp;
300
301 hp = gethostbyaddr_r(address, length, type, &h,
302                      buffer, 8192, &h_errnop);],[
303           AC_MSG_RESULT(yes)
304           AC_DEFINE(HAVE_GETHOSTBYADDR_R_7)
305           ac_cv_gethostbyaddr_args=7],[
306           AC_MSG_RESULT(no)
307           AC_MSG_CHECKING(if gethostbyaddr_r takes 8 arguments)
308           AC_TRY_COMPILE([
309 #include <sys/types.h>
310 #include <netdb.h>],[
311 char * address;
312 int length;
313 int type;
314 struct hostent h;
315 char buffer[8192];
316 int h_errnop;
317 struct hostent * hp;
318 int rc;
319
320 rc = gethostbyaddr_r(address, length, type, &h,
321                      buffer, 8192, &hp, &h_errnop);],[
322             AC_MSG_RESULT(yes)
323             AC_DEFINE(HAVE_GETHOSTBYADDR_R_8)
324             ac_cv_gethostbyaddr_args=8],[
325             AC_MSG_RESULT(no)
326             have_missing_r_funcs="$have_missing_r_funcs gethostbyaddr_r"])])])])])
327
328
329 ])
330
331 AC_DEFUN(CURL_CHECK_GETHOSTBYNAME_R,
332 [
333   dnl check for number of arguments to gethostbyname_r. it might take
334   dnl either 3, 5, or 6 arguments.
335   AC_CHECK_FUNCS(gethostbyname_r,[
336     AC_MSG_CHECKING(if gethostbyname_r takes 3 arguments)
337     AC_TRY_RUN([
338 #include <string.h>
339 #include <sys/types.h>
340 #include <netdb.h>
341
342 int
343 main () {
344 struct hostent h;
345 struct hostent_data hdata;
346 char *name = "localhost";
347 int rc;
348 memset(&h, 0, sizeof(struct hostent));
349 memset(&hdata, 0, sizeof(struct hostent_data));
350 rc = gethostbyname_r(name, &h, &hdata);
351 exit (rc != 0 ? 1 : 0); }],[
352       AC_MSG_RESULT(yes)
353       AC_DEFINE(HAVE_GETHOSTBYNAME_R_3)
354       ac_cv_gethostbyname_args=3],[
355       AC_MSG_RESULT(no)
356       AC_MSG_CHECKING(if gethostbyname_r with -D_REENTRANT takes 3 arguments)
357       AC_TRY_RUN([
358 #define _REENTRANT
359
360 #include <string.h>
361 #include <sys/types.h>
362 #include <netdb.h>
363
364 int
365 main () {
366 struct hostent h;
367 struct hostent_data hdata;
368 char *name = "localhost";
369 int rc;
370 memset(&h, 0, sizeof(struct hostent));
371 memset(&hdata, 0, sizeof(struct hostent_data));
372 rc = gethostbyname_r(name, &h, &hdata);
373 exit (rc != 0 ? 1 : 0); }],[
374         AC_MSG_RESULT(yes)
375         AC_DEFINE(HAVE_GETHOSTBYNAME_R_3)
376         AC_DEFINE(NEED_REENTRANT)
377         ac_cv_gethostbyname_args=3],[
378         AC_MSG_RESULT(no)
379         AC_MSG_CHECKING(if gethostbyname_r takes 5 arguments)
380         AC_TRY_RUN([
381 #include <sys/types.h>
382 #include <netdb.h>
383
384 int
385 main () {
386 struct hostent *hp;
387 struct hostent h;
388 char *name = "localhost";
389 char buffer[8192];
390 int h_errno;
391 hp = gethostbyname_r(name, &h, buffer, 8192, &h_errno);
392 exit (hp == NULL ? 1 : 0); }],[
393           AC_MSG_RESULT(yes)
394           AC_DEFINE(HAVE_GETHOSTBYNAME_R_5)
395           ac_cv_gethostbyname_args=5],[
396           AC_MSG_RESULT(no)
397           AC_MSG_CHECKING(if gethostbyname_r takes 6 arguments)
398           AC_TRY_RUN([
399 #include <sys/types.h>
400 #include <netdb.h>
401
402 int
403 main () {
404 struct hostent h;
405 struct hostent *hp;
406 char *name = "localhost";
407 char buf[8192];
408 int rc;
409 int h_errno;
410 rc = gethostbyname_r(name, &h, buf, 8192, &hp, &h_errno);
411 exit (rc != 0 ? 1 : 0); }],[
412             AC_MSG_RESULT(yes)
413             AC_DEFINE(HAVE_GETHOSTBYNAME_R_6)
414             ac_cv_gethostbyname_args=6],[
415             AC_MSG_RESULT(no)
416             have_missing_r_funcs="$have_missing_r_funcs gethostbyname_r"],
417             [ac_cv_gethostbyname_args=0])],
418           [ac_cv_gethostbyname_args=0])],
419         [ac_cv_gethostbyname_args=0])],
420       [ac_cv_gethostbyname_args=0])])
421
422 if test "$ac_cv_func_gethostbyname_r" = "yes"; then
423   if test "$ac_cv_gethostbyname_args" = "0"; then
424     dnl there's a gethostbyname_r() function, but we don't know how
425     dnl many arguments it wants!
426     AC_MSG_ERROR([couldn't figure out how to use gethostbyname_r()])
427   fi
428 fi
429 ])