blob: 89dce8987364cacfb3f635dd2391aebbec1dbe75 [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**
Elliott Hughesdd66bcb2011-04-12 11:28:59 -07005** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Elliott Hughesdd66bcb2011-04-12 11:28:59 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Elliott Hughesdd66bcb2011-04-12 11:28:59 -070011** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039static jfieldID gFileStatusDevFieldID;
40static jfieldID gFileStatusInoFieldID;
41static jfieldID gFileStatusModeFieldID;
42static jfieldID gFileStatusNlinkFieldID;
43static jfieldID gFileStatusUidFieldID;
44static jfieldID gFileStatusGidFieldID;
45static jfieldID gFileStatusSizeFieldID;
46static jfieldID gFileStatusBlksizeFieldID;
47static jfieldID gFileStatusBlocksFieldID;
48static jfieldID gFileStatusAtimeFieldID;
49static jfieldID gFileStatusMtimeFieldID;
50static jfieldID gFileStatusCtimeFieldID;
51
52jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
53 jstring file, jint mode,
54 jint uid, jint gid)
55{
56 #if HAVE_ANDROID_OS
57 const jchar* str = env->GetStringCritical(file, 0);
58 String8 file8;
59 if (str) {
60 file8 = String8(str, env->GetStringLength(file));
61 env->ReleaseStringCritical(file, str);
62 }
63 if (file8.size() <= 0) {
64 return ENOENT;
65 }
66 if (uid >= 0 || gid >= 0) {
67 int res = chown(file8.string(), uid, gid);
68 if (res != 0) {
69 return errno;
70 }
71 }
72 return chmod(file8.string(), mode) == 0 ? 0 : errno;
73 #else
74 return ENOSYS;
75 #endif
76}
77
78jint android_os_FileUtils_getPermissions(JNIEnv* env, jobject clazz,
79 jstring file, jintArray outArray)
80{
81 #if HAVE_ANDROID_OS
82 const jchar* str = env->GetStringCritical(file, 0);
83 String8 file8;
84 if (str) {
85 file8 = String8(str, env->GetStringLength(file));
86 env->ReleaseStringCritical(file, str);
87 }
88 if (file8.size() <= 0) {
89 return ENOENT;
90 }
91 struct stat st;
92 if (stat(file8.string(), &st) != 0) {
93 return errno;
94 }
95 jint* array = (jint*)env->GetPrimitiveArrayCritical(outArray, 0);
96 if (array) {
97 int len = env->GetArrayLength(outArray);
98 if (len >= 1) {
99 array[0] = st.st_mode;
100 }
101 if (len >= 2) {
102 array[1] = st.st_uid;
103 }
104 if (len >= 3) {
105 array[2] = st.st_gid;
106 }
107 }
108 env->ReleasePrimitiveArrayCritical(outArray, array, 0);
109 return 0;
110 #else
111 return ENOSYS;
112 #endif
113}
114
Mike Lockwood90960e82010-08-06 09:15:25 -0400115jint android_os_FileUtils_setUMask(JNIEnv* env, jobject clazz, jint mask)
116{
117 return umask(mask);
118}
119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
121{
122 #if HAVE_ANDROID_OS
123 if (path == NULL) {
124 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
125 return -1;
126 }
127 const char *pathStr = env->GetStringUTFChars(path, NULL);
128 int result = -1;
129 // only if our system supports this ioctl
130 #ifdef VFAT_IOCTL_GET_VOLUME_ID
131 int fd = open(pathStr, O_RDONLY);
132 if (fd >= 0) {
133 result = ioctl(fd, VFAT_IOCTL_GET_VOLUME_ID);
134 close(fd);
135 }
136 #endif
137
138 env->ReleaseStringUTFChars(path, pathStr);
139 return result;
140 #else
141 return -1;
142 #endif
143}
144
145jboolean android_os_FileUtils_getFileStatus(JNIEnv* env, jobject clazz, jstring path, jobject fileStatus) {
146 const char* pathStr = env->GetStringUTFChars(path, NULL);
147 jboolean ret = false;
Elliott Hughesdd66bcb2011-04-12 11:28:59 -0700148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 struct stat s;
150 int res = stat(pathStr, &s);
151 if (res == 0) {
152 ret = true;
153 if (fileStatus != NULL) {
154 env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
155 env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
156 env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
157 env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
158 env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
159 env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
160 env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
161 env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
162 env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
163 env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
164 env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
165 env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
166 }
167 }
Elliott Hughesdd66bcb2011-04-12 11:28:59 -0700168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 env->ReleaseStringUTFChars(path, pathStr);
Elliott Hughesdd66bcb2011-04-12 11:28:59 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 return ret;
172}
173
174static const JNINativeMethod methods[] = {
175 {"setPermissions", "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions},
176 {"getPermissions", "(Ljava/lang/String;[I)I", (void*)android_os_FileUtils_getPermissions},
Mike Lockwood90960e82010-08-06 09:15:25 -0400177 {"setUMask", "(I)I", (void*)android_os_FileUtils_setUMask},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 {"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId},
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800179 {"getFileStatusNative", "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z", (void*)android_os_FileUtils_getFileStatus},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180};
181
182static const char* const kFileUtilsPathName = "android/os/FileUtils";
183
184int register_android_os_FileUtils(JNIEnv* env)
185{
Carl Shapirob16f7692011-03-03 14:04:56 -0800186 jclass fileStatusClass = env->FindClass("android/os/FileUtils$FileStatus");
187 LOG_FATAL_IF(fileStatusClass == NULL, "Unable to find class android.os.FileUtils$FileStatus");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
Carl Shapirob16f7692011-03-03 14:04:56 -0800189 gFileStatusDevFieldID = env->GetFieldID(fileStatusClass, "dev", "I");
190 gFileStatusInoFieldID = env->GetFieldID(fileStatusClass, "ino", "I");
191 gFileStatusModeFieldID = env->GetFieldID(fileStatusClass, "mode", "I");
192 gFileStatusNlinkFieldID = env->GetFieldID(fileStatusClass, "nlink", "I");
193 gFileStatusUidFieldID = env->GetFieldID(fileStatusClass, "uid", "I");
194 gFileStatusGidFieldID = env->GetFieldID(fileStatusClass, "gid", "I");
195 gFileStatusSizeFieldID = env->GetFieldID(fileStatusClass, "size", "J");
196 gFileStatusBlksizeFieldID = env->GetFieldID(fileStatusClass, "blksize", "I");
197 gFileStatusBlocksFieldID = env->GetFieldID(fileStatusClass, "blocks", "J");
198 gFileStatusAtimeFieldID = env->GetFieldID(fileStatusClass, "atime", "J");
199 gFileStatusMtimeFieldID = env->GetFieldID(fileStatusClass, "mtime", "J");
200 gFileStatusCtimeFieldID = env->GetFieldID(fileStatusClass, "ctime", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201
202 return AndroidRuntime::registerNativeMethods(
203 env, kFileUtilsPathName,
204 methods, NELEM(methods));
205}
206
207}