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