make CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR

and CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME
internal to CHECK_FUNC_GETADDRINFO
This commit is contained in:
Yang Tse 2008-10-29 01:45:07 +00:00
parent 9c86097286
commit 23eb74e085
4 changed files with 270 additions and 278 deletions

View File

@ -554,8 +554,6 @@ CURL_CHECK_FUNC_SEND
CURL_CHECK_MSG_NOSIGNAL CURL_CHECK_MSG_NOSIGNAL
CARES_CHECK_FUNC_GETADDRINFO CARES_CHECK_FUNC_GETADDRINFO
CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME
CARES_CHECK_FUNC_GETHOSTNAME CARES_CHECK_FUNC_GETHOSTNAME
CARES_CHECK_FUNC_GETSERVBYPORT_R CARES_CHECK_FUNC_GETSERVBYPORT_R
CARES_CHECK_FUNC_INET_NTOP CARES_CHECK_FUNC_INET_NTOP

View File

@ -16,7 +16,7 @@
#*************************************************************************** #***************************************************************************
# File version for 'aclocal' use. Keep it a single number. # File version for 'aclocal' use. Keep it a single number.
# serial 13 # serial 14
dnl CARES_INCLUDES_ARPA_INET dnl CARES_INCLUDES_ARPA_INET
@ -243,6 +243,7 @@ AC_DEFUN([CARES_CHECK_FUNC_GETADDRINFO], [
AC_REQUIRE([CARES_INCLUDES_STDLIB])dnl AC_REQUIRE([CARES_INCLUDES_STDLIB])dnl
AC_REQUIRE([CARES_INCLUDES_SYS_SOCKET])dnl AC_REQUIRE([CARES_INCLUDES_SYS_SOCKET])dnl
AC_REQUIRE([CARES_INCLUDES_NETDB])dnl AC_REQUIRE([CARES_INCLUDES_NETDB])dnl
AC_REQUIRE([CARES_INCLUDES_STRING])dnl
# #
tst_links_getaddrinfo="unknown" tst_links_getaddrinfo="unknown"
tst_proto_getaddrinfo="unknown" tst_proto_getaddrinfo="unknown"
@ -363,154 +364,151 @@ AC_DEFUN([CARES_CHECK_FUNC_GETADDRINFO], [
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
ac_cv_func_getaddrinfo="no" ac_cv_func_getaddrinfo="no"
fi fi
])
dnl CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
dnl -------------------------------------------------
dnl verify if the ai_addr pointer member of the addrinfo
dnl struct returned by function getaddrinfo is a pointer
dnl which can actually be free()ed or not.
AC_DEFUN([CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR], [
AC_REQUIRE([CARES_CHECK_FUNC_GETADDRINFO])dnl
AC_REQUIRE([CARES_INCLUDES_STRING])dnl
# #
if test "$ac_cv_func_getaddrinfo" = "yes"; then if test "$ac_cv_func_getaddrinfo" = "yes"; then
AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_addr]) DO_CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
dnl only do runtime verification when not cross-compiling DO_CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME
if test "x$cross_compiling" != "xyes"; then
AC_RUN_IFELSE([
AC_LANG_PROGRAM([[
$cares_includes_ws2tcpip
$cares_includes_stdlib
$cares_includes_sys_socket
$cares_includes_netdb
$cares_includes_string
]],[[
struct sockaddr tmp_addr, *ai_addr, *freed_ptr;
struct addrinfo hints;
struct addrinfo *ai = 0;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", 0, &hints, &ai);
if(error || !ai)
/* should not happen, same test already succeeded, */
/* assume that returned ai_addr is not unfreeable. */
exit(0);
memset(&tmp_addr, 1, sizeof(tmp_addr));
/* attempt to free ai_addr pointer */
freed_ptr = ai_addr = ai->ai_addr;
/* seg-fault free'ing an unfreeable ptr would be */
/* nice, if this happen exit code will be non-zero. */
free(ai_addr);
/* attempt to write free'ed memory */
freed_ptr->sa_family = 'x';
/* attempt to reuse and clear free'ed memory */
ai_addr = calloc(1, sizeof(struct sockaddr));
/* attempt to read free'ed memory */
tmp_addr = *freed_ptr;
/* verify if everithing has worked */
if(tmp_addr.sa_family == 'x')
/* ai_addr might be unfreeable, ouch! */
exit(1);
else
/* ai_addr is certainly freeable */
exit(0);
]])
],[
dnl exit code was zero, getaddrinfo behaves nicely.
AC_MSG_RESULT([no])
],[
dnl exit code wasn't zero, getaddrinfo returns unfreeable ptr.
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_ADDR, 1,
[Define to 1 if getaddrinfo returns unfreeable ai_addr pointer.])
])
else
dnl for cross-compiling a static check would be nice.
AC_MSG_RESULT([unknown])
fi
fi fi
]) ])
dnl CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME dnl DO_CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
dnl -------------------------------------------------
dnl verify if the ai_addr pointer member of the addrinfo
dnl struct returned by function getaddrinfo is a pointer
dnl which can actually be free()ed or not. This is an
dnl internal macro used by CARES_CHECK_FUNC_GETADDRINFO
AC_DEFUN([DO_CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR], [
AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_addr])
dnl only do runtime verification when not cross-compiling
if test "x$cross_compiling" != "xyes"; then
AC_RUN_IFELSE([
AC_LANG_PROGRAM([[
$cares_includes_ws2tcpip
$cares_includes_stdlib
$cares_includes_sys_socket
$cares_includes_netdb
$cares_includes_string
]],[[
struct sockaddr tmp_addr, *ai_addr, *freed_ptr;
struct addrinfo hints;
struct addrinfo *ai = 0;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", 0, &hints, &ai);
if(error || !ai)
/* should not happen, same test already succeeded, */
/* assume that returned ai_addr is not unfreeable. */
exit(0);
memset(&tmp_addr, 1, sizeof(tmp_addr));
/* attempt to free ai_addr pointer */
freed_ptr = ai_addr = ai->ai_addr;
/* seg-faulting when free'ing an unfreeable ptr would be nice */
/* and desired here, if this happens exit code will be non-zero. */
free(ai_addr);
/* attempt to write free'ed memory */
freed_ptr->sa_family = 'x';
/* attempt to reuse and clear free'ed memory */
ai_addr = calloc(1, sizeof(struct sockaddr));
/* attempt to read free'ed memory */
tmp_addr = *freed_ptr;
/* verify if everything has worked */
if(tmp_addr.sa_family == 'x')
/* ai_addr might be unfreeable, ouch! */
exit(1);
else
/* ai_addr is certainly freeable */
exit(0);
]])
],[
dnl exit code was zero, getaddrinfo behaves nicely.
AC_MSG_RESULT([no])
],[
dnl exit code wasn't zero, getaddrinfo returns unfreeable ptr.
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_ADDR, 1,
[Define to 1 if getaddrinfo returns unfreeable ai_addr pointer.])
])
else
dnl for cross-compiling a static check would be nice.
AC_MSG_RESULT([unknown])
fi
])
dnl DO_CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl verify if the ai_canonname pointer member of the addrinfo dnl verify if the ai_canonname pointer member of the addrinfo
dnl struct returned by function getaddrinfo is a pointer dnl struct returned by function getaddrinfo is a pointer
dnl which can actually be free()ed or not. dnl which can actually be free()ed or not. This is an
dnl internal macro used by CARES_CHECK_FUNC_GETADDRINFO
AC_DEFUN([CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME], [ AC_DEFUN([DO_CARES_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME], [
AC_REQUIRE([CARES_CHECK_FUNC_GETADDRINFO])dnl AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_canonname])
AC_REQUIRE([CARES_INCLUDES_STRING])dnl dnl only do runtime verification when not cross-compiling
# if test "x$cross_compiling" != "xyes"; then
if test "$ac_cv_func_getaddrinfo" = "yes"; then AC_RUN_IFELSE([
AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_canonname]) AC_LANG_PROGRAM([[
dnl only do runtime verification when not cross-compiling $cares_includes_ws2tcpip
if test "x$cross_compiling" != "xyes"; then $cares_includes_stdlib
AC_RUN_IFELSE([ $cares_includes_sys_socket
AC_LANG_PROGRAM([[ $cares_includes_netdb
$cares_includes_ws2tcpip $cares_includes_string
$cares_includes_stdlib ]],[[
$cares_includes_sys_socket char tmp_canonname[80];
$cares_includes_netdb char *ai_canonname, *freed_ptr;
$cares_includes_string struct addrinfo hints;
]],[[ struct addrinfo *ai = 0;
char tmp_canonname[80]; int error;
char *ai_canonname, *freed_ptr;
struct addrinfo hints;
struct addrinfo *ai = 0;
int error;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST|AI_CANONNAME; hints.ai_flags = AI_NUMERICHOST|AI_CANONNAME;
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", 0, &hints, &ai); error = getaddrinfo("127.0.0.1", 0, &hints, &ai);
if(error || !ai) if(error || !ai)
/* should not happen, same test already succeeded, */ /* should not happen, same test already succeeded, */
/* assume that returned ai_canonname not unfreeable. */ /* assume that returned ai_canonname not unfreeable. */
exit(0); exit(0);
memset(&tmp_canonname, 1, sizeof(tmp_canonname)); memset(&tmp_canonname, 1, sizeof(tmp_canonname));
/* attempt to free ai_canonname pointer */ /* attempt to free ai_canonname pointer */
freed_ptr = ai_canonname = ai->ai_canonname; freed_ptr = ai_canonname = ai->ai_canonname;
/* seg-fault free'ing an unfreeable ptr would be */ /* seg-faulting when free'ing an unfreeable ptr would be nice */
/* nice, if this happen exit code will be non-zero. */ /* and desired here, if this happens exit code will be non-zero. */
free(ai_canonname); free(ai_canonname);
/* attempt to write free'ed memory */ /* attempt to write free'ed memory */
freed_ptr[0] = 'x'; freed_ptr[0] = 'x';
/* attempt to reuse and clear free'ed memory */ /* attempt to reuse and clear free'ed memory */
ai_canonname = calloc(1, sizeof(tmp_canonname)); ai_canonname = calloc(1, sizeof(tmp_canonname));
/* attempt to read free'ed memory */ /* attempt to read free'ed memory */
tmp_canonname[0] = freed_ptr[0]; tmp_canonname[0] = freed_ptr[0];
/* verify if everithing has worked */ /* verify if everything has worked */
if(tmp_canonname[0] == 'x') if(tmp_canonname[0] == 'x')
/* ai_canonname might be unfreeable, ouch! */ /* ai_canonname might be unfreeable, ouch! */
exit(1); exit(1);
else else
/* ai_canonname is certainly freeable */ /* ai_canonname is certainly freeable */
exit(0); exit(0);
]]) ]])
],[ ],[
dnl exit code was zero, getaddrinfo behaves nicely. dnl exit code was zero, getaddrinfo behaves nicely.
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
],[ ],[
dnl exit code wasn't zero, getaddrinfo returns unfreeable ptr. dnl exit code wasn't zero, getaddrinfo returns unfreeable member ptr.
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_CANONNAME, 1, AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_CANONNAME, 1,
[Define to 1 if getaddrinfo returns unfreeable ai_canonname pointer.]) [Define to 1 if getaddrinfo returns unfreeable ai_canonname pointer.])
]) ])
else else
dnl for cross-compiling a static check would be nice. dnl for cross-compiling a static check would be nice.
AC_MSG_RESULT([unknown]) AC_MSG_RESULT([unknown])
fi
fi fi
]) ])

View File

@ -2017,8 +2017,6 @@ CURL_CHECK_FUNC_ALARM
CURL_CHECK_FUNC_FDOPEN CURL_CHECK_FUNC_FDOPEN
CURL_CHECK_FUNC_FTRUNCATE CURL_CHECK_FUNC_FTRUNCATE
CURL_CHECK_FUNC_GETADDRINFO CURL_CHECK_FUNC_GETADDRINFO
CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME
CURL_CHECK_FUNC_GETHOSTBYADDR_R CURL_CHECK_FUNC_GETHOSTBYADDR_R
CURL_CHECK_FUNC_GETHOSTBYNAME_R CURL_CHECK_FUNC_GETHOSTBYNAME_R
CURL_CHECK_FUNC_GETHOSTNAME CURL_CHECK_FUNC_GETHOSTNAME

View File

@ -22,7 +22,7 @@
#*************************************************************************** #***************************************************************************
# File version for 'aclocal' use. Keep it a single number. # File version for 'aclocal' use. Keep it a single number.
# serial 29 # serial 30
dnl CURL_INCLUDES_ARPA_INET dnl CURL_INCLUDES_ARPA_INET
@ -596,6 +596,7 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [
AC_REQUIRE([CURL_INCLUDES_STDLIB])dnl AC_REQUIRE([CURL_INCLUDES_STDLIB])dnl
AC_REQUIRE([CURL_INCLUDES_SYS_SOCKET])dnl AC_REQUIRE([CURL_INCLUDES_SYS_SOCKET])dnl
AC_REQUIRE([CURL_INCLUDES_NETDB])dnl AC_REQUIRE([CURL_INCLUDES_NETDB])dnl
AC_REQUIRE([CURL_INCLUDES_STRING])dnl
# #
tst_links_getaddrinfo="unknown" tst_links_getaddrinfo="unknown"
tst_proto_getaddrinfo="unknown" tst_proto_getaddrinfo="unknown"
@ -716,154 +717,151 @@ AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO], [
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
ac_cv_func_getaddrinfo="no" ac_cv_func_getaddrinfo="no"
fi fi
])
dnl CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
dnl -------------------------------------------------
dnl verify if the ai_addr pointer member of the addrinfo
dnl struct returned by function getaddrinfo is a pointer
dnl which can actually be free()ed or not.
AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR], [
AC_REQUIRE([CURL_CHECK_FUNC_GETADDRINFO])dnl
AC_REQUIRE([CURL_INCLUDES_STRING])dnl
# #
if test "$ac_cv_func_getaddrinfo" = "yes"; then if test "$ac_cv_func_getaddrinfo" = "yes"; then
AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_addr]) DO_CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
dnl only do runtime verification when not cross-compiling DO_CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME
if test "x$cross_compiling" != "xyes"; then
AC_RUN_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_ws2tcpip
$curl_includes_stdlib
$curl_includes_sys_socket
$curl_includes_netdb
$curl_includes_string
]],[[
struct sockaddr tmp_addr, *ai_addr, *freed_ptr;
struct addrinfo hints;
struct addrinfo *ai = 0;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", 0, &hints, &ai);
if(error || !ai)
/* should not happen, same test already succeeded, */
/* assume that returned ai_addr is not unfreeable. */
exit(0);
memset(&tmp_addr, 1, sizeof(tmp_addr));
/* attempt to free ai_addr pointer */
freed_ptr = ai_addr = ai->ai_addr;
/* seg-fault free'ing an unfreeable ptr would be */
/* nice, if this happen exit code will be non-zero. */
free(ai_addr);
/* attempt to write free'ed memory */
freed_ptr->sa_family = 'x';
/* attempt to reuse and clear free'ed memory */
ai_addr = calloc(1, sizeof(struct sockaddr));
/* attempt to read free'ed memory */
tmp_addr = *freed_ptr;
/* verify if everithing has worked */
if(tmp_addr.sa_family == 'x')
/* ai_addr might be unfreeable, ouch! */
exit(1);
else
/* ai_addr is certainly freeable */
exit(0);
]])
],[
dnl exit code was zero, getaddrinfo behaves nicely.
AC_MSG_RESULT([no])
],[
dnl exit code wasn't zero, getaddrinfo returns unfreeable ptr.
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_ADDR, 1,
[Define to 1 if getaddrinfo returns unfreeable ai_addr pointer.])
])
else
dnl for cross-compiling a static check would be nice.
AC_MSG_RESULT([unknown])
fi
fi fi
]) ])
dnl CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME dnl DO_CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR
dnl -------------------------------------------------
dnl verify if the ai_addr pointer member of the addrinfo
dnl struct returned by function getaddrinfo is a pointer
dnl which can actually be free()ed or not. This is an
dnl internal macro used by CURL_CHECK_FUNC_GETADDRINFO
AC_DEFUN([DO_CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR], [
AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_addr])
dnl only do runtime verification when not cross-compiling
if test "x$cross_compiling" != "xyes"; then
AC_RUN_IFELSE([
AC_LANG_PROGRAM([[
$curl_includes_ws2tcpip
$curl_includes_stdlib
$curl_includes_sys_socket
$curl_includes_netdb
$curl_includes_string
]],[[
struct sockaddr tmp_addr, *ai_addr, *freed_ptr;
struct addrinfo hints;
struct addrinfo *ai = 0;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", 0, &hints, &ai);
if(error || !ai)
/* should not happen, same test already succeeded, */
/* assume that returned ai_addr is not unfreeable. */
exit(0);
memset(&tmp_addr, 1, sizeof(tmp_addr));
/* attempt to free ai_addr pointer */
freed_ptr = ai_addr = ai->ai_addr;
/* seg-faulting when free'ing an unfreeable ptr would be nice */
/* and desired here, if this happens exit code will be non-zero. */
free(ai_addr);
/* attempt to write free'ed memory */
freed_ptr->sa_family = 'x';
/* attempt to reuse and clear free'ed memory */
ai_addr = calloc(1, sizeof(struct sockaddr));
/* attempt to read free'ed memory */
tmp_addr = *freed_ptr;
/* verify if everything has worked */
if(tmp_addr.sa_family == 'x')
/* ai_addr might be unfreeable, ouch! */
exit(1);
else
/* ai_addr is certainly freeable */
exit(0);
]])
],[
dnl exit code was zero, getaddrinfo behaves nicely.
AC_MSG_RESULT([no])
],[
dnl exit code wasn't zero, getaddrinfo returns unfreeable member ptr.
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_ADDR, 1,
[Define to 1 if getaddrinfo returns unfreeable ai_addr pointer.])
])
else
dnl for cross-compiling a static check would be nice.
AC_MSG_RESULT([unknown])
fi
])
dnl DO_CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl verify if the ai_canonname pointer member of the addrinfo dnl verify if the ai_canonname pointer member of the addrinfo
dnl struct returned by function getaddrinfo is a pointer dnl struct returned by function getaddrinfo is a pointer
dnl which can actually be free()ed or not. dnl which can actually be free()ed or not. This is an
dnl internal macro used by CURL_CHECK_FUNC_GETADDRINFO
AC_DEFUN([CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME], [ AC_DEFUN([DO_CURL_CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME], [
AC_REQUIRE([CURL_CHECK_FUNC_GETADDRINFO])dnl AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_canonname])
AC_REQUIRE([CURL_INCLUDES_STRING])dnl dnl only do runtime verification when not cross-compiling
# if test "x$cross_compiling" != "xyes"; then
if test "$ac_cv_func_getaddrinfo" = "yes"; then AC_RUN_IFELSE([
AC_MSG_CHECKING([if getaddrinfo returns unfreeable ai_canonname]) AC_LANG_PROGRAM([[
dnl only do runtime verification when not cross-compiling $curl_includes_ws2tcpip
if test "x$cross_compiling" != "xyes"; then $curl_includes_stdlib
AC_RUN_IFELSE([ $curl_includes_sys_socket
AC_LANG_PROGRAM([[ $curl_includes_netdb
$curl_includes_ws2tcpip $curl_includes_string
$curl_includes_stdlib ]],[[
$curl_includes_sys_socket char tmp_canonname[80];
$curl_includes_netdb char *ai_canonname, *freed_ptr;
$curl_includes_string struct addrinfo hints;
]],[[ struct addrinfo *ai = 0;
char tmp_canonname[80]; int error;
char *ai_canonname, *freed_ptr;
struct addrinfo hints;
struct addrinfo *ai = 0;
int error;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST|AI_CANONNAME; hints.ai_flags = AI_NUMERICHOST|AI_CANONNAME;
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", 0, &hints, &ai); error = getaddrinfo("127.0.0.1", 0, &hints, &ai);
if(error || !ai) if(error || !ai)
/* should not happen, same test already succeeded, */ /* should not happen, same test already succeeded, */
/* assume that returned ai_canonname not unfreeable. */ /* assume that returned ai_canonname not unfreeable. */
exit(0); exit(0);
memset(&tmp_canonname, 1, sizeof(tmp_canonname)); memset(&tmp_canonname, 1, sizeof(tmp_canonname));
/* attempt to free ai_canonname pointer */ /* attempt to free ai_canonname pointer */
freed_ptr = ai_canonname = ai->ai_canonname; freed_ptr = ai_canonname = ai->ai_canonname;
/* seg-fault free'ing an unfreeable ptr would be */ /* seg-faulting when free'ing an unfreeable ptr would be nice */
/* nice, if this happen exit code will be non-zero. */ /* and desired here, if this happens exit code will be non-zero. */
free(ai_canonname); free(ai_canonname);
/* attempt to write free'ed memory */ /* attempt to write free'ed memory */
freed_ptr[0] = 'x'; freed_ptr[0] = 'x';
/* attempt to reuse and clear free'ed memory */ /* attempt to reuse and clear free'ed memory */
ai_canonname = calloc(1, sizeof(tmp_canonname)); ai_canonname = calloc(1, sizeof(tmp_canonname));
/* attempt to read free'ed memory */ /* attempt to read free'ed memory */
tmp_canonname[0] = freed_ptr[0]; tmp_canonname[0] = freed_ptr[0];
/* verify if everithing has worked */ /* verify if everything has worked */
if(tmp_canonname[0] == 'x') if(tmp_canonname[0] == 'x')
/* ai_canonname might be unfreeable, ouch! */ /* ai_canonname might be unfreeable, ouch! */
exit(1); exit(1);
else else
/* ai_canonname is certainly freeable */ /* ai_canonname is certainly freeable */
exit(0); exit(0);
]]) ]])
],[ ],[
dnl exit code was zero, getaddrinfo behaves nicely. dnl exit code was zero, getaddrinfo behaves nicely.
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
],[ ],[
dnl exit code wasn't zero, getaddrinfo returns unfreeable ptr. dnl exit code wasn't zero, getaddrinfo returns unfreeable member ptr.
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_CANONNAME, 1, AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_UNFREEABLE_AI_CANONNAME, 1,
[Define to 1 if getaddrinfo returns unfreeable ai_canonname pointer.]) [Define to 1 if getaddrinfo returns unfreeable ai_canonname pointer.])
]) ])
else else
dnl for cross-compiling a static check would be nice. dnl for cross-compiling a static check would be nice.
AC_MSG_RESULT([unknown]) AC_MSG_RESULT([unknown])
fi
fi fi
]) ])