Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/java/io/UnixFileSystem_md.c
32287 views
1
/*
2
* Copyright (c) 1998, 2017, 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
#ifndef MACOSX
212
rv = (jlong)sb.st_mtime * 1000;
213
rv += (jlong)sb.st_mtime_nsec / 1000000;
214
#else
215
rv = (jlong)sb.st_mtimespec.tv_sec * 1000;
216
rv += (jlong)sb.st_mtimespec.tv_nsec / 1000000;
217
#endif
218
}
219
} END_PLATFORM_STRING(env, path);
220
return rv;
221
}
222
223
224
JNIEXPORT jlong JNICALL
225
Java_java_io_UnixFileSystem_getLength(JNIEnv *env, jobject this,
226
jobject file)
227
{
228
jlong rv = 0;
229
230
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
231
struct stat64 sb;
232
if (stat64(path, &sb) == 0) {
233
rv = sb.st_size;
234
}
235
} END_PLATFORM_STRING(env, path);
236
return rv;
237
}
238
239
240
/* -- File operations -- */
241
242
243
JNIEXPORT jboolean JNICALL
244
Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls,
245
jstring pathname)
246
{
247
jboolean rv = JNI_FALSE;
248
249
WITH_PLATFORM_STRING(env, pathname, path) {
250
FD fd;
251
/* The root directory always exists */
252
if (strcmp (path, "/")) {
253
fd = handleOpen(path, O_RDWR | O_CREAT | O_EXCL, 0666);
254
if (fd < 0) {
255
if (errno != EEXIST)
256
JNU_ThrowIOExceptionWithLastError(env, path);
257
} else {
258
if (close(fd) == -1)
259
JNU_ThrowIOExceptionWithLastError(env, path);
260
rv = JNI_TRUE;
261
}
262
}
263
} END_PLATFORM_STRING(env, path);
264
return rv;
265
}
266
267
268
JNIEXPORT jboolean JNICALL
269
Java_java_io_UnixFileSystem_delete0(JNIEnv *env, jobject this,
270
jobject file)
271
{
272
jboolean rv = JNI_FALSE;
273
274
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
275
if (remove(path) == 0) {
276
rv = JNI_TRUE;
277
}
278
} END_PLATFORM_STRING(env, path);
279
return rv;
280
}
281
282
283
JNIEXPORT jobjectArray JNICALL
284
Java_java_io_UnixFileSystem_list(JNIEnv *env, jobject this,
285
jobject file)
286
{
287
DIR *dir = NULL;
288
struct dirent64 *ptr;
289
struct dirent64 *result;
290
int len, maxlen;
291
jobjectArray rv, old;
292
jclass str_class;
293
294
str_class = JNU_ClassString(env);
295
CHECK_NULL_RETURN(str_class, NULL);
296
297
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
298
dir = opendir(path);
299
} END_PLATFORM_STRING(env, path);
300
if (dir == NULL) return NULL;
301
302
ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));
303
if (ptr == NULL) {
304
JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
305
closedir(dir);
306
return NULL;
307
}
308
309
/* Allocate an initial String array */
310
len = 0;
311
maxlen = 16;
312
rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);
313
if (rv == NULL) goto error;
314
315
/* Scan the directory */
316
while ((readdir64_r(dir, ptr, &result) == 0) && (result != NULL)) {
317
jstring name;
318
if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
319
continue;
320
if (len == maxlen) {
321
old = rv;
322
rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);
323
if (rv == NULL) goto error;
324
if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
325
(*env)->DeleteLocalRef(env, old);
326
}
327
#ifdef MACOSX
328
name = newStringPlatform(env, ptr->d_name);
329
#else
330
name = JNU_NewStringPlatform(env, ptr->d_name);
331
#endif
332
if (name == NULL) goto error;
333
(*env)->SetObjectArrayElement(env, rv, len++, name);
334
(*env)->DeleteLocalRef(env, name);
335
}
336
closedir(dir);
337
free(ptr);
338
339
/* Copy the final results into an appropriately-sized array */
340
old = rv;
341
rv = (*env)->NewObjectArray(env, len, str_class, NULL);
342
if (rv == NULL) {
343
return NULL;
344
}
345
if (JNU_CopyObjectArray(env, rv, old, len) < 0) {
346
return NULL;
347
}
348
return rv;
349
350
error:
351
closedir(dir);
352
free(ptr);
353
return NULL;
354
}
355
356
357
JNIEXPORT jboolean JNICALL
358
Java_java_io_UnixFileSystem_createDirectory(JNIEnv *env, jobject this,
359
jobject file)
360
{
361
jboolean rv = JNI_FALSE;
362
363
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
364
if (mkdir(path, 0777) == 0) {
365
rv = JNI_TRUE;
366
}
367
} END_PLATFORM_STRING(env, path);
368
return rv;
369
}
370
371
372
JNIEXPORT jboolean JNICALL
373
Java_java_io_UnixFileSystem_rename0(JNIEnv *env, jobject this,
374
jobject from, jobject to)
375
{
376
jboolean rv = JNI_FALSE;
377
378
WITH_FIELD_PLATFORM_STRING(env, from, ids.path, fromPath) {
379
WITH_FIELD_PLATFORM_STRING(env, to, ids.path, toPath) {
380
if (rename(fromPath, toPath) == 0) {
381
rv = JNI_TRUE;
382
}
383
} END_PLATFORM_STRING(env, toPath);
384
} END_PLATFORM_STRING(env, fromPath);
385
return rv;
386
}
387
388
JNIEXPORT jboolean JNICALL
389
Java_java_io_UnixFileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
390
jobject file, jlong time)
391
{
392
jboolean rv = JNI_FALSE;
393
394
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
395
struct stat64 sb;
396
397
if (stat64(path, &sb) == 0) {
398
struct timeval tv[2];
399
400
/* Preserve access time */
401
#ifndef MACOSX
402
tv[0].tv_sec = sb.st_atime;
403
tv[0].tv_usec = sb.st_atime_nsec / 1000;
404
#else
405
tv[0].tv_sec = sb.st_atimespec.tv_sec;
406
tv[0].tv_usec = sb.st_atimespec.tv_nsec / 1000;
407
#endif
408
409
/* Change last-modified time */
410
tv[1].tv_sec = time / 1000;
411
tv[1].tv_usec = (time % 1000) * 1000;
412
413
if (utimes(path, tv) == 0)
414
rv = JNI_TRUE;
415
}
416
} END_PLATFORM_STRING(env, path);
417
418
return rv;
419
}
420
421
422
JNIEXPORT jboolean JNICALL
423
Java_java_io_UnixFileSystem_setReadOnly(JNIEnv *env, jobject this,
424
jobject file)
425
{
426
jboolean rv = JNI_FALSE;
427
428
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
429
int mode;
430
if (statMode(path, &mode)) {
431
if (chmod(path, mode & ~(S_IWUSR | S_IWGRP | S_IWOTH)) >= 0) {
432
rv = JNI_TRUE;
433
}
434
}
435
} END_PLATFORM_STRING(env, path);
436
return rv;
437
}
438
439
JNIEXPORT jlong JNICALL
440
Java_java_io_UnixFileSystem_getSpace(JNIEnv *env, jobject this,
441
jobject file, jint t)
442
{
443
jlong rv = 0L;
444
445
WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
446
struct statvfs64 fsstat;
447
memset(&fsstat, 0, sizeof(fsstat));
448
if (statvfs64(path, &fsstat) == 0) {
449
switch(t) {
450
case java_io_FileSystem_SPACE_TOTAL:
451
rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
452
long_to_jlong(fsstat.f_blocks));
453
break;
454
case java_io_FileSystem_SPACE_FREE:
455
rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
456
long_to_jlong(fsstat.f_bfree));
457
break;
458
case java_io_FileSystem_SPACE_USABLE:
459
rv = jlong_mul(long_to_jlong(fsstat.f_frsize),
460
long_to_jlong(fsstat.f_bavail));
461
break;
462
default:
463
assert(0);
464
}
465
}
466
} END_PLATFORM_STRING(env, path);
467
return rv;
468
}
469
470