• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2007, 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  */
16 
17 #if INCLUDE_SYS_MOUNT_FOR_STATFS
18 #include <sys/mount.h>
19 #else
20 #include <sys/statfs.h>
21 #endif
22 
23 #include <errno.h>
24 
25 #include "jni.h"
26 #include "JNIHelp.h"
27 #include "android_runtime/AndroidRuntime.h"
28 
29 
30 namespace android
31 {
32 
33 // ----------------------------------------------------------------------------
34 
35 struct fields_t {
36     jfieldID    context;
37 };
38 static fields_t fields;
39 
40 // ----------------------------------------------------------------------------
41 
42 static jint
android_os_StatFs_getBlockSize(JNIEnv * env,jobject thiz)43 android_os_StatFs_getBlockSize(JNIEnv *env, jobject thiz)
44 {
45     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
46     return stat->f_bsize;
47 }
48 
49 static jint
android_os_StatFs_getBlockCount(JNIEnv * env,jobject thiz)50 android_os_StatFs_getBlockCount(JNIEnv *env, jobject thiz)
51 {
52     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
53     return stat->f_blocks;
54 }
55 
56 static jint
android_os_StatFs_getFreeBlocks(JNIEnv * env,jobject thiz)57 android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz)
58 {
59     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
60     return stat->f_bfree;
61 }
62 
63 static jint
android_os_StatFs_getAvailableBlocks(JNIEnv * env,jobject thiz)64 android_os_StatFs_getAvailableBlocks(JNIEnv *env, jobject thiz)
65 {
66     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
67     return stat->f_bavail;
68 }
69 
70 static void
android_os_StatFs_native_restat(JNIEnv * env,jobject thiz,jstring path)71 android_os_StatFs_native_restat(JNIEnv *env, jobject thiz, jstring path)
72 {
73     if (path == NULL) {
74         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
75         return;
76     }
77 
78     // get the object handle
79     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
80     if (stat == NULL) {
81         jniThrowException(env, "java/lang/NoSuchFieldException", NULL);
82         return;
83     }
84 
85     const char* pathstr = env->GetStringUTFChars(path, NULL);
86     if (pathstr == NULL) {
87         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
88         return;
89     }
90 
91     // note that stat will contain the new file data corresponding to
92     // pathstr
93     if (statfs(pathstr, stat) != 0) {
94         LOGE("statfs %s failed, errno: %d", pathstr, errno);
95         delete stat;
96         env->SetIntField(thiz, fields.context, 0);
97         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
98     }
99     // Release pathstr
100     env->ReleaseStringUTFChars(path, pathstr);
101 }
102 
103 static void
android_os_StatFs_native_setup(JNIEnv * env,jobject thiz,jstring path)104 android_os_StatFs_native_setup(JNIEnv *env, jobject thiz, jstring path)
105 {
106     if (path == NULL) {
107         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
108         return;
109     }
110 
111     struct statfs* stat = new struct statfs;
112     if (stat == NULL) {
113         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
114         return;
115     }
116     env->SetIntField(thiz, fields.context, (int)stat);
117     android_os_StatFs_native_restat(env, thiz, path);
118 }
119 
120 static void
android_os_StatFs_native_finalize(JNIEnv * env,jobject thiz)121 android_os_StatFs_native_finalize(JNIEnv *env, jobject thiz)
122 {
123     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
124     if (stat != NULL) {
125         delete stat;
126         env->SetIntField(thiz, fields.context, 0);
127     }
128 }
129 
130 // ----------------------------------------------------------------------------
131 
132 static JNINativeMethod gMethods[] = {
133     {"getBlockSize",       "()I",                       (void *)android_os_StatFs_getBlockSize},
134     {"getBlockCount",      "()I",                       (void *)android_os_StatFs_getBlockCount},
135     {"getFreeBlocks",      "()I",                       (void *)android_os_StatFs_getFreeBlocks},
136     {"getAvailableBlocks", "()I",                       (void *)android_os_StatFs_getAvailableBlocks},
137     {"native_setup",       "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_setup},
138     {"native_finalize",    "()V",                       (void *)android_os_StatFs_native_finalize},
139     {"native_restat",      "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_restat},
140 };
141 
142 
register_android_os_StatFs(JNIEnv * env)143 int register_android_os_StatFs(JNIEnv *env)
144 {
145     jclass clazz;
146 
147     clazz = env->FindClass("android/os/StatFs");
148     if (clazz == NULL) {
149         LOGE("Can't find android/os/StatFs");
150         return -1;
151     }
152 
153     fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
154     if (fields.context == NULL) {
155         LOGE("Can't find StatFs.mNativeContext");
156         return -1;
157     }
158 
159     return AndroidRuntime::registerNativeMethods(env,
160             "android/os/StatFs", gMethods, NELEM(gMethods));
161 }
162 
163 }   // namespace android
164