From b44e9dfa01046bcf74170e44f91411a8dc7ff4ed Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Sat, 4 May 2002 09:58:01 +0000 Subject: [PATCH] Utilisation des versions reentrantes de gethostbyname et gethostbyaddr si possible git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@4770 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02 --- config/auto-aux/gethostbyaddr.c | 54 ++++++++++++++++ config/auto-aux/gethostbyname.c | 41 ++++++++++++ config/auto-aux/trycompile | 7 ++ config/s-templ.h | 12 ++++ configure | 18 ++++++ otherlibs/unix/gethost.c | 110 ++++++++++++++++++++++++++++---- 6 files changed, 229 insertions(+), 13 deletions(-) create mode 100644 config/auto-aux/gethostbyaddr.c create mode 100644 config/auto-aux/gethostbyname.c create mode 100755 config/auto-aux/trycompile diff --git a/config/auto-aux/gethostbyaddr.c b/config/auto-aux/gethostbyaddr.c new file mode 100644 index 000000000..5a10598ee --- /dev/null +++ b/config/auto-aux/gethostbyaddr.c @@ -0,0 +1,54 @@ +/***********************************************************************/ +/* */ +/* Objective Caml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 2002 Institut National de Recherche en Informatique et */ +/* en Automatique. All rights reserved. This file is distributed */ +/* under the terms of the GNU Library General Public License, with */ +/* the special exception on linking described in file ../../LICENSE. */ +/* */ +/***********************************************************************/ + +/* $Id$ */ + +#include +#include + +int main(int argc, char ** argv) +{ +#if NUM_ARGS == 7 + char * address; + int length; + int type; + struct hostent h; + char buffer[10]; + int buflen; + int h_errnop; + struct hostent * hp; + hp = gethostbyaddr_r(address, length, type, &h, + buffer, buflen, &h_errnop); +#elif NUM_ARGS == 8 + char * address; + int length; + int type; + struct hostent h; + char buffer[10]; + int buflen; + int h_errnop; + struct hostent * hp; + int rc; + rc = gethostbyaddr_r(address, length, type, &h, + buffer, buflen, &hp, &h_errnop); +#elif NUM_ARGS == 5 + char * address; + int length; + int type; + struct hostent h; + struct hostent_data hdata; + int rc; + rc = gethostbyaddr_r(address, length, type, &h, &hdata); +#endif + return 0; +} diff --git a/config/auto-aux/gethostbyname.c b/config/auto-aux/gethostbyname.c new file mode 100644 index 000000000..fa475b16d --- /dev/null +++ b/config/auto-aux/gethostbyname.c @@ -0,0 +1,41 @@ +/***********************************************************************/ +/* */ +/* Objective Caml */ +/* */ +/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ +/* */ +/* Copyright 2002 Institut National de Recherche en Informatique et */ +/* en Automatique. All rights reserved. This file is distributed */ +/* under the terms of the GNU Library General Public License, with */ +/* the special exception on linking described in file ../../LICENSE. */ +/* */ +/***********************************************************************/ + +/* $Id$ */ + +#include +#include + +int main(int argc, char ** argv) +{ +#if NUM_ARGS == 5 + struct hostent *hp; + struct hostent h; + char buffer[10]; + int h_errno; + hp = gethostbyname_r("www.caml.org", &h, buffer, 10, &h_errno); +#elif NUM_ARGS == 6 + struct hostent *hp; + struct hostent h; + char buffer[10]; + int h_errno; + int rc; + rc = gethostbyname_r("www.caml.org", &h, buffer, 10, &hp, &h_errno); +#elif NUM_ARGS == 3 + struct hostent h; + struct hostent_data hdata; + int rc; + rc = gethostbyname_r("www.caml.org", &h, &hdata); +#endif + return 0; +} diff --git a/config/auto-aux/trycompile b/config/auto-aux/trycompile new file mode 100755 index 000000000..797a1c386 --- /dev/null +++ b/config/auto-aux/trycompile @@ -0,0 +1,7 @@ +#!/bin/sh +if test "$verbose" = yes; then +echo "trycompile: $cc -o tst $* $cclibs" >&2 +$cc -o tst $* $cclibs || exit 100 +else +$cc -o tst $* $cclibs 2> /dev/null || exit 100 +fi diff --git a/config/s-templ.h b/config/s-templ.h index d5a914289..9904b4759 100644 --- a/config/s-templ.h +++ b/config/s-templ.h @@ -191,3 +191,15 @@ /* Define HAS_MMAP if you have the include file and the functions mmap() and munmap(). */ + +#define HAS_GETHOSTBYNAME_R 6 + +/* Define HAS_GETHOSTBYNAME_R if gethostbyname_r() is available. + The value of this symbol is the number of arguments of + gethostbyname_r(): either 3, 5 or 6 depending on prototype. */ + +#define HAS_GETHOSTBYADDR_R 8 + +/* Define HAS_GETHOSTBYADDR_R if gethostbyname_r() is available. + The value of this symbol is the number of arguments of + gethostbyaddr_r(): either 5, 7 or 8 depending on prototype. */ diff --git a/configure b/configure index 2472a7e57..788a5bb50 100755 --- a/configure +++ b/configure @@ -910,6 +910,24 @@ if sh ./hasgot -i sys/types.h -i sys/mman.h && sh ./hasgot mmap munmap; then echo "#define HAS_MMAP" >> s.h fi +nargs=none +for i in 5 6 3; do + if sh ./trycompile -DNUM_ARGS=${i} gethostbyname.c; then nargs=$i; break; fi +done +if test $nargs != "none"; then + echo "gethostbyname_r() found (with ${nargs} arguments)." + echo "#define HAS_GETHOSTBYNAME_R $nargs" >> s.h +fi + +nargs=none +for i in 7 8 5; do + if sh ./trycompile -DNUM_ARGS=${i} gethostbyaddr.c; then nargs=$i; break; fi +done +if test $nargs != "none"; then + echo "gethostbyaddr_r() found (with ${nargs} arguments)." + echo "#define HAS_GETHOSTBYADDR_R $nargs" >> s.h +fi + # Determine if the debugger is supported if test "$has_sockets" = "yes"; then diff --git a/otherlibs/unix/gethost.c b/otherlibs/unix/gethost.c index 2f3da9485..c1584ea6c 100644 --- a/otherlibs/unix/gethost.c +++ b/otherlibs/unix/gethost.c @@ -25,9 +25,17 @@ #include "socketaddr.h" #ifndef _WIN32 +#include #include #endif +#define NETDB_BUFFER_SIZE 10000 + +#ifdef _WIN32 +#define GETHOSTBYADDR_IS_REENTRANT +#define GETHOSTBYNAME_IS_REENTRANT +#endif + static int entry_h_length; extern int socket_domain_table[]; @@ -67,27 +75,103 @@ static value alloc_host_entry(struct hostent *entry) CAMLprim value unix_gethostbyaddr(value a) { - uint32 adr; - struct hostent * entry; - adr = GET_INET_ADDR(a); + uint32 adr = GET_INET_ADDR(a); + struct hostent * hp; +#if HAS_GETHOSTBYADDR_R == 7 + struct hostent h; + char buffer[NETDB_BUFFER_SIZE]; + int h_errnop; enter_blocking_section(); - entry = gethostbyaddr((char *) &adr, 4, AF_INET); + hp = gethostbyaddr_r((char *) &adr, 4, AF_INET, + &h, buffer, sizeof(buffer), &h_errnop); leave_blocking_section(); - if (entry == (struct hostent *) NULL) raise_not_found(); - return alloc_host_entry(entry); +#elif HAS_GETHOSTBYADDR_R == 8 + struct hostent h; + char buffer[NETDB_BUFFER_SIZE]; + int h_errnop, rc; + enter_blocking_section(); + rc = gethostbyaddr_r((char *) &adr, 4, AF_INET, + &h, buffer, sizeof(buffer), &hp, &h_errnop); + leave_blocking_section(); + if (rc != 0) hp = NULL; +#elif HAS_GETHOSTBYADDR_R == 5 + struct hostent h; + struct hostent_data hdata; + int rc; + enter_blocking_section(); + rc = gethostbyaddr_r((char *) &adr, 4, AF_INET, &h, &hdata); + leave_blocking_section(); + hp = rc == 0 ? &h : NULL; +#else +#ifdef GETHOSTBYADDR_IS_REENTRANT + enter_blocking_section(); +#endif + hp = gethostbyaddr((char *) &adr, 4, AF_INET); +#ifdef GETHOSTBYADDR_IS_REENTRANT + leave_blocking_section(); +#endif +#endif + if (hp == (struct hostent *) NULL) raise_not_found(); + return alloc_host_entry(hp); } CAMLprim value unix_gethostbyname(value name) { - char hostname[256]; - struct hostent * entry; - strncpy(hostname, String_val(name), sizeof(hostname) - 1); - hostname[sizeof(hostname) - 1] = 0; + struct hostent * hp; + char * hostname; + +#if HAS_GETHOSTBYNAME_R != 0 || GETHOSTBYNAME_IS_REENTRANT + hostname = stat_alloc(string_length(name) + 1); + strcpy(hostname, String_val(name)); +#else + hostname = String_val(name); +#endif + +#if HAS_GETHOSTBYNAME_R == 5 + { + struct hostent h; + char buffer[NETDB_BUFFER_SIZE]; + int h_errno; + enter_blocking_section(); + hp = gethostbyname_r(hostname, &h, buffer, sizeof(buffer), &h_errno); + leave_blocking_section(); + } +#elif HAS_GETHOSTBYNAME_R == 6 + { + struct hostent h; + char buffer[NETDB_BUFFER_SIZE]; + int h_errno, rc; + enter_blocking_section(); + rc = gethostbyname_r(hostname, &h, buffer, sizeof(buffer), &hp, &h_errno); + leave_blocking_section(); + if (rc != 0) hp = NULL; + } +#elif HAS_GETHOSTBYNAME_R == 3 + { + struct hostent h; + struct hostent_data hdata; + int rc; + enter_blocking_section(); + rc = gethostbyname_r(hostname, &h, &hdata); + leave_blocking_section(); + hp = rc == 0 ? &h : NULL; + } +#else +#ifdef GETHOSTBYNAME_IS_REENTRANT enter_blocking_section(); - entry = gethostbyname(hostname); +#endif + hp = gethostbyname(hostname); +#ifdef GETHOSTBYNAME_IS_REENTRANT leave_blocking_section(); - if (entry == (struct hostent *) NULL) raise_not_found(); - return alloc_host_entry(entry); +#endif +#endif + +#if HAS_GETHOSTBYNAME_R != 0 || GETHOSTBYNAME_IS_REENTRANT + stat_free(hostname); +#endif + + if (hp == (struct hostent *) NULL) raise_not_found(); + return alloc_host_entry(hp); } #else