diff options
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/os/ParcelFileDescriptor.java | 56 | ||||
| -rw-r--r-- | core/jni/android_os_ParcelFileDescriptor.cpp | 31 |
3 files changed, 74 insertions, 15 deletions
diff --git a/api/current.txt b/api/current.txt index dd619cfa0128..3339497a2f2c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -13924,12 +13924,14 @@ package android.os { public class ParcelFileDescriptor implements android.os.Parcelable { ctor public ParcelFileDescriptor(android.os.ParcelFileDescriptor); + method public static android.os.ParcelFileDescriptor adoptFd(int); method public void close() throws java.io.IOException; method public static android.os.ParcelFileDescriptor[] createPipe() throws java.io.IOException; method public int describeContents(); method public int detachFd(); method public static android.os.ParcelFileDescriptor dup(java.io.FileDescriptor) throws java.io.IOException; method public static android.os.ParcelFileDescriptor fromDatagramSocket(java.net.DatagramSocket); + method public static android.os.ParcelFileDescriptor fromFd(int) throws java.io.IOException; method public static android.os.ParcelFileDescriptor fromSocket(java.net.Socket); method public int getFd(); method public java.io.FileDescriptor getFileDescriptor(); diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 727fcca019d3..3ea3f5608ed9 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -129,7 +129,46 @@ public class ParcelFileDescriptor implements Parcelable { } /** - * Create a new ParcelFileDescriptor from the specified Socket. + * Create a new ParcelFileDescriptor from a raw native fd. The new + * ParcelFileDescriptor holds a dup of the original fd passed in here, + * so you must still close that fd as well as the new ParcelFileDescriptor. + * + * @param fd The native fd that the ParcelFileDescriptor should dup. + * + * @return Returns a new ParcelFileDescriptor holding a FileDescriptor + * for a dup of the given fd. + */ + public static ParcelFileDescriptor fromFd(int fd) throws IOException { + FileDescriptor fdesc = getFileDescriptorFromFd(fd); + return new ParcelFileDescriptor(fdesc); + } + + // Extracts the file descriptor from the specified socket and returns it untouched + private static native FileDescriptor getFileDescriptorFromFd(int fd) throws IOException; + + /** + * Take ownership of a raw native fd in to a new ParcelFileDescriptor. + * The returned ParcelFileDescriptor now owns the given fd, and will be + * responsible for closing it. You must not close the fd yourself. + * + * @param fd The native fd that the ParcelFileDescriptor should adopt. + * + * @return Returns a new ParcelFileDescriptor holding a FileDescriptor + * for the given fd. + */ + public static ParcelFileDescriptor adoptFd(int fd) { + FileDescriptor fdesc = getFileDescriptorFromFdNoDup(fd); + return new ParcelFileDescriptor(fdesc); + } + + // Extracts the file descriptor from the specified socket and returns it untouched + private static native FileDescriptor getFileDescriptorFromFdNoDup(int fd); + + /** + * Create a new ParcelFileDescriptor from the specified Socket. The new + * ParcelFileDescriptor holds a dup of the original FileDescriptor in + * the Socket, so you must still close the Socket as well as the new + * ParcelFileDescriptor. * * @param socket The Socket whose FileDescriptor is used to create * a new ParcelFileDescriptor. @@ -163,17 +202,14 @@ public class ParcelFileDescriptor implements Parcelable { */ public static ParcelFileDescriptor[] createPipe() throws IOException { FileDescriptor[] fds = new FileDescriptor[2]; - int res = createPipeNative(fds); - if (res == 0) { - ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2]; - pfds[0] = new ParcelFileDescriptor(fds[0]); - pfds[1] = new ParcelFileDescriptor(fds[1]); - return pfds; - } - throw new IOException("Unable to create pipe: errno=" + -res); + createPipeNative(fds); + ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2]; + pfds[0] = new ParcelFileDescriptor(fds[0]); + pfds[1] = new ParcelFileDescriptor(fds[1]); + return pfds; } - private static native int createPipeNative(FileDescriptor[] outFds); + private static native void createPipeNative(FileDescriptor[] outFds) throws IOException; /** * @hide Please use createPipe() or ContentProvider.openPipeHelper(). diff --git a/core/jni/android_os_ParcelFileDescriptor.cpp b/core/jni/android_os_ParcelFileDescriptor.cpp index 4ec131cd9f48..99a2d049be87 100644 --- a/core/jni/android_os_ParcelFileDescriptor.cpp +++ b/core/jni/android_os_ParcelFileDescriptor.cpp @@ -34,20 +34,37 @@ static struct parcel_file_descriptor_offsets_t jfieldID mFileDescriptor; } gParcelFileDescriptorOffsets; -static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env, +static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFd(JNIEnv* env, + jobject clazz, jint origfd) +{ + int fd = dup(origfd); + if (fd < 0) { + jniThrowException(env, "java/io/IOException", strerror(errno)); + return NULL; + } + return jniCreateFileDescriptor(env, fd); +} + +static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup(JNIEnv* env, + jobject clazz, jint fd) +{ + return jniCreateFileDescriptor(env, fd); +} + +static void android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env, jobject clazz, jobjectArray outFds) { int fds[2]; if (pipe(fds) < 0) { - return -errno; + int therr = errno; + jniThrowException(env, "java/io/IOException", strerror(therr)); + return; } for (int i=0; i<2; i++) { jobject fdObj = jniCreateFileDescriptor(env, fds[i]); env->SetObjectArrayElement(outFds, i, fdObj); } - - return 0; } static jint getFd(JNIEnv* env, jobject clazz) @@ -102,7 +119,11 @@ static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject cl } static const JNINativeMethod gParcelFileDescriptorMethods[] = { - {"createPipeNative", "([Ljava/io/FileDescriptor;)I", + {"getFileDescriptorFromFd", "(I)Ljava/io/FileDescriptor;", + (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFd}, + {"getFileDescriptorFromFdNoDup", "(I)Ljava/io/FileDescriptor;", + (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup}, + {"createPipeNative", "([Ljava/io/FileDescriptor;)V", (void*)android_os_ParcelFileDescriptor_createPipeNative}, {"getStatSize", "()J", (void*)android_os_ParcelFileDescriptor_getStatSize}, |