Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java
41137 views
1
/*
2
* Copyright (c) 2008, 2021, 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
package sun.nio.fs;
27
28
import java.nio.file.*;
29
import java.nio.file.attribute.*;
30
import java.nio.file.spi.FileTypeDetector;
31
import java.nio.channels.*;
32
import java.net.URI;
33
import java.util.concurrent.ExecutorService;
34
import java.io.IOException;
35
import java.io.FilePermission;
36
import java.util.*;
37
38
import sun.nio.ch.ThreadPool;
39
import sun.security.util.SecurityConstants;
40
import static sun.nio.fs.UnixNativeDispatcher.*;
41
import static sun.nio.fs.UnixConstants.*;
42
43
/**
44
* Base implementation of FileSystemProvider
45
*/
46
47
public abstract class UnixFileSystemProvider
48
extends AbstractFileSystemProvider
49
{
50
private static final String USER_DIR = "user.dir";
51
private static final byte[] EMPTY_PATH = new byte[0];
52
private final UnixFileSystem theFileSystem;
53
54
public UnixFileSystemProvider() {
55
String userDir = System.getProperty(USER_DIR);
56
theFileSystem = newFileSystem(userDir);
57
}
58
59
UnixFileSystem theFileSystem() {
60
return theFileSystem;
61
}
62
63
/**
64
* Constructs a new file system using the given default directory.
65
*/
66
abstract UnixFileSystem newFileSystem(String dir);
67
68
@Override
69
public final String getScheme() {
70
return "file";
71
}
72
73
private void checkUri(URI uri) {
74
if (!uri.getScheme().equalsIgnoreCase(getScheme()))
75
throw new IllegalArgumentException("URI does not match this provider");
76
if (uri.getRawAuthority() != null)
77
throw new IllegalArgumentException("Authority component present");
78
String path = uri.getPath();
79
if (path == null)
80
throw new IllegalArgumentException("Path component is undefined");
81
if (!path.equals("/"))
82
throw new IllegalArgumentException("Path component should be '/'");
83
if (uri.getRawQuery() != null)
84
throw new IllegalArgumentException("Query component present");
85
if (uri.getRawFragment() != null)
86
throw new IllegalArgumentException("Fragment component present");
87
}
88
89
@Override
90
public final FileSystem newFileSystem(URI uri, Map<String,?> env) {
91
checkUri(uri);
92
throw new FileSystemAlreadyExistsException();
93
}
94
95
@Override
96
public final FileSystem getFileSystem(URI uri) {
97
checkUri(uri);
98
return theFileSystem;
99
}
100
101
@Override
102
public Path getPath(URI uri) {
103
return UnixUriUtils.fromUri(theFileSystem, uri);
104
}
105
106
UnixPath checkPath(Path obj) {
107
if (obj == null)
108
throw new NullPointerException();
109
if (!(obj instanceof UnixPath))
110
throw new ProviderMismatchException();
111
return (UnixPath)obj;
112
}
113
114
@Override
115
@SuppressWarnings("unchecked")
116
public <V extends FileAttributeView> V getFileAttributeView(Path obj,
117
Class<V> type,
118
LinkOption... options)
119
{
120
UnixPath file = UnixPath.toUnixPath(obj);
121
boolean followLinks = Util.followLinks(options);
122
if (type == BasicFileAttributeView.class)
123
return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
124
if (type == PosixFileAttributeView.class)
125
return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
126
if (type == FileOwnerAttributeView.class)
127
return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
128
if (type == null)
129
throw new NullPointerException();
130
return (V) null;
131
}
132
133
@Override
134
@SuppressWarnings("unchecked")
135
public <A extends BasicFileAttributes> A readAttributes(Path file,
136
Class<A> type,
137
LinkOption... options)
138
throws IOException
139
{
140
Class<? extends BasicFileAttributeView> view;
141
if (type == BasicFileAttributes.class)
142
view = BasicFileAttributeView.class;
143
else if (type == PosixFileAttributes.class)
144
view = PosixFileAttributeView.class;
145
else if (type == null)
146
throw new NullPointerException();
147
else
148
throw new UnsupportedOperationException();
149
return (A) getFileAttributeView(file, view, options).readAttributes();
150
}
151
152
@Override
153
protected DynamicFileAttributeView getFileAttributeView(Path obj,
154
String name,
155
LinkOption... options)
156
{
157
UnixPath file = UnixPath.toUnixPath(obj);
158
boolean followLinks = Util.followLinks(options);
159
if (name.equals("basic"))
160
return UnixFileAttributeViews.createBasicView(file, followLinks);
161
if (name.equals("posix"))
162
return UnixFileAttributeViews.createPosixView(file, followLinks);
163
if (name.equals("unix"))
164
return UnixFileAttributeViews.createUnixView(file, followLinks);
165
if (name.equals("owner"))
166
return UnixFileAttributeViews.createOwnerView(file, followLinks);
167
return null;
168
}
169
170
@Override
171
public FileChannel newFileChannel(Path obj,
172
Set<? extends OpenOption> options,
173
FileAttribute<?>... attrs)
174
throws IOException
175
{
176
UnixPath file = checkPath(obj);
177
int mode = UnixFileModeAttribute
178
.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
179
try {
180
return UnixChannelFactory.newFileChannel(file, options, mode);
181
} catch (UnixException x) {
182
x.rethrowAsIOException(file);
183
return null;
184
}
185
}
186
187
@Override
188
public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
189
Set<? extends OpenOption> options,
190
ExecutorService executor,
191
FileAttribute<?>... attrs) throws IOException
192
{
193
UnixPath file = checkPath(obj);
194
int mode = UnixFileModeAttribute
195
.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
196
ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
197
try {
198
return UnixChannelFactory
199
.newAsynchronousFileChannel(file, options, mode, pool);
200
} catch (UnixException x) {
201
x.rethrowAsIOException(file);
202
return null;
203
}
204
}
205
206
207
@Override
208
public SeekableByteChannel newByteChannel(Path obj,
209
Set<? extends OpenOption> options,
210
FileAttribute<?>... attrs)
211
throws IOException
212
{
213
UnixPath file = UnixPath.toUnixPath(obj);
214
int mode = UnixFileModeAttribute
215
.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
216
try {
217
return UnixChannelFactory.newFileChannel(file, options, mode);
218
} catch (UnixException x) {
219
x.rethrowAsIOException(file);
220
return null; // keep compiler happy
221
}
222
}
223
224
@Override
225
boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
226
UnixPath file = UnixPath.toUnixPath(obj);
227
file.checkDelete();
228
229
// need file attributes to know if file is directory
230
UnixFileAttributes attrs = null;
231
try {
232
attrs = UnixFileAttributes.get(file, false);
233
if (attrs.isDirectory()) {
234
rmdir(file);
235
} else {
236
unlink(file);
237
}
238
return true;
239
} catch (UnixException x) {
240
// no-op if file does not exist
241
if (!failIfNotExists && x.errno() == ENOENT)
242
return false;
243
244
// DirectoryNotEmptyException if not empty
245
if (attrs != null && attrs.isDirectory() &&
246
(x.errno() == EEXIST || x.errno() == ENOTEMPTY))
247
throw new DirectoryNotEmptyException(file.getPathForExceptionMessage());
248
249
x.rethrowAsIOException(file);
250
return false;
251
}
252
}
253
254
@Override
255
public void copy(Path source, Path target, CopyOption... options)
256
throws IOException
257
{
258
UnixCopyFile.copy(UnixPath.toUnixPath(source),
259
UnixPath.toUnixPath(target),
260
options);
261
}
262
263
@Override
264
public void move(Path source, Path target, CopyOption... options)
265
throws IOException
266
{
267
UnixCopyFile.move(UnixPath.toUnixPath(source),
268
UnixPath.toUnixPath(target),
269
options);
270
}
271
272
@Override
273
public void checkAccess(Path obj, AccessMode... modes) throws IOException {
274
UnixPath file = UnixPath.toUnixPath(obj);
275
boolean e = false;
276
boolean r = false;
277
boolean w = false;
278
boolean x = false;
279
280
if (modes.length == 0) {
281
e = true;
282
} else {
283
for (AccessMode mode: modes) {
284
switch (mode) {
285
case READ : r = true; break;
286
case WRITE : w = true; break;
287
case EXECUTE : x = true; break;
288
default: throw new AssertionError("Should not get here");
289
}
290
}
291
}
292
293
int mode = 0;
294
if (e || r) {
295
file.checkRead();
296
mode |= (r) ? R_OK : F_OK;
297
}
298
if (w) {
299
file.checkWrite();
300
mode |= W_OK;
301
}
302
if (x) {
303
@SuppressWarnings("removal")
304
SecurityManager sm = System.getSecurityManager();
305
if (sm != null) {
306
// not cached
307
sm.checkExec(file.getPathForPermissionCheck());
308
}
309
mode |= X_OK;
310
}
311
try {
312
access(file, mode);
313
} catch (UnixException exc) {
314
exc.rethrowAsIOException(file);
315
}
316
}
317
318
@Override
319
public boolean isSameFile(Path obj1, Path obj2) throws IOException {
320
UnixPath file1 = UnixPath.toUnixPath(obj1);
321
if (file1.equals(obj2))
322
return true;
323
if (obj2 == null)
324
throw new NullPointerException();
325
if (!(obj2 instanceof UnixPath))
326
return false;
327
UnixPath file2 = (UnixPath)obj2;
328
329
// check security manager access to both files
330
file1.checkRead();
331
file2.checkRead();
332
333
UnixFileAttributes attrs1;
334
UnixFileAttributes attrs2;
335
try {
336
attrs1 = UnixFileAttributes.get(file1, true);
337
} catch (UnixException x) {
338
x.rethrowAsIOException(file1);
339
return false; // keep compiler happy
340
}
341
try {
342
attrs2 = UnixFileAttributes.get(file2, true);
343
} catch (UnixException x) {
344
x.rethrowAsIOException(file2);
345
return false; // keep compiler happy
346
}
347
return attrs1.isSameFile(attrs2);
348
}
349
350
@Override
351
public boolean isHidden(Path obj) {
352
UnixPath file = UnixPath.toUnixPath(obj);
353
file.checkRead();
354
UnixPath name = file.getFileName();
355
if (name == null)
356
return false;
357
358
byte[] path;
359
if (name.isEmpty()) { // corner case for empty paths
360
path = name.getFileSystem().defaultDirectory();
361
} else {
362
path = name.asByteArray();
363
}
364
return path[0] == '.';
365
}
366
367
/**
368
* Returns a FileStore to represent the file system where the given file
369
* reside.
370
*/
371
abstract FileStore getFileStore(UnixPath path) throws IOException;
372
373
@Override
374
public FileStore getFileStore(Path obj) throws IOException {
375
UnixPath file = UnixPath.toUnixPath(obj);
376
@SuppressWarnings("removal")
377
SecurityManager sm = System.getSecurityManager();
378
if (sm != null) {
379
sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
380
file.checkRead();
381
}
382
return getFileStore(file);
383
}
384
385
@Override
386
public void createDirectory(Path obj, FileAttribute<?>... attrs)
387
throws IOException
388
{
389
UnixPath dir = UnixPath.toUnixPath(obj);
390
dir.checkWrite();
391
392
int mode = UnixFileModeAttribute.toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
393
try {
394
mkdir(dir, mode);
395
} catch (UnixException x) {
396
if (x.errno() == EISDIR)
397
throw new FileAlreadyExistsException(dir.toString());
398
x.rethrowAsIOException(dir);
399
}
400
}
401
402
403
@Override
404
public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
405
throws IOException
406
{
407
UnixPath dir = UnixPath.toUnixPath(obj);
408
dir.checkRead();
409
if (filter == null)
410
throw new NullPointerException();
411
412
// can't return SecureDirectoryStream on kernels that don't support openat
413
// or O_NOFOLLOW
414
if (!openatSupported() || O_NOFOLLOW == 0) {
415
try {
416
long ptr = opendir(dir);
417
return new UnixDirectoryStream(dir, ptr, filter);
418
} catch (UnixException x) {
419
if (x.errno() == ENOTDIR)
420
throw new NotDirectoryException(dir.getPathForExceptionMessage());
421
x.rethrowAsIOException(dir);
422
}
423
}
424
425
// open directory and dup file descriptor for use by
426
// opendir/readdir/closedir
427
int dfd1 = -1;
428
int dfd2 = -1;
429
long dp = 0L;
430
try {
431
dfd1 = open(dir, O_RDONLY, 0);
432
dfd2 = dup(dfd1);
433
dp = fdopendir(dfd1);
434
} catch (UnixException x) {
435
if (dfd1 != -1)
436
UnixNativeDispatcher.close(dfd1);
437
if (dfd2 != -1)
438
UnixNativeDispatcher.close(dfd2);
439
if (x.errno() == UnixConstants.ENOTDIR)
440
throw new NotDirectoryException(dir.getPathForExceptionMessage());
441
x.rethrowAsIOException(dir);
442
}
443
return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
444
}
445
446
@Override
447
public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
448
throws IOException
449
{
450
UnixPath link = UnixPath.toUnixPath(obj1);
451
UnixPath target = UnixPath.toUnixPath(obj2);
452
453
// no attributes supported when creating links
454
if (attrs.length > 0) {
455
UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE
456
throw new UnsupportedOperationException("Initial file attributes" +
457
"not supported when creating symbolic link");
458
}
459
460
// permission check
461
@SuppressWarnings("removal")
462
SecurityManager sm = System.getSecurityManager();
463
if (sm != null) {
464
sm.checkPermission(new LinkPermission("symbolic"));
465
link.checkWrite();
466
}
467
468
// create link
469
try {
470
symlink(target.asByteArray(), link);
471
} catch (UnixException x) {
472
x.rethrowAsIOException(link);
473
}
474
}
475
476
@Override
477
public void createLink(Path obj1, Path obj2) throws IOException {
478
UnixPath link = UnixPath.toUnixPath(obj1);
479
UnixPath existing = UnixPath.toUnixPath(obj2);
480
481
// permission check
482
@SuppressWarnings("removal")
483
SecurityManager sm = System.getSecurityManager();
484
if (sm != null) {
485
sm.checkPermission(new LinkPermission("hard"));
486
link.checkWrite();
487
existing.checkWrite();
488
}
489
try {
490
link(existing, link);
491
} catch (UnixException x) {
492
x.rethrowAsIOException(link, existing);
493
}
494
}
495
496
@Override
497
public Path readSymbolicLink(Path obj1) throws IOException {
498
UnixPath link = UnixPath.toUnixPath(obj1);
499
// permission check
500
@SuppressWarnings("removal")
501
SecurityManager sm = System.getSecurityManager();
502
if (sm != null) {
503
FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
504
SecurityConstants.FILE_READLINK_ACTION);
505
sm.checkPermission(perm);
506
}
507
try {
508
byte[] target = readlink(link);
509
return new UnixPath(link.getFileSystem(), target);
510
} catch (UnixException x) {
511
if (x.errno() == UnixConstants.EINVAL)
512
throw new NotLinkException(link.getPathForExceptionMessage());
513
x.rethrowAsIOException(link);
514
return null; // keep compiler happy
515
}
516
}
517
518
@Override
519
public final boolean isDirectory(Path obj) {
520
UnixPath file = UnixPath.toUnixPath(obj);
521
file.checkRead();
522
int mode = UnixNativeDispatcher.stat(file);
523
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);
524
}
525
526
@Override
527
public final boolean isRegularFile(Path obj) {
528
UnixPath file = UnixPath.toUnixPath(obj);
529
file.checkRead();
530
int mode = UnixNativeDispatcher.stat(file);
531
return ((mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);
532
}
533
534
@Override
535
public final boolean exists(Path obj) {
536
UnixPath file = UnixPath.toUnixPath(obj);
537
file.checkRead();
538
return UnixNativeDispatcher.exists(file);
539
}
540
541
/**
542
* Returns a {@code FileTypeDetector} for this platform.
543
*/
544
FileTypeDetector getFileTypeDetector() {
545
return new AbstractFileTypeDetector() {
546
@Override
547
public String implProbeContentType(Path file) {
548
return null;
549
}
550
};
551
}
552
553
/**
554
* Returns a {@code FileTypeDetector} that chains the given array of file
555
* type detectors. When the {@code implProbeContentType} method is invoked
556
* then each of the detectors is invoked in turn, the result from the
557
* first to detect the file type is returned.
558
*/
559
final FileTypeDetector chain(final AbstractFileTypeDetector... detectors) {
560
return new AbstractFileTypeDetector() {
561
@Override
562
protected String implProbeContentType(Path file) throws IOException {
563
for (AbstractFileTypeDetector detector : detectors) {
564
String result = detector.implProbeContentType(file);
565
if (result != null && !result.isEmpty()) {
566
return result;
567
}
568
}
569
return null;
570
}
571
};
572
}
573
574
@Override
575
public byte[] getSunPathForSocketFile(Path obj) {
576
UnixPath file = UnixPath.toUnixPath(obj);
577
if (file.isEmpty()) {
578
return EMPTY_PATH;
579
}
580
return file.getByteArrayForSysCalls();
581
}
582
}
583
584