OSDN Git Service

LocalSocket: Add support for SOCK_DGRAM and SOCK_SEQPACKET
authorMike Lockwood <lockwood@google.com>
Tue, 16 Jul 2013 18:36:22 +0000 (11:36 -0700)
committerMike Lockwood <lockwood@google.com>
Wed, 17 Jul 2013 00:31:15 +0000 (17:31 -0700)
Also replaced some JNI code with libcore IO support

Change-Id: I091e2b6b8dd1fec554936c1ffab29e50f0979e4a

api/current.txt
core/java/android/net/LocalServerSocket.java
core/java/android/net/LocalSocket.java
core/java/android/net/LocalSocketImpl.java
core/jni/android_net_LocalSocketImpl.cpp

index 7196161..44e5937 100644 (file)
@@ -13462,6 +13462,7 @@ package android.net {
 
   public class LocalSocket implements java.io.Closeable {
     ctor public LocalSocket();
+    ctor public LocalSocket(int);
     method public void bind(android.net.LocalSocketAddress) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public void connect(android.net.LocalSocketAddress) throws java.io.IOException;
@@ -13487,6 +13488,9 @@ package android.net {
     method public void setSoTimeout(int) throws java.io.IOException;
     method public void shutdownInput() throws java.io.IOException;
     method public void shutdownOutput() throws java.io.IOException;
+    field public static final int SOCKET_DGRAM = 1; // 0x1
+    field public static final int SOCKET_SEQPACKET = 3; // 0x3
+    field public static final int SOCKET_STREAM = 2; // 0x2
   }
 
   public class LocalSocketAddress {
index 2b93fc2..a36203b 100644 (file)
@@ -46,7 +46,7 @@ public class LocalServerSocket {
     {
         impl = new LocalSocketImpl();
 
-        impl.create(true);
+        impl.create(LocalSocket.SOCKET_STREAM);
 
         localAddress = new LocalSocketAddress(name);
         impl.bind(localAddress);
@@ -93,7 +93,7 @@ public class LocalServerSocket {
 
         impl.accept (acceptedImpl);
 
-        return new LocalSocket(acceptedImpl);
+        return new LocalSocket(acceptedImpl, LocalSocket.SOCKET_UNKNOWN);
     }
 
     /**
index 14a8094..31bc20b 100644 (file)
@@ -34,21 +34,42 @@ public class LocalSocket implements Closeable {
     private LocalSocketAddress localAddress;
     private boolean isBound;
     private boolean isConnected;
+    private final int sockType;
+
+    /** unknown socket type (used for constructor with existing file descriptor) */
+    /* package */ static final int SOCKET_UNKNOWN = 0;
+    /** Datagram socket type */
+    public static final int SOCKET_DGRAM = 1;
+    /** Stream socket type */
+    public static final int SOCKET_STREAM = 2;
+    /** Sequential packet socket type */
+    public static final int SOCKET_SEQPACKET = 3;
 
     /**
      * Creates a AF_LOCAL/UNIX domain stream socket.
      */
     public LocalSocket() {
-        this(new LocalSocketImpl());
+        this(SOCKET_STREAM);
+    }
+
+    /**
+     * Creates a AF_LOCAL/UNIX domain stream socket with given socket type
+     *
+     * @param sockType either {@link #SOCKET_DGRAM}, {@link #SOCKET_STREAM}
+     * or {@link #SOCKET_SEQPACKET}
+     */
+    public LocalSocket(int sockType) {
+        this(new LocalSocketImpl(), sockType);
         isBound = false;
         isConnected = false;
     }
+
     /**
      * Creates a AF_LOCAL/UNIX domain stream socket with FileDescriptor.
      * @hide
      */
     public LocalSocket(FileDescriptor fd) throws IOException {
-        this(new LocalSocketImpl(fd));
+        this(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
         isBound = true;
         isConnected = true;
     }
@@ -57,8 +78,9 @@ public class LocalSocket implements Closeable {
      * for use with AndroidServerSocket
      * @param impl a SocketImpl
      */
-    /*package*/ LocalSocket(LocalSocketImpl impl) {
+    /*package*/ LocalSocket(LocalSocketImpl impl, int sockType) {
         this.impl = impl;
+        this.sockType = sockType;
         this.isConnected = false;
         this.isBound = false;
     }
@@ -81,7 +103,7 @@ public class LocalSocket implements Closeable {
             synchronized (this) {
                 if (!implCreated) {
                     try {
-                        impl.create(true);
+                        impl.create(sockType);
                     } finally {
                         implCreated = true;
                     }
index 3b43c36..fa3cf58 100644 (file)
@@ -22,6 +22,10 @@ import java.io.InputStream;
 import java.io.FileDescriptor;
 import java.net.SocketOptions;
 
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.OsConstants;
+
 /**
  * Socket implementation used for android.net.LocalSocket and
  * android.net.LocalServerSocket. Supports only AF_LOCAL sockets.
@@ -159,7 +163,6 @@ class LocalSocketImpl
 
     private native int pending_native(FileDescriptor fd) throws IOException;
     private native int available_native(FileDescriptor fd) throws IOException;
-    private native void close_native(FileDescriptor fd) throws IOException;
     private native int read_native(FileDescriptor fd) throws IOException;
     private native int readba_native(byte[] b, int off, int len,
             FileDescriptor fd) throws IOException;
@@ -171,8 +174,6 @@ class LocalSocketImpl
             int namespace) throws IOException;
     private native void bindLocal(FileDescriptor fd, String name, int namespace)
             throws IOException;
-    private native FileDescriptor create_native(boolean stream)
-            throws IOException;
     private native void listen_native(FileDescriptor fd, int backlog)
             throws IOException;
     private native void shutdown(FileDescriptor fd, boolean shutdownInput);
@@ -222,15 +223,33 @@ class LocalSocketImpl
     /**
      * Creates a socket in the underlying OS.
      *
-     * @param stream true if this should be a stream socket, false for
-     * datagram.
+     * @param sockType either {@link LocalSocket#SOCKET_DGRAM}, {@link LocalSocket#SOCKET_STREAM}
+     * or {@link LocalSocket#SOCKET_SEQPACKET}
      * @throws IOException
      */
-    public void create (boolean stream) throws IOException {
+    public void create (int sockType) throws IOException {
         // no error if socket already created
         // need this for LocalServerSocket.accept()
         if (fd == null) {
-            fd = create_native(stream);
+            int osType;
+            switch (sockType) {
+                case LocalSocket.SOCKET_DGRAM:
+                    osType = OsConstants.SOCK_DGRAM;
+                    break;
+                case LocalSocket.SOCKET_STREAM:
+                    osType = OsConstants.SOCK_STREAM;
+                    break;
+                case LocalSocket.SOCKET_SEQPACKET:
+                    osType = OsConstants.SOCK_SEQPACKET;
+                    break;
+                default:
+                    throw new IllegalStateException("unknown sockType");
+            }
+            try {
+                fd = Libcore.os.socket(OsConstants.AF_UNIX, osType, 0);
+            } catch (ErrnoException e) {
+                e.rethrowAsIOException();
+            }
         }
     }
 
@@ -242,7 +261,11 @@ class LocalSocketImpl
     public void close() throws IOException {
         synchronized (LocalSocketImpl.this) {
             if (fd == null) return;
-            close_native(fd);
+            try {
+                Libcore.os.close(fd);
+            } catch (ErrnoException e) {
+                e.rethrowAsIOException();
+            }
             fd = null;
         }
     }
index f2b69c6..b9ed28e 100644 (file)
@@ -44,26 +44,6 @@ static jclass class_Credentials;
 static jclass class_FileDescriptor;
 static jmethodID method_CredentialsInit;
 
-/*
- * private native FileDescriptor
- * create_native(boolean stream)
- *               throws IOException;
- */
-static jobject
-socket_create (JNIEnv *env, jobject object, jboolean stream)
-{
-    int ret;
-
-    ret = socket(PF_LOCAL, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
-
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return NULL;
-    }
-
-    return jniCreateFileDescriptor(env,ret);
-}
-
 /* private native void connectLocal(FileDescriptor fd,
  * String name, int namespace) throws IOException
  */
@@ -445,32 +425,6 @@ static jint socket_available (JNIEnv *env, jobject object,
 #endif
 }
 
-static void socket_close (JNIEnv *env, jobject object, jobject fileDescriptor)
-{
-    int fd;
-    int err;
-
-    if (fileDescriptor == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return;
-    }
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionOccurred() != NULL) {
-        return;
-    }
-
-    do {
-        err = close(fd);
-    } while (err < 0 && errno == EINTR);
-
-    if (err < 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-}
-
 /**
  * Processes ancillary data, handling only
  * SCM_RIGHTS. Creates appropriate objects and sets appropriate
@@ -909,7 +863,6 @@ static JNINativeMethod gMethods[] = {
      /* name, signature, funcPtr */
     {"getOption_native", "(Ljava/io/FileDescriptor;I)I", (void*)socket_getOption},
     {"setOption_native", "(Ljava/io/FileDescriptor;III)V", (void*)socket_setOption},
-    {"create_native", "(Z)Ljava/io/FileDescriptor;", (void*)socket_create},
     {"connectLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
                                                 (void*)socket_connect_local},
     {"bindLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", (void*)socket_bind_local},
@@ -918,7 +871,6 @@ static JNINativeMethod gMethods[] = {
     {"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown},
     {"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available},
     {"pending_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_pending},
-    {"close_native", "(Ljava/io/FileDescriptor;)V", (void*) socket_close},
     {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
     {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
     {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},