[cp-patches] RFC: local (unix-domain) sockets
Hi. A few of us were chatting in IRC today about local socket support, aka Unix domain sockets, in Classpath (that is, where you bind a socket to a special file, instead of to a network address. This is used mostly for IPC; for example, local X11 connections can use local sockets). I mentioned that I had written such a thing, and some people were interested in seeing this in Classpath. So, do we want this? The attached patch is my implementation of this, which basically introduces three new classes: gnu.java.net.local.LocalServerSocket gnu.java.net.local.LocalSocket gnu.java.net.local.LocalSocketAddress Which operate similarly to how normal Sockets do, but over local sockets. Note that this patch has to be cleaned up a lot, mostly to add detection for local socket support in configure. Also, SocketChannel support is missing, but may not be too hard to implement. If there is interest, I can polish this up some more and check it in. Thanks. --- /dev/null 2006-04-12 17:45:39.0 -0700 +++ include/gnu_java_net_local_LocalSocketImpl.h2006-04-12 16:41:25.0 -0700 @@ -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 + +#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__ */ --- /dev/null 2006-04-12 17:45:39.0 -0700 +++ gnu/java/net/local/LocalServerSocket.java 2006-04-12 15:21:42.0 -0700 @@ -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; + +
Re: [cp-patches] RFC: local (unix-domain) sockets
Hi, On Wed, 2006-04-12 at 18:11 -0700, Casey Marshall wrote: > Note that this patch has to be cleaned up a lot, mostly to add > detection for local socket support in configure. Also, SocketChannel > support is missing, but may not be too hard to implement. > > If there is interest, I can polish this up some more and check it in. That would be great. Java DBUS bindings will require this, so will the X protocol peer set we discussed on IRC. Tom
Re: [cp-patches] RFC: local (unix-domain) sockets
Casey Marshall wrote: Hi. A few of us were chatting in IRC today about local socket support, aka Unix domain sockets, in Classpath (that is, where you bind a socket to a special file, instead of to a network address. This is used mostly for IPC; for example, local X11 connections can use local sockets). I mentioned that I had written such a thing, and some people were interested in seeing this in Classpath. So, do we want this? The attached patch is my implementation of this, which basically introduces three new classes: gnu.java.net.local.LocalServerSocket gnu.java.net.local.LocalSocket gnu.java.net.local.LocalSocketAddress Which operate similarly to how normal Sockets do, but over local sockets. Note that this patch has to be cleaned up a lot, mostly to add detection for local socket support in configure. Also, SocketChannel support is missing, but may not be too hard to implement. If there is interest, I can polish this up some more and check it in. This would be great. I have already done a very simple UnixDomainSocket implementation for some of our internal code. I am sure that having this in classpath will save a lot of duplication of effort in this area. David Daney.
Re: [cp-patches] RFC: local (unix-domain) sockets
This isn't really related, but compiling this code with GCC 4.0.1 on Darwin/x86 introduces a potentially serious problem. In the `localBind' JNI function, I am doing this: char *addr_path; ... addr_path = (char *) (*env)->GetStringUTFChars (env, (jstring) path, &copied); if (local_bind (fd, addr_path)) { _throw (env, "java/io/IOException", local_error ()); } (*env)->ReleaseStringUTFChars (env, (jstring) path, addr_path); When it gets to the `ReleaseStringUTFChars' call, `addr_path' has changed! And, since `ReleaseStringUTFChars' calls free(3) on jamvm, this means that I'm freeing a pointer that was never malloc'd! It looks like the least significant byte of the pointer is being set to zero. If I add a `printf' of the path to `local_bind,' the problem disappears. So, my question is, is this a known problem with GCC? If so, is there any way to work around it? `local_bind' is an extremely simple function: int local_bind (int fd, char *addr) { struct sockaddr_un saddr; strncpy (saddr.sun_path, (char *) 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)); } Does anyone know how to prevent GCC from breaking my program like this? Am I doing something wrong without realizing it?
Re: [cp-patches] RFC: local (unix-domain) sockets
> "Casey" == Casey Marshall <[EMAIL PROTECTED]> writes: Casey> This isn't really related, but compiling this code with GCC 4.0.1 on Casey> Darwin/x86 introduces a potentially serious problem. In the Casey> `localBind' JNI function, I am doing this: Casey> So, my question is, is this a known problem with GCC? If so, is there Casey> any way to work around it? Whenever I see a cast these days, I think that there must be an aliasing bug. But if there's one in this code, I don't see it. Offhand I don't recall hearing of a bug like this. Tom
Re: [cp-patches] RFC: local (unix-domain) sockets
On Apr 13, 2006, at 5:48 PM, Tom Tromey wrote: "Casey" == Casey Marshall <[EMAIL PROTECTED]> writes: Casey> This isn't really related, but compiling this code with GCC 4.0.1 on Casey> Darwin/x86 introduces a potentially serious problem. In the Casey> `localBind' JNI function, I am doing this: Casey> So, my question is, is this a known problem with GCC? If so, is there Casey> any way to work around it? Whenever I see a cast these days, I think that there must be an aliasing bug. But if there's one in this code, I don't see it. Offhand I don't recall hearing of a bug like this. The cast got me thinking, because GetStringUTFChars returns `const char *', and I'm trying to keep the code -Werror clean, so I cast it to `char *'. Changing everything to `const char *' in both the JNI function and the `local_bind' function does nothing, though. My workaround so far is to add this to `local_bind': > static int foo = 0; > ... > if (foo) > fprintf (stderr, "bind %p\n", addr);
Re: [cp-patches] RFC: local (unix-domain) sockets
Hi, I'd be inclined to have a look at the code produced with and without the workaround. The easiest way I find to do this is to temporarily hack the Makefile and add a -S onto the CFLAGS. Touch the file and remake, leaving the assembler in the .o file (of course the link will now fail). This way you don't have to worry about include paths, -Ds, etc. Alternatively you can get a dissassembly in gdb with x/i local_bind... Rob. P.S. What version of JamVM were you using? I kinda get worried when I see pointers changing, as the CVS version updates pointers (heap compaction) but this isn't an object reference... On 4/14/06, Casey Marshall <[EMAIL PROTECTED]> wrote: > On Apr 13, 2006, at 5:48 PM, Tom Tromey wrote: > > >> "Casey" == Casey Marshall <[EMAIL PROTECTED]> writes: > > > > Casey> This isn't really related, but compiling this code with GCC > > 4.0.1 on > > Casey> Darwin/x86 introduces a potentially serious problem. In the > > Casey> `localBind' JNI function, I am doing this: > > > > Casey> So, my question is, is this a known problem with GCC? If so, > > is there > > Casey> any way to work around it? > > > > Whenever I see a cast these days, I think that there must be an > > aliasing bug. But if there's one in this code, I don't see it. > > Offhand I don't recall hearing of a bug like this. > > > > The cast got me thinking, because GetStringUTFChars returns `const > char *', and I'm trying to keep the code -Werror clean, so I cast it > to `char *'. Changing everything to `const char *' in both the JNI > function and the `local_bind' function does nothing, though. > > My workaround so far is to add this to `local_bind': > > > static int foo = 0; > > ... > > if (foo) > > fprintf (stderr, "bind %p\n", addr); > >