Commit ff7a61f8 authored by Rein Klazes's avatar Rein Klazes Committed by Alexandre Julliard

Make calls to gethostbyname, gethostbyaddr, getservbyname,

getservbyport, getprotobyname and getprotobynumber thread-safe.
parent 2cc15088
...@@ -5883,15 +5883,66 @@ EOF ...@@ -5883,15 +5883,66 @@ EOF
echo $ac_n "checking "whether we can use re-entrant gethostbyname_r Linux style"""... $ac_c" 1>&6
echo "configure:5889: checking "whether we can use re-entrant gethostbyname_r Linux style"" >&5
if eval "test \"`echo '$''{'wine_cv_linux_gethostbyname_r_6'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 5894 "configure"
#include "confdefs.h"
#include <netdb.h>
int main() {
char *name=NULL;
struct hostent he;
struct hostent *result;
char *buf=NULL;
int bufsize=0;
int res,errnr;
char *addr=NULL;
int addrlen=0;
int addrtype=0;
res=gethostbyname_r(name,&he,buf,bufsize,&result,&errnr);
res=gethostbyaddr_r(addr, addrlen, addrtype,&he,buf,bufsize,&result,&errnr);
; return 0; }
EOF
if { (eval echo configure:5915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
wine_cv_linux_gethostbyname_r_6=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
wine_cv_linux_gethostbyname_r_6=no
fi
rm -f conftest*
fi
echo "$ac_t""$wine_cv_linux_gethostbyname_r_6" 1>&6
if test "$wine_cv_linux_gethostbyname_r_6" = "yes"
then
cat >> confdefs.h <<\EOF
#define HAVE_LINUX_GETHOSTBYNAME_R_6 1
EOF
fi
if test "$ac_cv_header_linux_joystick_h" = "yes" if test "$ac_cv_header_linux_joystick_h" = "yes"
then then
echo $ac_n "checking "whether linux/joystick.h uses the Linux 2.2+ API"""... $ac_c" 1>&6 echo $ac_n "checking "whether linux/joystick.h uses the Linux 2.2+ API"""... $ac_c" 1>&6
echo "configure:5890: checking "whether linux/joystick.h uses the Linux 2.2+ API"" >&5 echo "configure:5941: checking "whether linux/joystick.h uses the Linux 2.2+ API"" >&5
if eval "test \"`echo '$''{'wine_cv_linux_joystick_22_api'+set}'`\" = set"; then if eval "test \"`echo '$''{'wine_cv_linux_joystick_22_api'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 5895 "configure" #line 5946 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
...@@ -5906,7 +5957,7 @@ int main() { ...@@ -5906,7 +5957,7 @@ int main() {
/*empty*/ /*empty*/
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:5910: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:5961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
wine_cv_linux_joystick_22_api=yes wine_cv_linux_joystick_22_api=yes
else else
...@@ -5933,12 +5984,12 @@ fi ...@@ -5933,12 +5984,12 @@ fi
if test "$ac_cv_header_sys_vfs_h" = "yes" if test "$ac_cv_header_sys_vfs_h" = "yes"
then then
echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6 echo $ac_n "checking "whether sys/vfs.h defines statfs"""... $ac_c" 1>&6
echo "configure:5937: checking "whether sys/vfs.h defines statfs"" >&5 echo "configure:5988: checking "whether sys/vfs.h defines statfs"" >&5
if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then if eval "test \"`echo '$''{'wine_cv_sys_vfs_has_statfs'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 5942 "configure" #line 5993 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -5955,7 +6006,7 @@ int main() { ...@@ -5955,7 +6006,7 @@ int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:5959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:6010: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
wine_cv_sys_vfs_has_statfs=yes wine_cv_sys_vfs_has_statfs=yes
else else
...@@ -5982,12 +6033,12 @@ fi ...@@ -5982,12 +6033,12 @@ fi
if test "$ac_cv_header_sys_statfs_h" = "yes" if test "$ac_cv_header_sys_statfs_h" = "yes"
then then
echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6 echo $ac_n "checking "whether sys/statfs.h defines statfs"""... $ac_c" 1>&6
echo "configure:5986: checking "whether sys/statfs.h defines statfs"" >&5 echo "configure:6037: checking "whether sys/statfs.h defines statfs"" >&5
if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then if eval "test \"`echo '$''{'wine_cv_sys_statfs_has_statfs'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 5991 "configure" #line 6042 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -6002,7 +6053,7 @@ int main() { ...@@ -6002,7 +6053,7 @@ int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:6006: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:6057: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
wine_cv_sys_statfs_has_statfs=yes wine_cv_sys_statfs_has_statfs=yes
else else
...@@ -6029,12 +6080,12 @@ fi ...@@ -6029,12 +6080,12 @@ fi
if test "$ac_cv_header_sys_mount_h" = "yes" if test "$ac_cv_header_sys_mount_h" = "yes"
then then
echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6 echo $ac_n "checking "whether sys/mount.h defines statfs"""... $ac_c" 1>&6
echo "configure:6033: checking "whether sys/mount.h defines statfs"" >&5 echo "configure:6084: checking "whether sys/mount.h defines statfs"" >&5
if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then if eval "test \"`echo '$''{'wine_cv_sys_mount_has_statfs'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6038 "configure" #line 6089 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -6049,7 +6100,7 @@ int main() { ...@@ -6049,7 +6100,7 @@ int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:6053: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:6104: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
wine_cv_sys_mount_has_statfs=yes wine_cv_sys_mount_has_statfs=yes
else else
...@@ -6075,7 +6126,7 @@ fi ...@@ -6075,7 +6126,7 @@ fi
echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6 echo $ac_n "checking "for statfs.f_bfree"""... $ac_c" 1>&6
echo "configure:6079: checking "for statfs.f_bfree"" >&5 echo "configure:6130: checking "for statfs.f_bfree"" >&5
if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then if eval "test \"`echo '$''{'wine_cv_statfs_bfree'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -6084,7 +6135,7 @@ else ...@@ -6084,7 +6135,7 @@ else
wine_cv_statfs_bfree=no wine_cv_statfs_bfree=no
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6088 "configure" #line 6139 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -6111,7 +6162,7 @@ int main() { ...@@ -6111,7 +6162,7 @@ int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:6115: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:6166: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
wine_cv_statfs_bfree=yes wine_cv_statfs_bfree=yes
else else
...@@ -6135,7 +6186,7 @@ EOF ...@@ -6135,7 +6186,7 @@ EOF
fi fi
echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6 echo $ac_n "checking "for statfs.f_bavail"""... $ac_c" 1>&6
echo "configure:6139: checking "for statfs.f_bavail"" >&5 echo "configure:6190: checking "for statfs.f_bavail"" >&5
if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then if eval "test \"`echo '$''{'wine_cv_statfs_bavail'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
...@@ -6144,7 +6195,7 @@ else ...@@ -6144,7 +6195,7 @@ else
wine_cv_statfs_bavail=no wine_cv_statfs_bavail=no
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6148 "configure" #line 6199 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
...@@ -6171,7 +6222,7 @@ int main() { ...@@ -6171,7 +6222,7 @@ int main() {
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:6175: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:6226: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
wine_cv_statfs_bavail=yes wine_cv_statfs_bavail=yes
else else
...@@ -6196,12 +6247,12 @@ fi ...@@ -6196,12 +6247,12 @@ fi
echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6 echo $ac_n "checking "for msg_accrights in struct msghdr"""... $ac_c" 1>&6
echo "configure:6200: checking "for msg_accrights in struct msghdr"" >&5 echo "configure:6251: checking "for msg_accrights in struct msghdr"" >&5
if eval "test \"`echo '$''{'ac_cv_c_msg_accrights'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_c_msg_accrights'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6205 "configure" #line 6256 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
...@@ -6209,7 +6260,7 @@ int main() { ...@@ -6209,7 +6260,7 @@ int main() {
struct msghdr hdr; hdr.msg_accrights=0 struct msghdr hdr; hdr.msg_accrights=0
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:6213: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:6264: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_c_msg_accrights="yes" ac_cv_c_msg_accrights="yes"
else else
...@@ -6232,12 +6283,12 @@ fi ...@@ -6232,12 +6283,12 @@ fi
echo $ac_n "checking "for sun_len in struct sockaddr_un"""... $ac_c" 1>&6 echo $ac_n "checking "for sun_len in struct sockaddr_un"""... $ac_c" 1>&6
echo "configure:6236: checking "for sun_len in struct sockaddr_un"" >&5 echo "configure:6287: checking "for sun_len in struct sockaddr_un"" >&5
if eval "test \"`echo '$''{'ac_cv_c_sun_len'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_c_sun_len'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6241 "configure" #line 6292 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
...@@ -6246,7 +6297,7 @@ int main() { ...@@ -6246,7 +6297,7 @@ int main() {
static struct sockaddr_un addr; addr.sun_len = 1 static struct sockaddr_un addr; addr.sun_len = 1
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:6250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if { (eval echo configure:6301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest* rm -rf conftest*
ac_cv_c_sun_len="yes" ac_cv_c_sun_len="yes"
else else
...@@ -6269,12 +6320,12 @@ fi ...@@ -6269,12 +6320,12 @@ fi
echo $ac_n "checking "whether we need to define __i386__"""... $ac_c" 1>&6 echo $ac_n "checking "whether we need to define __i386__"""... $ac_c" 1>&6
echo "configure:6273: checking "whether we need to define __i386__"" >&5 echo "configure:6324: checking "whether we need to define __i386__"" >&5
if eval "test \"`echo '$''{'ac_cv_cpp_def_i386'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_cpp_def_i386'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6278 "configure" #line 6329 "configure"
#include "confdefs.h" #include "confdefs.h"
#if (defined(i386) || defined(__i386)) && !defined(__i386__) #if (defined(i386) || defined(__i386)) && !defined(__i386__)
yes yes
......
...@@ -786,6 +786,33 @@ AC_C_INLINE() ...@@ -786,6 +786,33 @@ AC_C_INLINE()
AC_TYPE_SIZE_T() AC_TYPE_SIZE_T()
AC_CHECK_SIZEOF(long long,0) AC_CHECK_SIZEOF(long long,0)
AC_CACHE_CHECK("whether we can use re-entrant gethostbyname_r Linux style",
wine_cv_linux_gethostbyname_r_6,
AC_TRY_COMPILE([
#include <netdb.h>
], [
char *name=NULL;
struct hostent he;
struct hostent *result;
char *buf=NULL;
int bufsize=0;
int res,errnr;
char *addr=NULL;
int addrlen=0;
int addrtype=0;
res=gethostbyname_r(name,&he,buf,bufsize,&result,&errnr);
res=gethostbyaddr_r(addr, addrlen, addrtype,&he,buf,bufsize,&result,&errnr);
],
wine_cv_linux_gethostbyname_r_6=yes,
wine_cv_linux_gethostbyname_r_6=no
)
)
if test "$wine_cv_linux_gethostbyname_r_6" = "yes"
then
AC_DEFINE(HAVE_LINUX_GETHOSTBYNAME_R_6)
fi
if test "$ac_cv_header_linux_joystick_h" = "yes" if test "$ac_cv_header_linux_joystick_h" = "yes"
then then
AC_CACHE_CHECK("whether linux/joystick.h uses the Linux 2.2+ API", AC_CACHE_CHECK("whether linux/joystick.h uses the Linux 2.2+ API",
......
...@@ -90,10 +90,14 @@ ...@@ -90,10 +90,14 @@
DEFAULT_DEBUG_CHANNEL(winsock); DEFAULT_DEBUG_CHANNEL(winsock);
/* critical section to protect some non-rentrant net function */
CRITICAL_SECTION csWSgetXXXbyYYY = CRITICAL_SECTION_INIT;
/* protoptypes of some functions in socket.c /* protoptypes of some functions in socket.c
*/ */
UINT16 wsaErrno(void); UINT16 wsaErrno(void);
UINT16 wsaHerrno(void); UINT16 wsaHerrno(int errnr);
#define AQ_WIN16 0x00 #define AQ_WIN16 0x00
#define AQ_WIN32 0x04 #define AQ_WIN32 0x04
...@@ -362,24 +366,49 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { ...@@ -362,24 +366,49 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) {
case AQ_GETHOST: { case AQ_GETHOST: {
struct hostent *he; struct hostent *he;
char *copy_hostent = targetptr; char *copy_hostent = targetptr;
#if HAVE_LINUX_GETHOSTBYNAME_R_6
char *extrabuf;
int ebufsize=1024;
struct hostent hostentry;
int locerr = ENOBUFS;
he = NULL;
extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
while(extrabuf) {
int res = (aq->flags & AQ_NAME) ?
gethostbyname_r(aq->host_name,
&hostentry, extrabuf, ebufsize, &he, &locerr):
gethostbyaddr_r(aq->host_addr,aq->host_len,aq->host_type,
&hostentry, extrabuf, ebufsize, &he, &locerr);
if( res != ERANGE) break;
ebufsize *=2;
extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
}
if (!he) fail = ((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
#else
EnterCriticalSection( &csWSgetXXXbyYYY );
he = (aq->flags & AQ_NAME) ? he = (aq->flags & AQ_NAME) ?
gethostbyname(aq->host_name): gethostbyname(aq->host_name):
gethostbyaddr(aq->host_addr,aq->host_len,aq->host_type); gethostbyaddr(aq->host_addr,aq->host_len,aq->host_type);
if (!he) fail = ((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
#endif
if (he) { if (he) {
size = WS_copy_he(copy_hostent,(char*)aq->sbuf,aq->sbuflen,he,aq->flags); size = WS_copy_he(copy_hostent,(char*)aq->sbuf,aq->sbuflen,he,aq->flags);
if (size < 0) { if (size < 0) {
fail = WSAENOBUFS; fail = WSAENOBUFS;
size = -size; size = -size;
} }
} else {
fail = ((h_errno < 0) ? wsaErrno() : wsaHerrno());
} }
#if HAVE_LINUX_GETHOSTBYNAME_R_6
HeapFree(GetProcessHeap(),0,extrabuf);
#else
LeaveCriticalSection( &csWSgetXXXbyYYY );
#endif
} }
break; break;
case AQ_GETPROTO: { case AQ_GETPROTO: {
struct protoent *pe; struct protoent *pe;
char *copy_protoent = targetptr; char *copy_protoent = targetptr;
EnterCriticalSection( &csWSgetXXXbyYYY );
pe = (aq->flags & AQ_NAME)? pe = (aq->flags & AQ_NAME)?
getprotobyname(aq->proto_name) : getprotobyname(aq->proto_name) :
getprotobynumber(aq->proto_number); getprotobynumber(aq->proto_number);
...@@ -390,19 +419,21 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { ...@@ -390,19 +419,21 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) {
size = -size; size = -size;
} }
} else { } else {
if (aq->flags & AQ_NAME) if (aq->flags & AQ_NAME)
MESSAGE("protocol %s not found; You might want to add " MESSAGE("protocol %s not found; You might want to add "
"this to /etc/protocols\n", debugstr_a(aq->proto_name) ); "this to /etc/protocols\n", debugstr_a(aq->proto_name) );
else else
MESSAGE("protocol number %d not found; You might want to add " MESSAGE("protocol number %d not found; You might want to add "
"this to /etc/protocols\n", aq->proto_number ); "this to /etc/protocols\n", aq->proto_number );
fail = WSANO_DATA; fail = WSANO_DATA;
} }
LeaveCriticalSection( &csWSgetXXXbyYYY );
} }
break; break;
case AQ_GETSERV: { case AQ_GETSERV: {
struct servent *se; struct servent *se;
char *copy_servent = targetptr; char *copy_servent = targetptr;
EnterCriticalSection( &csWSgetXXXbyYYY );
se = (aq->flags & AQ_NAME)? se = (aq->flags & AQ_NAME)?
getservbyname(aq->serv_name,aq->serv_proto) : getservbyname(aq->serv_name,aq->serv_proto) :
getservbyport(aq->serv_port,aq->serv_proto); getservbyport(aq->serv_port,aq->serv_proto);
...@@ -413,16 +444,17 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) { ...@@ -413,16 +444,17 @@ static DWORD WINAPI _async_queryfun(LPVOID arg) {
size = -size; size = -size;
} }
} else { } else {
if (aq->flags & AQ_NAME) if (aq->flags & AQ_NAME)
MESSAGE("service %s protocol %s not found; You might want to add " MESSAGE("service %s protocol %s not found; You might want to add "
"this to /etc/services\n", debugstr_a(aq->serv_name) , "this to /etc/services\n", debugstr_a(aq->serv_name) ,
aq->serv_proto ? debugstr_a(aq->serv_proto ):"*"); aq->serv_proto ? debugstr_a(aq->serv_proto ):"*");
else else
MESSAGE("service on port %d protocol %s not found; You might want to add " MESSAGE("service on port %d protocol %s not found; You might want to add "
"this to /etc/services\n", aq->serv_port, "this to /etc/services\n", aq->serv_port,
aq->serv_proto ? debugstr_a(aq->serv_proto ):"*"); aq->serv_proto ? debugstr_a(aq->serv_proto ):"*");
fail = WSANO_DATA; fail = WSANO_DATA;
} }
LeaveCriticalSection( &csWSgetXXXbyYYY );
} }
break; break;
} }
......
...@@ -92,6 +92,9 @@ ...@@ -92,6 +92,9 @@
DEFAULT_DEBUG_CHANNEL(winsock); DEFAULT_DEBUG_CHANNEL(winsock);
/* critical section to protect some non-rentrant net function */
extern CRITICAL_SECTION csWSgetXXXbyYYY;
#define DEBUG_SOCKADDR 0 #define DEBUG_SOCKADDR 0
#define dump_sockaddr(a) \ #define dump_sockaddr(a) \
DPRINTF("sockaddr_in: family %d, address %s, port %d\n", \ DPRINTF("sockaddr_in: family %d, address %s, port %d\n", \
...@@ -166,7 +169,7 @@ int WSAIOCTL_GetInterfaceCount(void); ...@@ -166,7 +169,7 @@ int WSAIOCTL_GetInterfaceCount(void);
int WSAIOCTL_GetInterfaceName(int intNumber, char *intName); int WSAIOCTL_GetInterfaceName(int intNumber, char *intName);
UINT16 wsaErrno(void); UINT16 wsaErrno(void);
UINT16 wsaHerrno(void); UINT16 wsaHerrno(int errnr);
static HANDLE _WSHeap = 0; static HANDLE _WSHeap = 0;
...@@ -2297,20 +2300,46 @@ static char* NULL_STRING = "NULL"; ...@@ -2297,20 +2300,46 @@ static char* NULL_STRING = "NULL";
*/ */
static WIN_hostent* __ws_gethostbyaddr(const char *addr, int len, int type, int dup_flag) static WIN_hostent* __ws_gethostbyaddr(const char *addr, int len, int type, int dup_flag)
{ {
WIN_hostent *retval = NULL;
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
if( pwsi ) if( pwsi )
{ {
struct hostent* host; struct hostent* host;
if( (host = gethostbyaddr(addr, len, type)) != NULL ) #if HAVE_LINUX_GETHOSTBYNAME_R_6
char *extrabuf;
int ebufsize=1024;
struct hostent hostentry;
int locerr=ENOBUFS;
host = NULL;
extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
while(extrabuf) {
int res = gethostbyaddr_r(addr, len, type,
&hostentry, extrabuf, ebufsize, &host, &locerr);
if( res != ERANGE) break;
ebufsize *=2;
extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
}
if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
#else
EnterCriticalSection( &csWSgetXXXbyYYY );
host = gethostbyaddr(addr, len, type);
if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
#endif
if( host != NULL )
{
if( WS_dup_he(pwsi, host, dup_flag) ) if( WS_dup_he(pwsi, host, dup_flag) )
return (WIN_hostent*)(pwsi->he); retval = (WIN_hostent*)(pwsi->he);
else else
SetLastError(WSAENOBUFS); SetLastError(WSAENOBUFS);
else }
SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno()); #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6
HeapFree(GetProcessHeap(),0,extrabuf);
#else
LeaveCriticalSection( &csWSgetXXXbyYYY );
#endif
} }
return NULL; return retval;
} }
SEGPTR WINAPI WINSOCK_gethostbyaddr16(const char *addr, INT16 len, INT16 type) SEGPTR WINAPI WINSOCK_gethostbyaddr16(const char *addr, INT16 len, INT16 type)
...@@ -2335,18 +2364,44 @@ WIN_hostent* WINAPI WSOCK32_gethostbyaddr(const char *addr, INT len, ...@@ -2335,18 +2364,44 @@ WIN_hostent* WINAPI WSOCK32_gethostbyaddr(const char *addr, INT len,
*/ */
static WIN_hostent * __ws_gethostbyname(const char *name, int dup_flag) static WIN_hostent * __ws_gethostbyname(const char *name, int dup_flag)
{ {
WIN_hostent *retval = NULL;
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
if( pwsi ) if( pwsi )
{ {
struct hostent* host; struct hostent* host;
if( (host = gethostbyname(name)) != NULL ) #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6
char *extrabuf;
int ebufsize=1024;
struct hostent hostentry;
int locerr = ENOBUFS;
host = NULL;
extrabuf=HeapAlloc(GetProcessHeap(),0,ebufsize) ;
while(extrabuf) {
int res = gethostbyname_r(name, &hostentry, extrabuf, ebufsize, &host, &locerr);
if( res != ERANGE) break;
ebufsize *=2;
extrabuf=HeapReAlloc(GetProcessHeap(),0,extrabuf,ebufsize) ;
}
if (!host) SetLastError((locerr < 0) ? wsaErrno() : wsaHerrno(locerr));
#else
EnterCriticalSection( &csWSgetXXXbyYYY );
host = gethostbyname(name);
if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno));
#endif
if( host != NULL )
{
if( WS_dup_he(pwsi, host, dup_flag) ) if( WS_dup_he(pwsi, host, dup_flag) )
return (WIN_hostent*)(pwsi->he); retval = (WIN_hostent*)(pwsi->he);
else SetLastError(WSAENOBUFS); else SetLastError(WSAENOBUFS);
else SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno()); }
#ifdef HAVE_LINUX_GETHOSTBYNAME_R_6
HeapFree(GetProcessHeap(),0,extrabuf);
#else
LeaveCriticalSection( &csWSgetXXXbyYYY );
#endif
} }
return NULL; return retval;
} }
SEGPTR WINAPI WINSOCK_gethostbyname16(const char *name) SEGPTR WINAPI WINSOCK_gethostbyname16(const char *name)
...@@ -2369,22 +2424,27 @@ WIN_hostent* WINAPI WSOCK32_gethostbyname(const char* name) ...@@ -2369,22 +2424,27 @@ WIN_hostent* WINAPI WSOCK32_gethostbyname(const char* name)
*/ */
static WIN_protoent* __ws_getprotobyname(const char *name, int dup_flag) static WIN_protoent* __ws_getprotobyname(const char *name, int dup_flag)
{ {
WIN_protoent* retval = NULL;
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
if( pwsi ) if( pwsi )
{ {
struct protoent* proto; struct protoent* proto;
EnterCriticalSection( &csWSgetXXXbyYYY );
if( (proto = getprotobyname(name)) != NULL ) if( (proto = getprotobyname(name)) != NULL )
{
if( WS_dup_pe(pwsi, proto, dup_flag) ) if( WS_dup_pe(pwsi, proto, dup_flag) )
return (WIN_protoent*)(pwsi->pe); retval = (WIN_protoent*)(pwsi->pe);
else SetLastError(WSAENOBUFS); else SetLastError(WSAENOBUFS);
}
else { else {
MESSAGE("protocol %s not found; You might want to add " MESSAGE("protocol %s not found; You might want to add "
"this to /etc/protocols\n", debugstr_a(name) ); "this to /etc/protocols\n", debugstr_a(name) );
SetLastError(WSANO_DATA); SetLastError(WSANO_DATA);
} }
LeaveCriticalSection( &csWSgetXXXbyYYY );
} else SetLastError(WSANOTINITIALISED); } else SetLastError(WSANOTINITIALISED);
return NULL; return retval;
} }
SEGPTR WINAPI WINSOCK_getprotobyname16(const char *name) SEGPTR WINAPI WINSOCK_getprotobyname16(const char *name)
...@@ -2407,22 +2467,27 @@ WIN_protoent* WINAPI WSOCK32_getprotobyname(const char* name) ...@@ -2407,22 +2467,27 @@ WIN_protoent* WINAPI WSOCK32_getprotobyname(const char* name)
*/ */
static WIN_protoent* __ws_getprotobynumber(int number, int dup_flag) static WIN_protoent* __ws_getprotobynumber(int number, int dup_flag)
{ {
WIN_protoent* retval = NULL;
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
if( pwsi ) if( pwsi )
{ {
struct protoent* proto; struct protoent* proto;
EnterCriticalSection( &csWSgetXXXbyYYY );
if( (proto = getprotobynumber(number)) != NULL ) if( (proto = getprotobynumber(number)) != NULL )
{
if( WS_dup_pe(pwsi, proto, dup_flag) ) if( WS_dup_pe(pwsi, proto, dup_flag) )
return (WIN_protoent*)(pwsi->pe); retval = (WIN_protoent*)(pwsi->pe);
else SetLastError(WSAENOBUFS); else SetLastError(WSAENOBUFS);
}
else { else {
MESSAGE("protocol number %d not found; You might want to add " MESSAGE("protocol number %d not found; You might want to add "
"this to /etc/protocols\n", number ); "this to /etc/protocols\n", number );
SetLastError(WSANO_DATA); SetLastError(WSANO_DATA);
} }
LeaveCriticalSection( &csWSgetXXXbyYYY );
} else SetLastError(WSANOTINITIALISED); } else SetLastError(WSANOTINITIALISED);
return NULL; return retval;
} }
SEGPTR WINAPI WINSOCK_getprotobynumber16(INT16 number) SEGPTR WINAPI WINSOCK_getprotobynumber16(INT16 number)
...@@ -2445,6 +2510,7 @@ WIN_protoent* WINAPI WSOCK32_getprotobynumber(INT number) ...@@ -2445,6 +2510,7 @@ WIN_protoent* WINAPI WSOCK32_getprotobynumber(INT number)
*/ */
static WIN_servent* __ws_getservbyname(const char *name, const char *proto, int dup_flag) static WIN_servent* __ws_getservbyname(const char *name, const char *proto, int dup_flag)
{ {
WIN_servent* retval = NULL;
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
if( pwsi ) if( pwsi )
...@@ -2453,22 +2519,26 @@ static WIN_servent* __ws_getservbyname(const char *name, const char *proto, int ...@@ -2453,22 +2519,26 @@ static WIN_servent* __ws_getservbyname(const char *name, const char *proto, int
int i = wsi_strtolo( pwsi, name, proto ); int i = wsi_strtolo( pwsi, name, proto );
if( i ) { if( i ) {
EnterCriticalSection( &csWSgetXXXbyYYY );
serv = getservbyname(pwsi->buffer, serv = getservbyname(pwsi->buffer,
proto ? (pwsi->buffer + i) : NULL); proto ? (pwsi->buffer + i) : NULL);
if( serv != NULL ) if( serv != NULL )
{
if( WS_dup_se(pwsi, serv, dup_flag) ) if( WS_dup_se(pwsi, serv, dup_flag) )
return (WIN_servent*)(pwsi->se); retval = (WIN_servent*)(pwsi->se);
else SetLastError(WSAENOBUFS); else SetLastError(WSAENOBUFS);
}
else { else {
MESSAGE("service %s protocol %s not found; You might want to add " MESSAGE("service %s protocol %s not found; You might want to add "
"this to /etc/services\n", debugstr_a(pwsi->buffer), "this to /etc/services\n", debugstr_a(pwsi->buffer),
proto ? debugstr_a(pwsi->buffer+i):"*"); proto ? debugstr_a(pwsi->buffer+i):"*");
SetLastError(WSANO_DATA); SetLastError(WSANO_DATA);
} }
LeaveCriticalSection( &csWSgetXXXbyYYY );
} }
else SetLastError(WSAENOBUFS); else SetLastError(WSAENOBUFS);
} else SetLastError(WSANOTINITIALISED); } else SetLastError(WSANOTINITIALISED);
return NULL; return retval;
} }
SEGPTR WINAPI WINSOCK_getservbyname16(const char *name, const char *proto) SEGPTR WINAPI WINSOCK_getservbyname16(const char *name, const char *proto)
...@@ -2493,15 +2563,17 @@ WIN_servent* WINAPI WSOCK32_getservbyname(const char *name, const char *proto) ...@@ -2493,15 +2563,17 @@ WIN_servent* WINAPI WSOCK32_getservbyname(const char *name, const char *proto)
*/ */
static WIN_servent* __ws_getservbyport(int port, const char* proto, int dup_flag) static WIN_servent* __ws_getservbyport(int port, const char* proto, int dup_flag)
{ {
WIN_servent* retval = NULL;
LPWSINFO pwsi = WINSOCK_GetIData(); LPWSINFO pwsi = WINSOCK_GetIData();
if( pwsi ) if( pwsi )
{ {
struct servent* serv; struct servent* serv;
if (!proto || wsi_strtolo( pwsi, proto, NULL )) { if (!proto || wsi_strtolo( pwsi, proto, NULL )) {
EnterCriticalSection( &csWSgetXXXbyYYY );
if( (serv = getservbyport(port, (proto) ? pwsi->buffer : NULL)) != NULL ) { if( (serv = getservbyport(port, (proto) ? pwsi->buffer : NULL)) != NULL ) {
if( WS_dup_se(pwsi, serv, dup_flag) ) if( WS_dup_se(pwsi, serv, dup_flag) )
return (WIN_servent*)(pwsi->se); retval = (WIN_servent*)(pwsi->se);
else SetLastError(WSAENOBUFS); else SetLastError(WSAENOBUFS);
} }
else { else {
...@@ -2510,10 +2582,11 @@ static WIN_servent* __ws_getservbyport(int port, const char* proto, int dup_flag ...@@ -2510,10 +2582,11 @@ static WIN_servent* __ws_getservbyport(int port, const char* proto, int dup_flag
proto ? debugstr_a(pwsi->buffer) : "*"); proto ? debugstr_a(pwsi->buffer) : "*");
SetLastError(WSANO_DATA); SetLastError(WSANO_DATA);
} }
LeaveCriticalSection( &csWSgetXXXbyYYY );
} }
else SetLastError(WSAENOBUFS); else SetLastError(WSAENOBUFS);
} else SetLastError(WSANOTINITIALISED); } else SetLastError(WSANOTINITIALISED);
return NULL; return retval;
} }
SEGPTR WINAPI WINSOCK_getservbyport16(INT16 port, const char *proto) SEGPTR WINAPI WINSOCK_getservbyport16(INT16 port, const char *proto)
...@@ -3231,9 +3304,8 @@ UINT16 wsaErrno(void) ...@@ -3231,9 +3304,8 @@ UINT16 wsaErrno(void)
} }
} }
UINT16 wsaHerrno(void) UINT16 wsaHerrno(int loc_errno)
{ {
int loc_errno = h_errno;
WARN("h_errno %d.\n", loc_errno); WARN("h_errno %d.\n", loc_errno);
...@@ -3243,6 +3315,7 @@ UINT16 wsaHerrno(void) ...@@ -3243,6 +3315,7 @@ UINT16 wsaHerrno(void)
case TRY_AGAIN: return WSATRY_AGAIN; case TRY_AGAIN: return WSATRY_AGAIN;
case NO_RECOVERY: return WSANO_RECOVERY; case NO_RECOVERY: return WSANO_RECOVERY;
case NO_DATA: return WSANO_DATA; case NO_DATA: return WSANO_DATA;
case ENOBUFS: return WSAENOBUFS;
case 0: return 0; case 0: return 0;
default: default:
......
...@@ -116,3 +116,6 @@ ...@@ -116,3 +116,6 @@
/* Define if the X libraries support XVideo */ /* Define if the X libraries support XVideo */
#undef HAVE_XVIDEO #undef HAVE_XVIDEO
/* Define if Linux-style gethostbyname_r and gethostbyaddr_r are available */
#undef HAVE_LINUX_GETHOSTBYNAME_R_6
...@@ -152,6 +152,9 @@ ...@@ -152,6 +152,9 @@
/* Define if the X libraries support XVideo */ /* Define if the X libraries support XVideo */
#undef HAVE_XVIDEO #undef HAVE_XVIDEO
/* Define if Linux-style gethostbyname_r and gethostbyaddr_r are available */
#undef HAVE_LINUX_GETHOSTBYNAME_R_6
/* The number of bytes in a long long. */ /* The number of bytes in a long long. */
#undef SIZEOF_LONG_LONG #undef SIZEOF_LONG_LONG
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment