summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCasey Marshall <csm@gnu.org>2006-04-16 21:54:09 +0000
committerCasey Marshall <csm@gnu.org>2006-04-16 21:54:09 +0000
commit0299478674d2218168968af00a90c01099ebc617 (patch)
tree8caf96e23178141fedfd280347bc5fa4a19e0697
parent8ffa5c4e180edd9801a841264f2fd8a23b6a7d52 (diff)
downloadclasspath-0299478674d2218168968af00a90c01099ebc617.tar.gz
2005-04-16 Casey Marshall <csm@gnu.org>
* configure.ac (--enable-local-sockets): new enable argument. (ENABLE_LOCAL_SOCKETS): new define. * native/jni/java-net/Makefile.am (local_sources): new variable. (lib_javanet_la_SOURCES): append `local_sources.' * native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c, * native/jni/java-net/local.c, * native/jni/java-net/local.h, * include/gnu_java_net_local_LocalSocketImpl.h, * gnu/java/net/local/LocalServerSocket.java, * gnu/java/net/local/LocalSocket.java, * gnu/java/net/local/LocalSocketAddress.java, * gnu/java/net/local/LocalSocketImpl.java: new files.
-rw-r--r--configure.ac24
-rw-r--r--gnu/java/net/local/LocalServerSocket.java172
-rw-r--r--gnu/java/net/local/LocalSocket.java312
-rw-r--r--gnu/java/net/local/LocalSocketAddress.java100
-rw-r--r--gnu/java/net/local/LocalSocketImpl.java322
-rw-r--r--include/gnu_java_net_local_LocalSocketImpl.h31
-rw-r--r--native/jni/java-net/Makefile.am13
-rw-r--r--native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c538
-rw-r--r--native/jni/java-net/local.c182
-rw-r--r--native/jni/java-net/local.h28
10 files changed, 1720 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index b426b1f17..65b1921f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -612,6 +612,30 @@ AC_SUBST(PATH_TO_GLIBJ_ZIP)
dnl -----------------------------------------------------------
+dnl Check if local socket support should be included.
+dnl -----------------------------------------------------------
+AC_ARG_ENABLE([local-sockets],
+ [AS_HELP_STRING(--enable-local-sockets,enables local (AF_LOCAL) socket API [default: no])],
+ [case "${enableval}" in
+ yes)
+ ENABLE_LOCAL_SOCKETS=yes
+ ;;
+ *)
+ ENABLE_LOCAL_SOCKETS=no
+ ;;
+ esac],
+ [])
+if test "x$ENABLE_LOCAL_SOCKETS" = "xyes"
+then
+ AC_CHECK_HEADER([sys/un.h])
+ AC_CHECK_FUNCS([read write bind listen accept shutdown], [],
+ AC_MSG_ERROR([networking support not available]))
+ AC_DEFINE(ENABLE_LOCAL_SOCKETS, [1], [Define to enable support for local sockets.])
+fi
+AM_CONDITIONAL(ENABLE_LOCAL_SOCKETS, test "x$ENABLE_LOCAL_SOCKETS" = "xyes")
+
+
+dnl -----------------------------------------------------------
dnl output files
dnl -----------------------------------------------------------
AC_CONFIG_FILES([Makefile
diff --git a/gnu/java/net/local/LocalServerSocket.java b/gnu/java/net/local/LocalServerSocket.java
new file mode 100644
index 000000000..15163f243
--- /dev/null
+++ b/gnu/java/net/local/LocalServerSocket.java
@@ -0,0 +1,172 @@
+/* LocalServerSocket.java -- a unix domain server socket.
+ 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. */
+
+
+package gnu.java.net.local;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+
+public final class LocalServerSocket extends ServerSocket
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private LocalSocketImpl myImpl;
+ private boolean closed;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public LocalServerSocket () throws IOException
+ {
+ myImpl = new LocalSocketImpl ();
+ }
+
+ public LocalServerSocket (SocketAddress bindPoint) throws IOException
+ {
+ this ();
+ bind (bindPoint);
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public void bind (SocketAddress bindPoint) throws IOException
+ {
+ bind (bindPoint, 0);
+ }
+
+ public void bind (SocketAddress bindPoint, int backlog) throws IOException
+ {
+ myImpl.doCreate ();
+ myImpl.bind (bindPoint);
+ myImpl.listen (backlog);
+ }
+
+ public InetAddress getInetAddress ()
+ {
+ return null;
+ }
+
+ public int getLocalPort ()
+ {
+ return -1;
+ }
+
+ public SocketAddress getLocalSocketAddress ()
+ {
+ return myImpl.getLocalAddress ();
+ }
+
+ public Socket accept () throws IOException
+ {
+ LocalSocket s = new LocalSocket (true);
+ myImpl.accept (s.getLocalImpl());
+ s.localConnected = true;
+ return s;
+ }
+
+ public void close () throws IOException
+ {
+ myImpl.close ();
+ myImpl.unlink ();
+ closed = true;
+ }
+
+ public boolean isBound ()
+ {
+ return myImpl.getLocalAddress () != null;
+ }
+
+ public boolean isClosed ()
+ {
+ return closed;
+ }
+
+ public void setSoTimeout (int timeout)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support timeouts");
+ }
+
+ public int getSoTimeout ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support timeouts");
+ }
+
+ public void setReuseAddress (boolean b)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support reuse address");
+ }
+
+ public boolean getReuseAddress ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support reuse address");
+ }
+
+ public String toString ()
+ {
+ return LocalServerSocket.class.getName() + " [ address="
+ + myImpl.getLocalAddress() + " ]";
+ }
+
+ public void setReceiveBufferSize (int size)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+
+ public int getReceiveBufferSize ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+
+ public void setSendBufferSize (int size)
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+
+ public int getSendBufferSize ()
+ {
+ throw new UnsupportedOperationException ("local sockets do not support buffer size");
+ }
+}
diff --git a/gnu/java/net/local/LocalSocket.java b/gnu/java/net/local/LocalSocket.java
new file mode 100644
index 000000000..b977d69c1
--- /dev/null
+++ b/gnu/java/net/local/LocalSocket.java
@@ -0,0 +1,312 @@
+/* LocalSocket.java -- a unix domain client socket.
+ 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. */
+
+
+package gnu.java.net.local;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+
+import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.SocketChannel;
+
+/**
+ * A local, or unix-domain socket. Unix domain sockets are connected on the
+ * local filesystem itself, rather than a remote address.
+ */
+public final class LocalSocket extends Socket
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private final LocalSocketImpl localimpl;
+ boolean localClosed;
+ boolean localConnected;
+
+ // Constructors.
+ // -------------------------------------------------------------------------
+
+ public LocalSocket () throws SocketException
+ {
+ super ();
+ localimpl = new LocalSocketImpl ();
+ }
+
+ public LocalSocket (LocalSocketAddress addr) throws SocketException
+ {
+ this ();
+ try
+ {
+ connect (addr);
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException ();
+ se.initCause (ioe);
+ throw se;
+ }
+ }
+
+ LocalSocket (boolean nocreate) throws IOException
+ {
+ super ();
+ localimpl = new LocalSocketImpl (nocreate);
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public void bind (SocketAddress bindpoint) throws IOException
+ {
+ throw new SocketException ("binding local client sockets is nonsensical");
+ }
+
+ public void connect (SocketAddress endpoint, int timeout) throws IOException
+ {
+ if (isClosed ())
+ {
+ throw new SocketException ("socket is closed");
+ }
+ if (! (endpoint instanceof LocalSocketAddress))
+ {
+ throw new IllegalArgumentException ("socket address is not a local address");
+ }
+ if (getChannel() != null && !getChannel().isBlocking())
+ {
+ throw new IllegalBlockingModeException ();
+ }
+
+ try
+ {
+ localimpl.doCreate ();
+ localimpl.localConnect ((LocalSocketAddress) endpoint);
+ }
+ catch (IOException ioe)
+ {
+ close ();
+ throw ioe;
+ }
+ localConnected = true;
+ }
+
+ public InetAddress getInetAddress ()
+ {
+ return null;
+ }
+
+ public InetAddress getLocalAddress ()
+ {
+ return null;
+ }
+
+ public int getPort ()
+ {
+ return -1;
+ }
+
+ public int getLocalPort ()
+ {
+ return -1;
+ }
+
+ public SocketChannel getChannel ()
+ {
+ return null;
+ }
+
+ public SocketAddress getLocalSocketAddress ()
+ {
+ return localimpl.getLocalAddress ();
+ }
+
+ public SocketAddress getRemoteSocketAddress ()
+ {
+ return localimpl.getRemoteAddress ();
+ }
+
+ public InputStream getInputStream () throws IOException
+ {
+ return localimpl.getInputStream ();
+ }
+
+ public OutputStream getOutputStream () throws IOException
+ {
+ return localimpl.getOutputStream ();
+ }
+
+ public void sendUrgentData (int b) throws IOException
+ {
+ localimpl.sendUrgentData (b);
+ }
+
+ public synchronized void close () throws IOException
+ {
+ localimpl.close ();
+ localClosed = true;
+ }
+
+ public void shutdownInput () throws IOException
+ {
+ localimpl.shutdownInput ();
+ }
+
+ public void shutdownOutput () throws IOException
+ {
+ localimpl.shutdownOutput ();
+ }
+
+ public boolean isClosed ()
+ {
+ return localClosed;
+ }
+
+ public boolean isBound ()
+ {
+ return false;
+ }
+
+ public boolean isConnected ()
+ {
+ return localConnected;
+ }
+
+ // Unsupported methods.
+ // -------------------------------------------------------------------------
+
+ public void setTcpNoDelay (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getTcpNoDelay() throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setSoLinger (boolean b, int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getSoLinger () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setOOBInline (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getOOBInline () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setSoTimeout (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getSoTimeout () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setSendBufferSize (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getSendBufferSize() throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setReceiveBufferSize (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getReceiveBufferSize () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setKeepAlive (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getKeepAlive () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setTrafficClass (int i) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public int getTrafficClass () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public void setReuseAddress (boolean b) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ public boolean getReuseAddress () throws SocketException
+ {
+ throw new SocketException ("local sockets do not support this option");
+ }
+
+ LocalSocketImpl getLocalImpl ()
+ {
+ return localimpl;
+ }
+}
diff --git a/gnu/java/net/local/LocalSocketAddress.java b/gnu/java/net/local/LocalSocketAddress.java
new file mode 100644
index 000000000..ac5c53db2
--- /dev/null
+++ b/gnu/java/net/local/LocalSocketAddress.java
@@ -0,0 +1,100 @@
+/* LocalSocketAddress.java -- unix-domain socket address.
+ 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. */
+
+
+package gnu.java.net.local;
+
+import java.net.SocketAddress;
+
+public final class LocalSocketAddress extends SocketAddress
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private final String path;
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Creates a new unix domain socket address.
+ *
+ * @param path The path to the socket.
+ * @throws NullPointerException If <i>path</i> is <tt>null</tt>.
+ */
+ public LocalSocketAddress (String path)
+ {
+ if (path == null)
+ {
+ throw new NullPointerException ();
+ }
+ this.path = path;
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ /**
+ * Returns the path of the socket.
+ *
+ * @return The path.
+ */
+ public String getPath ()
+ {
+ return path;
+ }
+
+ public boolean equals (Object o)
+ {
+ if (!(o instanceof LocalSocketAddress))
+ {
+ return false;
+ }
+ return getPath ().equals (((LocalSocketAddress) o).getPath ());
+ }
+
+ public int hashCode ()
+ {
+ return path.hashCode();
+ }
+
+ public String toString ()
+ {
+ return super.toString() + " [ " + path + " ]";
+ }
+}
diff --git a/gnu/java/net/local/LocalSocketImpl.java b/gnu/java/net/local/LocalSocketImpl.java
new file mode 100644
index 000000000..f907e5f46
--- /dev/null
+++ b/gnu/java/net/local/LocalSocketImpl.java
@@ -0,0 +1,322 @@
+/* LocalSocketImpl.java -- a unix domain client 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. */
+
+
+package gnu.java.net.local;
+
+import java.io.FileDescriptor;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+
+final class LocalSocketImpl extends SocketImpl
+{
+
+ // Fields.
+ // -------------------------------------------------------------------------
+
+ private boolean created;
+ private InputStream in;
+ private OutputStream out;
+ private int socket_fd;
+ private LocalSocketAddress local;
+ private LocalSocketAddress remote;
+
+ static
+ {
+ try
+ {
+ System.loadLibrary ("javanet");
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace ();
+ }
+ }
+
+ // Constructor.
+ // -------------------------------------------------------------------------
+
+ LocalSocketImpl ()
+ {
+ this (false);
+ }
+
+ LocalSocketImpl (boolean nocreate)
+ {
+ created = nocreate;
+ socket_fd = -1;
+ fd = new FileDescriptor ();
+ }
+
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public void setOption (int opt, Object value) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support options");
+ }
+
+ public Object getOption (int opt) throws SocketException
+ {
+ throw new SocketException ("local sockets do not support options");
+ }
+
+ protected native void create (boolean stream) throws IOException;
+ protected native void listen (int timeout) throws IOException;
+ protected native void accept (LocalSocketImpl socket) throws IOException;
+ protected native int available () throws IOException;
+ protected native void close () throws IOException;
+ protected native void sendUrgentData (int data) throws IOException;
+ protected native void shutdownInput () throws IOException;
+ protected native void shutdownOutput () throws IOException;
+
+ native void unlink () throws IOException;
+ native void localBind (LocalSocketAddress addr) throws IOException;
+ native void localConnect (LocalSocketAddress addr) throws IOException;
+ native int read (byte[] buf, int off, int len) throws IOException;
+ native void write (byte[] buf, int off, int len) throws IOException;
+
+ void doCreate () throws IOException
+ {
+ if (!created)
+ {
+ create (true);
+ }
+ }
+
+ LocalSocketAddress getLocalAddress ()
+ {
+ return local;
+ }
+
+ LocalSocketAddress getRemoteAddress ()
+ {
+ return remote;
+ }
+
+ protected InputStream getInputStream()
+ {
+ if (in == null)
+ {
+ in = new LocalInputStream (this);
+ }
+
+ return in;
+ }
+
+ protected OutputStream getOutputStream()
+ {
+ if (out == null)
+ {
+ out = new LocalOutputStream (this);
+ }
+
+ return out;
+ }
+
+ protected void accept (SocketImpl impl) throws IOException
+ {
+ if (! (impl instanceof LocalSocketImpl))
+ {
+ throw new IllegalArgumentException ("not a local socket");
+ }
+ accept ((LocalSocketImpl) impl);
+ }
+
+ protected void connect (String host, int port) throws IOException
+ {
+ throw new SocketException ("this is a local socket");
+ }
+
+ protected void connect (InetAddress addr, int port) throws IOException
+ {
+ throw new SocketException ("this is a local socket");
+ }
+
+ protected void connect(SocketAddress addr, int timeout) throws IOException
+ {
+ if (! (addr instanceof LocalSocketAddress))
+ {
+ throw new SocketException ("address is not local");
+ }
+ localConnect ((LocalSocketAddress) addr);
+ }
+
+ protected void bind (InetAddress addr, int port) throws IOException
+ {
+ throw new SocketException ("this is a local socket");
+ }
+
+ protected void bind (SocketAddress addr) throws IOException
+ {
+ if (! (addr instanceof LocalSocketAddress))
+ {
+ throw new SocketException ("address is not local");
+ }
+ localBind ((LocalSocketAddress) addr);
+ }
+
+ // Inner classes.
+ // -------------------------------------------------------------------------
+
+ class LocalInputStream extends InputStream
+ {
+
+ // Field.
+ // -----------------------------------------------------------------------
+
+ private final LocalSocketImpl impl;
+
+ // Constructor.
+ // -----------------------------------------------------------------------
+
+ LocalInputStream (LocalSocketImpl impl)
+ {
+ this.impl = impl;
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public int available () throws IOException
+ {
+ return impl.available();
+ }
+
+ public boolean markSupported ()
+ {
+ return false;
+ }
+
+ public void mark (int readLimit)
+ {
+ }
+
+ public void reset () throws IOException
+ {
+ throw new IOException ("mark/reset not supported");
+ }
+
+ public void close () throws IOException
+ {
+ impl.close();
+ }
+
+ public int read () throws IOException
+ {
+ byte[] buf = new byte[1];
+ int ret = read (buf);
+ if (ret != -1)
+ {
+ return buf[0] & 0xFF;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ public int read (byte[] buf) throws IOException
+ {
+ return read (buf, 0, buf.length);
+ }
+
+ public int read (byte[] buf, int off, int len) throws IOException
+ {
+ int ret = impl.read (buf, off, len);
+
+ if (ret == 0)
+ {
+ return -1;
+ }
+
+ return ret;
+ }
+ }
+
+ class LocalOutputStream extends OutputStream
+ {
+
+ // Field.
+ // -----------------------------------------------------------------------
+
+ private final LocalSocketImpl impl;
+
+ // Constructor.
+ // -----------------------------------------------------------------------
+
+ LocalOutputStream (LocalSocketImpl impl)
+ {
+ this.impl = impl;
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public void close () throws IOException
+ {
+ impl.close ();
+ }
+
+ public void flush () throws IOException
+ {
+ }
+
+ public void write (int b) throws IOException
+ {
+ byte[] buf = new byte [1];
+ buf[0] = (byte) b;
+ write (buf);
+ }
+
+ public void write (byte[] buf) throws IOException
+ {
+ write (buf, 0, buf.length);
+ }
+
+ public void write (byte[] buf, int off, int len) throws IOException
+ {
+ impl.write (buf, off, len);
+ }
+ }
+}
diff --git a/include/gnu_java_net_local_LocalSocketImpl.h b/include/gnu_java_net_local_LocalSocketImpl.h
new file mode 100644
index 000000000..3309053f1
--- /dev/null
+++ b/include/gnu_java_net_local_LocalSocketImpl.h
@@ -0,0 +1,31 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+#ifndef __gnu_java_net_local_LocalSocketImpl__
+#define __gnu_java_net_local_LocalSocketImpl__
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_create (JNIEnv *env, jobject, jboolean);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_listen (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_accept (JNIEnv *env, jobject, jobject);
+JNIEXPORT jint JNICALL Java_gnu_java_net_local_LocalSocketImpl_available (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_close (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_sendUrgentData (JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_shutdownInput (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_shutdownOutput (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_unlink (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_localBind (JNIEnv *env, jobject, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_localConnect (JNIEnv *env, jobject, jobject);
+JNIEXPORT jint JNICALL Java_gnu_java_net_local_LocalSocketImpl_read (JNIEnv *env, jobject, jbyteArray, jint, jint);
+JNIEXPORT void JNICALL Java_gnu_java_net_local_LocalSocketImpl_write (JNIEnv *env, jobject, jbyteArray, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gnu_java_net_local_LocalSocketImpl__ */
diff --git a/native/jni/java-net/Makefile.am b/native/jni/java-net/Makefile.am
index 5ad257f5a..e85d27080 100644
--- a/native/jni/java-net/Makefile.am
+++ b/native/jni/java-net/Makefile.am
@@ -1,14 +1,23 @@
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
AM_LDFLAGS = @CLASSPATH_MODULE@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
-AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@ --save-temps
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..4a66ae4d2
--- /dev/null
+++ b/native/jni/java-net/local.c
@@ -0,0 +1,182 @@
+/* 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 <errno.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)
+{
+ return read (fd, buf, len);
+}
+
+int
+local_write (int fd, void *buf, int len)
+{
+ return write (fd, buf, len);
+}
+
+#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__ */