Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-aarch32-jdk8u
Path: blob/jdk8u272-b10-aarch32-20201026/jdk/src/solaris/native/java/io/UnixFileSystem_md.c
48795 views
1
/*
2
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include <assert.h>
27
#include <sys/types.h>
28
#include <sys/time.h>
29
#include <sys/stat.h>
30
#include <sys/statvfs.h>
31
#include <string.h>
32
#include <stdlib.h>
33
#include <dlfcn.h>
34
#include <limits.h>
35
36
#include "jni.h"
37
#include "jni_util.h"
38
#include "jlong.h"
39
#include "jvm.h"
40
#include "io_util.h"
41
#include "io_util_md.h"
42
#include "java_io_FileSystem.h"
43
#include "java_io_UnixFileSystem.h"
44
45
#if defined(_ALLBSD_SOURCE)
46
#define dirent64 dirent
47
#define readdir64_r readdir_r
48
#define stat64 stat
49
#define statvfs64 statvfs
50
#endif
51
52
/* -- Field IDs -- */
53
54
static struct {
55
jfieldID path;
56
} ids;
57
58
59
JNIEXPORT void JNICALL
60
Java_java_io_UnixFileSystem_initIDs(JNIEnv *env, jclass cls)
61
{
62
jclass fileClass = (*env)->FindClass(env, "java/io/File");
63
if (!fileClass) return;
64
ids.path = (*env)->GetFieldID(env, fileClass,
65
"path", "Ljava/lang/String;");
66
}
67
68
/* -- Path operations -- */
69
70
extern int canonicalize(char *path, const char *out, int len);
71
72
JNIEXPORT jstring JNICALL
73
Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this,
74
jstring pathname)
75
{
76
jstring rv = NULL;
77
78
WITH_PLATFORM_STRING(env, pathname, path) {
79
char canonicalPath[JVM_MAXPATHLEN];
80
if (canonicalize((char *)path,
81
canonicalPath, JVM_MAXPATHLEN) < 0) {
82
JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
83
} else {
84
#ifdef MACOSX
85
rv = newStringPlatform(env, canonicalPath);
86
#else
87
rv = JNU_NewStringPlatform(env, canonicalPath);
88
#endif
89
}
90
} END_PLATFORM_STRING(env, path);
91
return rv;
92
}
93
94
95
/* -- Attribute accessors -- */
96
97
98
static jboolean
99
statMode(const char *path, int *mode)
100
{
101
struct stat64 sb;
102
if (stat64(path, &sb) == 0) {
103
*mode = sb.st_mode;
104
return JNI_TRUE;
105
}
106
return JNI_FALSE;
107
}
108
109
110
JNIEXPORT jint JNICALL
111
Java_java_io_UnixFileSystem_getBooleanAttributes0(JNIEnv *env, jobject this,
112
jobject file)
113
{
114
jint rv = 0;
115
116
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
117
int mode;
118
if (statMode(path, &mode)) {
119
int fmt = mode & S_IFMT;
120
rv = (jint) (java_io_FileSystem_BA_EXISTS
121
| ((fmt == S_IFREG) ? java_io_FileSystem_BA_REGULAR : 0)
122
| ((fmt == S_IFDIR) ? java_io_FileSystem_BA_DIRECTORY : 0));
123
}
124
} END_PLATFORM_STRING(env, path);
125
return rv;
126
}
127
128
JNIEXPORT jboolean JNICALL
129
Java_java_io_UnixFileSystem_checkAccess(JNIEnv *env, jobject this,
130
jobject file, jint a)
131
{
132
jboolean rv = JNI_FALSE;
133
int mode = 0;
134
switch (a) {
135
case java_io_FileSystem_ACCESS_READ:
136
mode = R_OK;
137
break;
138
case java_io_FileSystem_ACCESS_WRITE:
139
mode = W_OK;
140
break;
141
case java_io_FileSystem_ACCESS_EXECUTE:
142
mode = X_OK;
143
break;
144
default: assert(0);
145
}
146
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
147
if (access(path, mode) == 0) {
148
rv = JNI_TRUE;
149
}
150
} END_PLATFORM_STRING(env, path);
151
return rv;
152
}
153
154
155
JNIEXPORT jboolean JNICALL
156
Java_java_io_UnixFileSystem_setPermission(JNIEnv *env, jobject this,
157
jobject file,
158
jint access,
159
jboolean enable,
160
jboolean owneronly)
161
{
162
jboolean rv = JNI_FALSE;
163
164
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
165
int amode = 0;
166
int mode;
167
switch (access) {
168
case java_io_FileSystem_ACCESS_READ:
169
if (owneronly)
170
amode = S_IRUSR;
171
else
172
amode = S_IRUSR | S_IRGRP | S_IROTH;
173
break;
174
case java_io_FileSystem_ACCESS_WRITE:
175
if (owneronly)
176
amode = S_IWUSR;
177
else
178
amode = S_IWUSR | S_IWGRP | S_IWOTH;
179
break;
180
case java_io_FileSystem_ACCESS_EXECUTE:
181
if (owneronly)
182
amode = S_IXUSR;
183
else
184
amode = S_IXUSR | S_IXGRP | S_IXOTH;
185
break;
186
default:
187
assert(0);
188
}
189
if (statMode(path, &mode)) {
190
if (enable)
191
mode |= amode;
192
else
193
mode &= ~amode;
194
if (chmod(path, mode) >= 0) {
195
rv = JNI_TRUE;
196
}
197
}
198
} END_PLATFORM_STRING(env, path);
199
return rv;
200
}
201
202
JNIEXPORT jlong JNICALL
203
Java_java_io_UnixFileSystem_getLastModifiedTime(JNIEnv *env, jobject this,
204
jobject file)
205
{
206
jlong rv = 0;
207
208
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
209
struct stat64 sb;
210
if (stat64(path, &sb) == 0) {
211
rv = 1000 * (jlong)sb.st_mtime;
212
}
213
} END_PLATFORM_STRING(env, path);
214
return rv;
215
}
216
217
218
JNIEXPORT jlong JNICALL
219
Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,
220
jobject file)
221
{
222
jlong rv = 0;
223
224
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
225
struct stat64 sb;
226
if (stat64(path, &sb) == 0) {
227
rv = sb.st_size;
228
}
229
} END_PLATFORM_STRING(env, path);
230
return rv;
231
}
232
233
234
/* -- File operations -- */
235
236
237
JNIEXPORT jboolean JNICALL
238
Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls,
239
jstring pathname)
240
{
241
jboolean rv = JNI_FALSE;
242
243
WITH_PLATFORM_STRING(env, pathname, path) {
244
FD fd;
245
/* The root directory always exists */
246
if (strcmp (path, "/")) {
247
fd = handleOpen(path, O_RDWR | O_CREAT | O_EXCL, 0666);
248
if (fd < 0) {
249
if (errno != EEXIST)
250
JNU_ThrowIOExceptionWithLastError(env, path);
251
} else {
252
if (close(fd) == -1)
253
JNU_ThrowIOExceptionWithLastError(env, path);
254
rv = JNI_TRUE;
255
}
256
}
257
} END_PLATFORM_STRING(env, path);
258
return rv;
259
}
260
261
262
JNIEXPORT jboolean JNICALL
263
Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,
264
jobject file)
265
{
266
jboolean rv = JNI_FALSE;
267
268
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
269
if (remove(path) == 0) {
270
rv = JNI_TRUE;
271
}
272
} END_PLATFORM_STRING(env, path);
273
return rv;
274
}
275
276
277
JNIEXPORT jobjectArray JNICALL
278
Java_java_io_UnixFileSystem_list(JNIEnv *env, jobject this,
279
jobject file)
280
{
281
DIR *dir = NULL;
282
struct dirent64 *ptr;
283
struct dirent64 *result;
284
int len, maxlen;
285
jobjectArray rv, old;
286
jclass str_class;
287
288
str_class = JNU_ClassString(env);
289
CHECK_NULL_RETURN(str_class, NULL);
290
291
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
292
dir = opendir(path);
293
} END_PLATFORM_STRING(env, path);
294
if (dir == NULL) return NULL;
295
296
ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));
297
if (ptr == NULL) {
298
JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
299
closedir(dir);
300
return NULL;
301
}
302
303
/* Allocate an initial String array */
304
len = 0;
305
maxlen = 16;
306
rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);
307
if (rv == NULL) goto error;
308
309
/* Scan the directory */
310
while ((readdir64_r(dir, ptr, &result) == 0) && (result != NULL)) {
311
jstring name;
312
if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
313
continue;
314
if (len == maxlen) {
315
old = rv;
316
rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);
317
if (rv == NULL) goto error;
318
if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
319
(*env)->DeleteLocalRef(env, old);
320
}
321
#ifdef MACOSX
322
name = newStringPlatform(env, ptr->d_name);
323
#else
324
name = JNU_NewStringPlatform(env, ptr->d_name);
325
#endif
326
if (name == NULL) goto error;
327
(*env)->SetObjectArrayElement(env, rv, len++, name);
328
(*env)->DeleteLocalRef(env, name);
329
}
330
closedir(dir);
331
free(ptr);
332
333
/* Copy the final results into an appropriately-sized array */
334
old = rv;
335
rv = (*env)->NewObjectArray(env, len, str_class, NULL);
336
if (rv == NULL) {
337
return NULL;
338
}
339
if (JNU_CopyObjectArray(env, rv, old, len) < 0) {
340
return NULL;
341
}
342
return rv;
343
344
error:
345
closedir(dir);
346
free(ptr);
347
return NULL;
348
}
349
350
351
JNIEXPORT jboolean JNICALL
352
Java_java_io_UnixFileSystem_createDirectory(JNIEnv *env, jobject this,
353
jobject file)
354
{
355
jboolean rv = JNI_FALSE;
356
357
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
358
if (mkdir(path, 0777) == 0) {
359
rv = JNI_TRUE;
360
}
361
} END_PLATFORM_STRING(env, path);
362
return rv;
363
}
364
365
366
JNIEXPORT jboolean JNICALL
367
Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
368
jobject from, jobject to)
369
{
370
jboolean rv = JNI_FALSE;
371
372
WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {
373
WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {
374
if (rename(fromPath, toPath) == 0) {
375
rv = JNI_TRUE;
376
}
377
} END_PLATFORM_STRING(env, toPath);
378
} END_PLATFORM_STRING(env, fromPath);
379
return rv;
380
}
381
382
JNIEXPORT jboolean JNICALL
383
Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
384
jobject file, jlong time)
385
{
386
jboolean rv = JNI_FALSE;
387
388
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
389
struct stat64 sb;
390
391
if (stat64(path, &sb) == 0) {
392
struct timeval tv[2];
393
394
/* Preserve access time */
395
tv[0].tv_sec = sb.st_atime;
396
tv[0].tv_usec = 0;
397
398
/* Change last-modified time */
399
tv[1].tv_sec = time / 1000;
400
tv[1].tv_usec = (time % 1000) * 1000;
401
402
if (utimes(path, tv) == 0)
403
rv = JNI_TRUE;
404
}
405
} END_PLATFORM_STRING(env, path);
406
407
return rv;
408
}
409
410
411
JNIEXPORT jboolean JNICALL
412
Java_java_io_UnixFileSystem_setReadOnly(JNIEnv *env, jobject this,
413
jobject file)
414
{
415
jboolean rv = JNI_FALSE;
416
417
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
418
int mode;
419
if (statMode(path, &mode)) {
420
if (chmod(path, mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)) >= 0) {
421
rv = JNI_TRUE;
422
}
423
}
424
} END_PLATFORM_STRING(env, path);
425
return rv;
426
}
427
428
JNIEXPORT jlong JNICALL
429
Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,
430
jobject file, jint t)
431
{
432
jlong rv = 0L;
433
434
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
435
struct statvfs64 fsstat;
436
memset(&fsstat, 0, sizeof(fsstat));
437
if (statvfs64(path, &fsstat) == 0) {
438
switch(t) {
439
case java_io_FileSystem_SPACE_TOTAL:
440
rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
441
long_to_jlong(fsstat.f_blocks));
442
break;
443
case java_io_FileSystem_SPACE_FREE:
444
rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
445
long_to_jlong(fsstat.f_bfree));
446
break;
447
case java_io_FileSystem_SPACE_USABLE:
448
rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
449
long_to_jlong(fsstat.f_bavail));
450
break;
451
default:
452
assert(0);
453
}
454
}
455
} END_PLATFORM_STRING(env, path);
456
return rv;
457
}
458
459