diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-05-01 21:45:41 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-05-01 21:45:41 +0000 |
commit | 480ccb4bfcc622c1ce320c20ce992188187f7573 (patch) | |
tree | aebfd0e230d0370ec1ac1a9b1a99b478abdc6854 /native | |
parent | 4d80ae24073737202d4c51bf9efd2466fea8696d (diff) | |
download | classpath-480ccb4bfcc622c1ce320c20ce992188187f7573.tar.gz |
2006-05-01 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge HEAD-->generics-branch for the period
2006-04-13 to 2006-05-01.
Diffstat (limited to 'native')
-rw-r--r-- | native/fdlibm/Makefile.am | 2 | ||||
-rw-r--r-- | native/fdlibm/ieeefp.h | 2 | ||||
-rw-r--r-- | native/jni/classpath/Makefile.am | 2 | ||||
-rw-r--r-- | native/jni/java-lang/java_lang_VMProcess.c | 3 | ||||
-rw-r--r-- | native/jni/java-net/Makefile.am | 11 | ||||
-rw-r--r-- | native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c | 538 | ||||
-rw-r--r-- | native/jni/java-net/local.c | 193 | ||||
-rw-r--r-- | native/jni/java-net/local.h | 28 |
8 files changed, 774 insertions, 5 deletions
diff --git a/native/fdlibm/Makefile.am b/native/fdlibm/Makefile.am index 64b3b3936..09d868106 100644 --- a/native/fdlibm/Makefile.am +++ b/native/fdlibm/Makefile.am @@ -58,7 +58,7 @@ libfdlibm_la_SOURCES = \ w_sqrt.c \ namespace.h -AM_LDFLAGS = @CLASSPATH_MODULE@ +AM_LDFLAGS = @CLASSPATH_CONVENIENCE@ # We just want the standard flags for fdlibm since it is an upstream lib # and our normal -pedantic -Wall -Werror breaks this lib. So no AM_CFLAGS. diff --git a/native/fdlibm/ieeefp.h b/native/fdlibm/ieeefp.h index 1dda99b32..1a9740f66 100644 --- a/native/fdlibm/ieeefp.h +++ b/native/fdlibm/ieeefp.h @@ -123,7 +123,7 @@ #define __IEEE_LITTLE_ENDIAN #endif -#if defined (__PPC__) || defined (__ppc__) || defined (__powerpc__) || defined (__ppc64__) +#if defined (__PPC__) || defined (__ppc__) || defined (__powerpc__) || defined (__ppc64__) || defined (_POWER) || defined (_IBMR2) #if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX) || defined (__BIG_ENDIAN__)|| defined (__APPLE__) #define __IEEE_BIG_ENDIAN #else diff --git a/native/jni/classpath/Makefile.am b/native/jni/classpath/Makefile.am index a26ab832b..d996df636 100644 --- a/native/jni/classpath/Makefile.am +++ b/native/jni/classpath/Makefile.am @@ -7,6 +7,6 @@ libclasspath_la_SOURCES = jcl.c jcl.h \ jnilink.c jnilink.h \ native_state.c native_state.h -AM_LDFLAGS = @CLASSPATH_MODULE@ +AM_LDFLAGS = @CLASSPATH_CONVENIENCE@ AM_CPPFLAGS = @CLASSPATH_INCLUDES@ AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@ diff --git a/native/jni/java-lang/java_lang_VMProcess.c b/native/jni/java-lang/java_lang_VMProcess.c index af14edaa8..f13a94f18 100644 --- a/native/jni/java-lang/java_lang_VMProcess.c +++ b/native/jni/java-lang/java_lang_VMProcess.c @@ -263,7 +263,7 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, } close (fds[1][1]); } - if (pipe_count == 3) + if (pipe_count == 2) { /* Duplicate stdout to stderr. */ if (dup2 (1, 2) == -1) @@ -315,6 +315,7 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, goto done; for (i = 0; i < pipe_count; i++) { + /* Mode is WRITE (2) for in and READ (1) for out and err. */ const int fd = fds[i][i == 0]; const int mode = ((i == 0) ? gnu_java_nio_channels_FileChannelImpl_WRITE diff --git a/native/jni/java-net/Makefile.am b/native/jni/java-net/Makefile.am index 5ad257f5a..e48173a16 100644 --- a/native/jni/java-net/Makefile.am +++ b/native/jni/java-net/Makefile.am @@ -1,11 +1,20 @@ nativeexeclib_LTLIBRARIES = libjavanet.la +if ENABLE_LOCAL_SOCKETS +local_sources = gnu_java_net_local_LocalSocketImpl.c \ + local.c \ + local.h +else +local_sources = gnu_java_net_local_LocalSocketImpl.c +endif + libjavanet_la_SOURCES = javanet.c \ javanet.h \ java_net_VMInetAddress.c \ java_net_VMNetworkInterface.c \ gnu_java_net_VMPlainDatagramSocketImpl.c \ - gnu_java_net_VMPlainSocketImpl.c + gnu_java_net_VMPlainSocketImpl.c \ + $(local_sources) libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo diff --git a/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c b/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c new file mode 100644 index 000000000..3b29001a7 --- /dev/null +++ b/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c @@ -0,0 +1,538 @@ +/* gnu_java_net_local_LocalSocketImpl.c -- native local socket implementation. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <gnu_java_net_local_LocalSocketImpl.h> + +#include <stddef.h> +#include "local.h" + +#ifdef DEBUG +#define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg) +#else +#define TRACE(msg) +#endif + +static void +_throw (JNIEnv *env, const char *exception, const char *msg) +{ + jclass _theclass = (*env)->FindClass (env, exception); + TRACE("begin"); + if (!_theclass) + { + (*env)->FatalError (env, "exception class not found"); + } + (*env)->ThrowNew (env, _theclass, msg); + TRACE("end"); +} + +void +Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv *env, jobject this, jboolean stream) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd, created; + jclass clazz; + jint fd = (jint) local_create ((int) stream); + + TRACE("begin"); + + if (fd < 0) + { + _throw (env, "java/io/IOException", local_error ()); + return; + } + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + created = (*env)->GetFieldID (env, clazz, "created", "Z"); + if (!created) + { + return; + } + (*env)->SetIntField (env, this, socket_fd, fd); + (*env)->SetBooleanField (env, this, created, JNI_TRUE); + + TRACE("end"); +#else + (void) this; + (void) stream; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv *env, jobject this, jint backlog) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + if (local_listen (fd, (int) backlog)) + { + _throw (env, "java/io/IOException", local_error ()); + return; + } + + TRACE("end"); +#else + (void) this; + (void) backlog; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv *env, jobject this, jobject socket) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jmethodID addr_init; + jfieldID socket_fd, remote_addr, local_addr; + jclass clazz1, clazz2; + jobject remote, local; + jint fd; + char path[108]; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (*env)->GetIntField (env, this, socket_fd); + fd = (jint) local_accept ((int) fd, path); + if (fd < 0) + { + _throw (env, "java/io/IOException", local_error ()); + return; + } + + clazz2 = (*env)->FindClass (env, "gnu/java/net/local/LocalSocketAddress"); + if (!clazz2) + { + return; + } + addr_init = (*env)->GetMethodID (env, clazz2, "<init>", "(Ljava/lang/String;)V"); + if (!addr_init) + { + return; + } + remote = (*env)->NewObject (env, clazz2, addr_init, (*env)->NewStringUTF (env, path)); + + remote_addr = (*env)->GetFieldID (env, clazz1, "remote", "Lgnu/java/net/local/LocalSocketAddress;"); + if (!remote_addr) + { + return; + } + local_addr = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;"); + if (!local_addr) + { + return; + } + local = (*env)->GetObjectField (env, this, local_addr); + (*env)->SetIntField (env, socket, socket_fd, fd); + (*env)->SetObjectField (env, socket, remote_addr, remote); + (*env)->SetObjectField (env, socket, local_addr, local); + + TRACE("end"); +#else + (void) this; + (void) socket; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +jint +Java_gnu_java_net_local_LocalSocketImpl_available (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + jint avail; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return 0; + } + avail = (jint) local_available ((int) (*env)->GetIntField (env, this, socket_fd)); + if (avail < 0) + { + _throw (env, "java/io/IOException", local_error ()); + return 0; + } + + TRACE("end"); + + return avail; +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); + return -1; +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + if (local_close (fd)) + { + _throw (env, "java/io/IOException", local_error ()); + } + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID local; + jmethodID get_path; + jclass clazz1, clazz2; + jobject local_ref, path; + char *addr_path; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + local = (*env)->GetFieldID (env, clazz1, "local", "Lgnu/java/net/local/LocalSocketAddress;"); + if (!local) + { + return; + } + local_ref = (*env)->GetObjectField (env, this, local); + clazz2 = (*env)->GetObjectClass (env, local_ref); + get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;"); + if (!get_path) + { + return; + } + path = (*env)->CallObjectMethod (env, local_ref, get_path); + addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL); + if (local_unlink (addr_path)) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path); + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_sendUrgentData (JNIEnv *env, jobject this __attribute__((unused)), jint data __attribute__((unused))) +{ + /* XXX I don't remember why I have this. Probably should just + remove. */ + (*env)->FatalError (env, "Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject) not implemented"); +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (*env)->GetIntField (env, this, socket_fd); + if (local_shutdown_input (fd)) + { + _throw (env, "java/io/IOException", local_error ()); + } + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv *env, jobject this) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + int fd; + + TRACE("begin"); + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (*env)->GetIntField (env, this, socket_fd); + if (local_shutdown_output (fd)) + { + _throw (env, "java/io/IOException", local_error ()); + } + + TRACE("end"); +#else + (void) this; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv *env, jobject this, jobject address) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jmethodID get_path; + jobject path; + jclass clazz1, clazz2; + const char *addr_path; + int fd; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + clazz2 = (*env)->GetObjectClass (env, address); + get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;"); + path = (*env)->CallObjectMethod (env, address, get_path); + addr_path = (*env)->GetStringUTFChars (env, (jstring) path, NULL); + if (local_bind (fd, addr_path)) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path); + + TRACE("end"); +#else + (void) this; + (void) address; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv *env, jobject this, jobject address) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jmethodID get_path; + jobject path; + jclass clazz1, clazz2; + char *addr_path; + int fd; + + TRACE("begin"); + + clazz1 = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz1, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + clazz2 = (*env)->GetObjectClass (env, address); + get_path = (*env)->GetMethodID (env, clazz2, "getPath", "()Ljava/lang/String;"); + path = (*env)->CallObjectMethod (env, address, get_path); + addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, NULL); + if (local_connect (fd, addr_path)) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path); + + TRACE("end"); +#else + (void) this; + (void) address; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +jint +Java_gnu_java_net_local_LocalSocketImpl_read (JNIEnv *env, jobject this, jbyteArray buf, jint off, jint len) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + jbyte *buffer; + jint count; + int fd; + + TRACE("begin"); + + if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf)) + { + _throw (env, "java/lang/ArrayIndexOutOfBoundsException", ""); + } + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return 0; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + buffer = (*env)->GetByteArrayElements (env, buf, NULL); + count = (jint) local_read (fd, (void *) (buffer + off), (int) len); + if (count < 0) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseByteArrayElements (env, buf, buffer, 0); + + TRACE("end"); + + return count; +#else + (void) this; + (void) buf; + (void) off; + (void) len; + _throw (env, "java/lang/Error", "support for local sockets not available"); + return -1; +#endif /* ENABLE_LOCAL_SOCKETS */ +} + + +void +Java_gnu_java_net_local_LocalSocketImpl_write (JNIEnv *env, jobject this, jbyteArray buf, jint off, jint len) +{ +#ifdef ENABLE_LOCAL_SOCKETS + jfieldID socket_fd; + jclass clazz; + jbyte *buffer; + int fd; + + TRACE("begin"); + + if (off < 0 || len < 0 || off + len > (*env)->GetArrayLength (env, buf)) + { + _throw (env, "java/lang/ArrayIndexOutOfBoundsException", ""); + } + + clazz = (*env)->GetObjectClass (env, this); + socket_fd = (*env)->GetFieldID (env, clazz, "socket_fd", "I"); + if (!socket_fd) + { + return; + } + fd = (int) (*env)->GetIntField (env, this, socket_fd); + buffer = (*env)->GetByteArrayElements (env, buf, NULL); + if (local_write (fd, (void *) (buffer + off), (int) len) < 0) + { + _throw (env, "java/io/IOException", local_error ()); + } + (*env)->ReleaseByteArrayElements (env, buf, buffer, JNI_ABORT); + + TRACE("end"); +#else + (void) this; + (void) buf; + (void) off; + (void) len; + _throw (env, "java/lang/Error", "support for local sockets not available"); +#endif /* ENABLE_LOCAL_SOCKETS */ +} diff --git a/native/jni/java-net/local.c b/native/jni/java-net/local.c new file mode 100644 index 000000000..cdddd89ef --- /dev/null +++ b/native/jni/java-net/local.c @@ -0,0 +1,193 @@ +/* local.c -- implementation of unix-domain sockets. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +USA + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef ENABLE_LOCAL_SOCKETS + +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <stdio.h> + +#include "local.h" + +const char * +local_error (void) +{ + return strerror (errno); +} + +int +local_create (int stream) +{ + return socket (PF_UNIX, stream ? SOCK_STREAM : SOCK_DGRAM, 0); +} + +static int gcc_sucks = 0; + +int +local_bind (int fd, const char *addr) +{ + struct sockaddr_un saddr; + + /* For some reason, GCC 4.0.1 on Darwin/x86 MODIFIES the `addr' + pointer in the CALLER's STACK FRAME after calling this function, + but if we add this statement below, it doesn't! */ + if (gcc_sucks) + fprintf (stderr, "bind %p\n", addr); + + if (strlen (addr) > sizeof (saddr.sun_path)) + { + errno = ENAMETOOLONG; + return -1; + } + + strncpy (saddr.sun_path, addr, sizeof (saddr.sun_path)); + saddr.sun_path[sizeof (saddr.sun_path)] = '\0'; + saddr.sun_family = AF_LOCAL; + + return bind (fd, (struct sockaddr *) &saddr, SUN_LEN (&saddr)); +} + +int +local_listen (int fd, int backlog) +{ + return listen (fd, backlog); +} + +int +local_accept (int fd, char *path) +{ + int newfd; + struct sockaddr_un addr; + socklen_t sz = SUN_LEN(&addr); + + newfd = accept (fd, (struct sockaddr *) &addr, &sz); + if (newfd >= 0) + { + /** sun_path is some crazy statically-sized buffer, and it's + size is different on different OSes. */ + int n = sizeof (addr.sun_path); + strncpy (path, addr.sun_path, n); + path[n] = '\0'; + } + return newfd; +} + +int +local_available (int fd) +{ + int val; + if (ioctl (fd, FIONREAD, &val)) + { + return -1; + } + return val; +} + +int +local_close (int fd) +{ + return close (fd); +} + +int +local_unlink (char *path) +{ + return unlink (path); +} + +int +local_shutdown_input (int fd) +{ + return shutdown (fd, 0); +} + +int +local_shutdown_output (int fd) +{ + return shutdown (fd, 1); +} + +int +local_connect (int fd, char *path) +{ + struct sockaddr_un saddr; + + strncpy (saddr.sun_path, path, sizeof (saddr.sun_path)); + saddr.sun_path[sizeof (saddr.sun_path) - 1] = '\0'; + saddr.sun_family = AF_UNIX; + + return connect (fd, (struct sockaddr *) &saddr, SUN_LEN(&saddr)); +} + +int +local_read (int fd, void *buf, int len) +{ + int count = -1; + do + { + count = read (fd, buf, len); + } + while (count == -1 && errno == EINTR); + return count; +} + +int +local_write (int fd, void *buf, int len) +{ + int count = -1; + do + { + count = write (fd, buf, len); + } + while (count == -1 && errno == EINTR); + return count; +} + +#endif /* ENABLE_LOCAL_SOCKETS */ diff --git a/native/jni/java-net/local.h b/native/jni/java-net/local.h new file mode 100644 index 000000000..035996a80 --- /dev/null +++ b/native/jni/java-net/local.h @@ -0,0 +1,28 @@ +#ifndef __LOCAL_H__ +#define __LOCAL_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif +#define __EMACSEN__ } + +extern const char *local_error (void); +extern int local_create (int); +extern int local_bind (int, const char *); +extern int local_listen (int, int); +extern int local_accept (int, char *); +extern int local_available (int); +extern int local_close (int); +extern int local_shutdown_input (int); +extern int local_shutdown_output (int); +extern int local_connect (int, char *); +extern int local_unlink (char *); +extern int local_read (int, void *, int); +extern int local_write (int, void *, int); + +#ifdef __cplusplus +} +#endif + +#endif /* __LOCAL_H__ */ |