blob: 4ec131cd9f48823948dbace922b99a8ed74cd096 [file] [log] [blame]
Joe Onoratob1a7ffe2009-05-06 18:06:21 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080016
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070017//#define LOG_NDEBUG 0
18
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019#include "JNIHelp.h"
20
21#include <fcntl.h>
22#include <sys/stat.h>
23#include <stdio.h>
24
25#include <utils/Log.h>
26
27#include <android_runtime/AndroidRuntime.h>
28
29namespace android
30{
31
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070032static struct parcel_file_descriptor_offsets_t
33{
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070034 jfieldID mFileDescriptor;
35} gParcelFileDescriptorOffsets;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
Dianne Hackborn23fdaf62010-08-06 12:16:55 -070037static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
38 jobject clazz, jobjectArray outFds)
39{
40 int fds[2];
41 if (pipe(fds) < 0) {
42 return -errno;
43 }
44
45 for (int i=0; i<2; i++) {
Elliott Hughesa3804cf2011-04-11 16:50:19 -070046 jobject fdObj = jniCreateFileDescriptor(env, fds[i]);
Dianne Hackborn23fdaf62010-08-06 12:16:55 -070047 env->SetObjectArrayElement(outFds, i, fdObj);
48 }
49
50 return 0;
51}
52
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070053static jint getFd(JNIEnv* env, jobject clazz)
54{
55 jobject descriptor = env->GetObjectField(clazz, gParcelFileDescriptorOffsets.mFileDescriptor);
56 if (descriptor == NULL) return -1;
Elliott Hughesa3804cf2011-04-11 16:50:19 -070057 return jniGetFDFromFileDescriptor(env, descriptor);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070058}
59
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060static jlong android_os_ParcelFileDescriptor_getStatSize(JNIEnv* env,
61 jobject clazz)
62{
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070063 jint fd = getFd(env, clazz);
64 if (fd < 0) {
65 jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
66 return -1;
67 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -070068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 struct stat st;
70 if (fstat(fd, &st) != 0) {
71 return -1;
72 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -070073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
75 return st.st_size;
76 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -070077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 return -1;
79}
80
81static jlong android_os_ParcelFileDescriptor_seekTo(JNIEnv* env,
82 jobject clazz, jlong pos)
83{
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070084 jint fd = getFd(env, clazz);
85 if (fd < 0) {
86 jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
87 return -1;
88 }
Elliott Hughesa3804cf2011-04-11 16:50:19 -070089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 return lseek(fd, pos, SEEK_SET);
91}
92
Dianne Hackbornc9119f52011-02-28 18:03:26 -080093static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject clazz)
94{
95 jint fd = getFd(env, clazz);
96 if (fd < 0) {
97 jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
98 return -1;
99 }
100
101 return fd;
102}
103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104static const JNINativeMethod gParcelFileDescriptorMethods[] = {
Dianne Hackborn23fdaf62010-08-06 12:16:55 -0700105 {"createPipeNative", "([Ljava/io/FileDescriptor;)I",
106 (void*)android_os_ParcelFileDescriptor_createPipeNative},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 {"getStatSize", "()J",
108 (void*)android_os_ParcelFileDescriptor_getStatSize},
109 {"seekTo", "(J)J",
Dianne Hackbornc9119f52011-02-28 18:03:26 -0800110 (void*)android_os_ParcelFileDescriptor_seekTo},
111 {"getFdNative", "()I",
112 (void*)android_os_ParcelFileDescriptor_getFdNative}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113};
114
115const char* const kParcelFileDescriptorPathName = "android/os/ParcelFileDescriptor";
116
117int register_android_os_ParcelFileDescriptor(JNIEnv* env)
118{
Elliott Hughes43907582011-04-12 14:25:23 -0700119 jclass clazz = env->FindClass(kParcelFileDescriptorPathName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700121 gParcelFileDescriptorOffsets.mFileDescriptor = env->GetFieldID(clazz, "mFileDescriptor", "Ljava/io/FileDescriptor;");
122 LOG_FATAL_IF(gParcelFileDescriptorOffsets.mFileDescriptor == NULL,
123 "Unable to find mFileDescriptor field in android.os.ParcelFileDescriptor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124
125 return AndroidRuntime::registerNativeMethods(
126 env, kParcelFileDescriptorPathName,
127 gParcelFileDescriptorMethods, NELEM(gParcelFileDescriptorMethods));
128}
129
130}