blob: d8a3db3b93059d46bca454a463d07e68c930c85f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/libs/android_runtime/android_util_Process.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "FileUtils"
19
20#include <utils/Log.h>
21
22#include <android_runtime/AndroidRuntime.h>
23
24#include "JNIHelp.h"
25
26#include <sys/errno.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <fcntl.h>
30#include <signal.h>
31
32#if HAVE_ANDROID_OS
33#include <sys/ioctl.h>
34#include <linux/msdos_fs.h>
35#endif
36
37namespace android {
38
39static jclass gFileStatusClass;
40static jfieldID gFileStatusDevFieldID;
41static jfieldID gFileStatusInoFieldID;
42static jfieldID gFileStatusModeFieldID;
43static jfieldID gFileStatusNlinkFieldID;
44static jfieldID gFileStatusUidFieldID;
45static jfieldID gFileStatusGidFieldID;
46static jfieldID gFileStatusSizeFieldID;
47static jfieldID gFileStatusBlksizeFieldID;
48static jfieldID gFileStatusBlocksFieldID;
49static jfieldID gFileStatusAtimeFieldID;
50static jfieldID gFileStatusMtimeFieldID;
51static jfieldID gFileStatusCtimeFieldID;
52
53jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
54 jstring file, jint mode,
55 jint uid, jint gid)
56{
57 #if HAVE_ANDROID_OS
58 const jchar* str = env->GetStringCritical(file, 0);
59 String8 file8;
60 if (str) {
61 file8 = String8(str, env->GetStringLength(file));
62 env->ReleaseStringCritical(file, str);
63 }
64 if (file8.size() <= 0) {
65 return ENOENT;
66 }
67 if (uid >= 0 || gid >= 0) {
68 int res = chown(file8.string(), uid, gid);
69 if (res != 0) {
70 return errno;
71 }
72 }
73 return chmod(file8.string(), mode) == 0 ? 0 : errno;
74 #else
75 return ENOSYS;
76 #endif
77}
78
79jint android_os_FileUtils_getPermissions(JNIEnv* env, jobject clazz,
80 jstring file, jintArray outArray)
81{
82 #if HAVE_ANDROID_OS
83 const jchar* str = env->GetStringCritical(file, 0);
84 String8 file8;
85 if (str) {
86 file8 = String8(str, env->GetStringLength(file));
87 env->ReleaseStringCritical(file, str);
88 }
89 if (file8.size() <= 0) {
90 return ENOENT;
91 }
92 struct stat st;
93 if (stat(file8.string(), &st) != 0) {
94 return errno;
95 }
96 jint* array = (jint*)env->GetPrimitiveArrayCritical(outArray, 0);
97 if (array) {
98 int len = env->GetArrayLength(outArray);
99 if (len >= 1) {
100 array[0] = st.st_mode;
101 }
102 if (len >= 2) {
103 array[1] = st.st_uid;
104 }
105 if (len >= 3) {
106 array[2] = st.st_gid;
107 }
108 }
109 env->ReleasePrimitiveArrayCritical(outArray, array, 0);
110 return 0;
111 #else
112 return ENOSYS;
113 #endif
114}
115
Mike Lockwood90960e82010-08-06 09:15:25 -0400116jint android_os_FileUtils_setUMask(JNIEnv* env, jobject clazz, jint mask)
117{
118 return umask(mask);
119}
120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
122{
123 #if HAVE_ANDROID_OS
124 if (path == NULL) {
125 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
126 return -1;
127 }
128 const char *pathStr = env->GetStringUTFChars(path, NULL);
129 int result = -1;
130 // only if our system supports this ioctl
131 #ifdef VFAT_IOCTL_GET_VOLUME_ID
132 int fd = open(pathStr, O_RDONLY);
133 if (fd >= 0) {
134 result = ioctl(fd, VFAT_IOCTL_GET_VOLUME_ID);
135 close(fd);
136 }
137 #endif
138
139 env->ReleaseStringUTFChars(path, pathStr);
140 return result;
141 #else
142 return -1;
143 #endif
144}
145
146jboolean android_os_FileUtils_getFileStatus(JNIEnv* env, jobject clazz, jstring path, jobject fileStatus) {
147 const char* pathStr = env->GetStringUTFChars(path, NULL);
148 jboolean ret = false;
149
150 struct stat s;
151 int res = stat(pathStr, &s);
152 if (res == 0) {
153 ret = true;
154 if (fileStatus != NULL) {
155 env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
156 env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
157 env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
158 env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
159 env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
160 env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
161 env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
162 env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
163 env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
164 env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
165 env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
166 env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
167 }
168 }
169
170 env->ReleaseStringUTFChars(path, pathStr);
171
172 return ret;
173}
174
175static const JNINativeMethod methods[] = {
176 {"setPermissions", "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions},
177 {"getPermissions", "(Ljava/lang/String;[I)I", (void*)android_os_FileUtils_getPermissions},
Mike Lockwood90960e82010-08-06 09:15:25 -0400178 {"setUMask", "(I)I", (void*)android_os_FileUtils_setUMask},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 {"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId},
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800180 {"getFileStatusNative", "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z", (void*)android_os_FileUtils_getFileStatus},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181};
182
183static const char* const kFileUtilsPathName = "android/os/FileUtils";
184
185int register_android_os_FileUtils(JNIEnv* env)
186{
187 jclass clazz;
188
189 clazz = env->FindClass(kFileUtilsPathName);
190 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.FileUtils");
191
192 gFileStatusClass = env->FindClass("android/os/FileUtils$FileStatus");
193 LOG_FATAL_IF(gFileStatusClass == NULL, "Unable to find class android.os.FileUtils$FileStatus");
194
195 gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
196 gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
197 gFileStatusModeFieldID = env->GetFieldID(gFileStatusClass, "mode", "I");
198 gFileStatusNlinkFieldID = env->GetFieldID(gFileStatusClass, "nlink", "I");
199 gFileStatusUidFieldID = env->GetFieldID(gFileStatusClass, "uid", "I");
200 gFileStatusGidFieldID = env->GetFieldID(gFileStatusClass, "gid", "I");
201 gFileStatusSizeFieldID = env->GetFieldID(gFileStatusClass, "size", "J");
202 gFileStatusBlksizeFieldID = env->GetFieldID(gFileStatusClass, "blksize", "I");
203 gFileStatusBlocksFieldID = env->GetFieldID(gFileStatusClass, "blocks", "J");
204 gFileStatusAtimeFieldID = env->GetFieldID(gFileStatusClass, "atime", "J");
205 gFileStatusMtimeFieldID = env->GetFieldID(gFileStatusClass, "mtime", "J");
206 gFileStatusCtimeFieldID = env->GetFieldID(gFileStatusClass, "ctime", "J");
207
208 return AndroidRuntime::registerNativeMethods(
209 env, kFileUtilsPathName,
210 methods, NELEM(methods));
211}
212
213}