mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-31 00:55:06 +08:00
3610e0d548
2001-05-23 Tom Tromey <tromey@redhat.com> * posix-threads.cc (_Jv_self_cache): Renamed from self_cache. * gcj/Makefile.in: Rebuilt. * gcj/Makefile.am (gcj_HEADERS): Added libgcj-config.h. * gcj/javaprims.h: Include gcj/libgcj-config.h. * gcj/libgcj-config.h.in: New file. * libgcj.spec.in (*jc1): Added @HASH_SYNC_SPEC@. * configure: Rebuilt. * configure.in: Enable hash synchronization by default on some platforms. (HASH_SYNC_SPEC): New subst. (AC_CONFIG_HEADER): Added gcj/libgcj-config.h. Correctly use `test -z' instead of `test -n' in a couple places. (JV_HASH_SYNCHRONIZATION): Use AC_DEFINE; don't add to LIBGCJ_CXXFLAGS. * configure.host (enable_java_net_default): Initialize. (enable_hash_synchronization_default): New variable. 2001-05-23 Hans Boehm <Hans_Boehm@hp.com> * boehm.cc (_Jv_MarkObj): Don't mark sync_info when hash synchronization in use. (_Jv_MarkArray): Likewise. (_Jv_AllocBytes): Don't check return result. (handle_out_of_memory): New function. (_Jv_InitGC): Set GC_oom_fn. (trace_one_vtable): New global. (_Jv_AllocTraceOne): New function. * configure.in: Added --enable-hash-synchronization. * defineclass.cc, prims.cc, resolve.cc, java/lang/natString.cc, java/net/natInetAddress.cc: Remove _Jv_AllocBytesChecked. * nogc.cc (_Jv_AllocObj): Throw out-of-memory. (_Jv_AllocArray): Likewise. (_Jv_AllocBytes): Likewise. (_Jv_AllocPtrFreeObject): New function. (_Jv_AllocTraceOne): Likewise. * posix-threads.cc (_Jv_ThreadRegister): Handle slow pthread_self(). (self_cache): New global. (_Jv_ThreadSelf_out_of_line): New function. * prims.cc (_Jv_AllocBytesChecked): Removed. (_Jv_ThrowNoMemory): New function. (_Jv_AllocObject): Don't check for null return from allocator. (_Jv_NewObjectArray): Likewise. (_Jv_AllocPtrFreeObject): New function. (_Jv_NewPrimArray): Allocate pointer-free object if possible. * include/javaprims.h (_Jv_AllocPtrFreeObject): Declare. (_Jv_MonitorEnter, _Jv_MonitorExit): Don't return value. * include/boehm-gc.h (_Jv_AllocObj): Define. (_Jv_AllocPtrFreeObj): Define. * include/jvm.h (_Jv_AllocPtrFreeObj): Declare. (_Jv_ThrowNoMemory): Declare. (_Jv_AllocTraceOne): Declare. (_Jv_AllocBytesChecked): Removed. * include/posix-threads.h (_Jv_MutexInit, _Jv_MutexLock, _Jv_MutexUnlock): Handle LOCK_DEBUG. (_Jv_ThreadSelf): Handle case where system pthread_self() is slow. * java/lang/Class.h (Class): Declare _Jv_AllocPtrFreeObj as friend. * java/lang/Object.h (sync_info): Conditional upon presence of hash synchronization. * java/lang/natObject.cc: Much new code to handle thin locks and hash synchronization. * java/lang/natString.cc (_Jv_AllocString): Allocate pointer-free object if possible. From-SVN: r42519
357 lines
8.0 KiB
C++
357 lines
8.0 KiB
C++
// natInetAddress.cc
|
|
|
|
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
|
|
|
|
This file is part of libgcj.
|
|
|
|
This software is copyrighted work licensed under the terms of the
|
|
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|
details. */
|
|
|
|
#include <config.h>
|
|
|
|
#ifdef USE_WINSOCK
|
|
|
|
#include <windows.h>
|
|
#include <winsock.h>
|
|
|
|
#ifndef MAXHOSTNAMELEN
|
|
#define MAXHOSTNAMELEN 64
|
|
#endif /* MAXHOSTNAMELEN */
|
|
|
|
#else
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
#include <sys/socket.h>
|
|
#endif
|
|
#ifdef HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif
|
|
#ifdef HAVE_ARPA_INET_H
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
#ifdef HAVE_NETDB_H
|
|
#include <netdb.h>
|
|
#endif
|
|
|
|
#endif /* USE_WINSOCK */
|
|
|
|
#include <gcj/cni.h>
|
|
#include <jvm.h>
|
|
#include <java/net/InetAddress.h>
|
|
#include <java/net/UnknownHostException.h>
|
|
#include <java/lang/SecurityException.h>
|
|
|
|
#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
|
|
#include <sys/utsname.h>
|
|
#endif
|
|
|
|
#ifndef HAVE_GETHOSTNAME_DECL
|
|
extern "C" int gethostname (char *name, int namelen);
|
|
#endif
|
|
|
|
#ifdef DISABLE_JAVA_NET
|
|
|
|
jbyteArray
|
|
java::net::InetAddress::aton (jstring)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
jint
|
|
java::net::InetAddress::getFamily (jbyteArray bytes)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
JArray<java::net::InetAddress*> *
|
|
java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
jstring
|
|
java::net::InetAddress::getLocalHostname ()
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
#else /* DISABLE_JAVA_NET */
|
|
|
|
jbyteArray
|
|
java::net::InetAddress::aton (jstring host)
|
|
{
|
|
char *hostname;
|
|
char buf[100];
|
|
int len = JvGetStringUTFLength(host);
|
|
if (len < 100)
|
|
hostname = buf;
|
|
else
|
|
hostname = (char*) _Jv_AllocBytes (len+1);
|
|
JvGetStringUTFRegion (host, 0, host->length(), hostname);
|
|
buf[len] = '\0';
|
|
char* bytes = NULL;
|
|
int blen = 0;
|
|
#ifdef HAVE_INET_ATON
|
|
struct in_addr laddr;
|
|
if (inet_aton (hostname, &laddr))
|
|
{
|
|
bytes = (char*) &laddr;
|
|
blen = 4;
|
|
}
|
|
#elif defined(HAVE_INET_ADDR)
|
|
#if ! HAVE_IN_ADDR_T
|
|
typedef jint in_addr_t;
|
|
#endif
|
|
in_addr_t laddr = inet_addr (hostname);
|
|
if (laddr != (in_addr_t)(-1))
|
|
{
|
|
bytes = (char*) &laddr;
|
|
blen = 4;
|
|
}
|
|
#endif
|
|
#if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
|
|
char inet6_addr[16];
|
|
if (len == 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
|
|
{
|
|
bytes = inet6_addr;
|
|
blen = 16;
|
|
}
|
|
#endif
|
|
if (blen == 0)
|
|
return NULL;
|
|
jbyteArray result = JvNewByteArray (blen);
|
|
memcpy (elements (result), bytes, blen);
|
|
return result;
|
|
}
|
|
|
|
jint
|
|
java::net::InetAddress::getFamily (jbyteArray bytes)
|
|
{
|
|
int len = bytes->length;
|
|
if (len == 4)
|
|
return AF_INET;
|
|
#ifdef HAVE_INET6
|
|
else if (len == 16)
|
|
return AF_INET6;
|
|
#endif /* HAVE_INET6 */
|
|
else
|
|
JvFail ("unrecognized size");
|
|
}
|
|
|
|
|
|
JArray<java::net::InetAddress*> *
|
|
java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
|
|
jboolean all)
|
|
{
|
|
struct hostent *hptr = NULL;
|
|
#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
|
|
struct hostent hent_r;
|
|
#if HAVE_STRUCT_HOSTENT_DATA
|
|
struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
|
|
#else
|
|
#if defined (__GLIBC__)
|
|
// FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
|
|
// ERANGE to errno if the buffer size is too small, rather than what is
|
|
// expected here. We work around this by setting a bigger buffer size and
|
|
// hoping that it is big enough.
|
|
char fixed_buffer[1024];
|
|
#else
|
|
char fixed_buffer[200];
|
|
#endif
|
|
char *buffer_r = fixed_buffer;
|
|
int size_r = sizeof (fixed_buffer);
|
|
#endif
|
|
#endif
|
|
|
|
if (host != NULL)
|
|
{
|
|
char *hostname;
|
|
char buf[100];
|
|
int len = JvGetStringUTFLength(host);
|
|
if (len < 100)
|
|
hostname = buf;
|
|
else
|
|
hostname = (char*) _Jv_AllocBytes (len+1);
|
|
JvGetStringUTFRegion (host, 0, host->length(), hostname);
|
|
buf[len] = '\0';
|
|
#ifdef HAVE_GETHOSTBYNAME_R
|
|
while (true)
|
|
{
|
|
int ok;
|
|
#if HAVE_STRUCT_HOSTENT_DATA
|
|
ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
|
|
#else
|
|
int herr = 0;
|
|
#ifdef GETHOSTBYNAME_R_RETURNS_INT
|
|
ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
|
|
&hptr, &herr);
|
|
#else
|
|
hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
|
|
ok = hptr != NULL;
|
|
#endif /* GETHOSTNAME_R_RETURNS_INT */
|
|
if (! ok && herr == ERANGE)
|
|
{
|
|
size_r *= 2;
|
|
buffer_r = (char *) _Jv_AllocBytes (size_r);
|
|
}
|
|
else
|
|
#endif /* HAVE_STRUCT_HOSTENT_DATA */
|
|
break;
|
|
}
|
|
#else
|
|
// FIXME: this is insufficient if some other piece of code calls
|
|
// this gethostbyname.
|
|
JvSynchronize sync (java::net::InetAddress::localhostAddress);
|
|
hptr = gethostbyname (hostname);
|
|
#endif /* HAVE_GETHOSTBYNAME_R */
|
|
}
|
|
else
|
|
{
|
|
jbyteArray bytes = iaddr->addr;
|
|
char *chars = (char*) elements (bytes);
|
|
int len = bytes->length;
|
|
int type;
|
|
char *val;
|
|
if (len == 4)
|
|
{
|
|
val = chars;
|
|
type = iaddr->family = AF_INET;
|
|
}
|
|
#ifdef HAVE_INET6
|
|
else if (len == 16)
|
|
{
|
|
val = (char *) &chars;
|
|
type = iaddr->family = AF_INET6;
|
|
}
|
|
#endif /* HAVE_INET6 */
|
|
else
|
|
JvFail ("unrecognized size");
|
|
|
|
#ifdef HAVE_GETHOSTBYADDR_R
|
|
while (true)
|
|
{
|
|
int ok;
|
|
#if HAVE_STRUCT_HOSTENT_DATA
|
|
ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
|
|
#else
|
|
int herr = 0;
|
|
#ifdef GETHOSTBYADDR_R_RETURNS_INT
|
|
ok = ! gethostbyaddr_r (val, len, type, &hent_r,
|
|
buffer_r, size_r, &hptr, &herr);
|
|
#else
|
|
hptr = gethostbyaddr_r (val, len, type, &hent_r,
|
|
buffer_r, size_r, &herr);
|
|
ok = hptr != NULL;
|
|
#endif /* GETHOSTBYADDR_R_RETURNS_INT */
|
|
if (! ok && herr == ERANGE)
|
|
{
|
|
size_r *= 2;
|
|
buffer_r = (char *) _Jv_AllocBytes (size_r);
|
|
}
|
|
else
|
|
#endif /* HAVE_STRUCT_HOSTENT_DATA */
|
|
break;
|
|
}
|
|
#else /* HAVE_GETHOSTBYADDR_R */
|
|
// FIXME: this is insufficient if some other piece of code calls
|
|
// this gethostbyaddr.
|
|
JvSynchronize sync (java::net::InetAddress::localhostAddress);
|
|
hptr = gethostbyaddr (val, len, type);
|
|
#endif /* HAVE_GETHOSTBYADDR_R */
|
|
}
|
|
if (hptr != NULL)
|
|
{
|
|
if (!all)
|
|
host = JvNewStringUTF (hptr->h_name);
|
|
java::lang::SecurityException *ex = checkConnect (host);
|
|
if (ex != NULL)
|
|
{
|
|
if (iaddr == NULL || iaddr->addr == NULL)
|
|
throw ex;
|
|
hptr = NULL;
|
|
}
|
|
}
|
|
if (hptr == NULL)
|
|
{
|
|
if (iaddr != NULL && iaddr->addr != NULL)
|
|
{
|
|
iaddr->hostName = iaddr->getHostAddress();
|
|
return NULL;
|
|
}
|
|
else
|
|
throw new java::net::UnknownHostException(host);
|
|
}
|
|
int count;
|
|
if (all)
|
|
{
|
|
char** ptr = hptr->h_addr_list;
|
|
count = 0;
|
|
while (*ptr++) count++;
|
|
}
|
|
else
|
|
count = 1;
|
|
JArray<java::net::InetAddress*> *result;
|
|
java::net::InetAddress** iaddrs;
|
|
if (all)
|
|
{
|
|
result = java::net::InetAddress::allocArray (count);
|
|
iaddrs = elements (result);
|
|
}
|
|
else
|
|
{
|
|
result = NULL;
|
|
iaddrs = &iaddr;
|
|
}
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
if (iaddrs[i] == NULL)
|
|
iaddrs[i] = new java::net::InetAddress (NULL, NULL);
|
|
if (iaddrs[i]->hostName == NULL)
|
|
iaddrs[i]->hostName = host;
|
|
if (iaddrs[i]->addr == NULL)
|
|
{
|
|
char *bytes = hptr->h_addr_list[i];
|
|
iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
|
|
iaddrs[i]->family = getFamily (iaddrs[i]->addr);
|
|
memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
jstring
|
|
java::net::InetAddress::getLocalHostname ()
|
|
{
|
|
char *chars;
|
|
#ifdef HAVE_GETHOSTNAME
|
|
char buffer[MAXHOSTNAMELEN];
|
|
if (gethostname (buffer, MAXHOSTNAMELEN))
|
|
return NULL;
|
|
chars = buffer;
|
|
#elif HAVE_UNAME
|
|
struct utsname stuff;
|
|
if (uname (&stuff) != 0)
|
|
return NULL;
|
|
chars = stuff.nodename;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
// It is admittedly non-optimal to convert the hostname to Unicode
|
|
// only to convert it back in getByName, but simplicity wins. Note
|
|
// that unless there is a SecurityManager, we only get called once
|
|
// anyway, thanks to the InetAddress.localhost cache.
|
|
return JvNewStringUTF (chars);
|
|
}
|
|
|
|
#endif /* DISABLE_JAVA_NET */
|