mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8054834: Modular Source Code
Co-authored-by: Alan Bateman <alan.bateman@oracle.com> Co-authored-by: Alex Buckley <alex.buckley@oracle.com> Co-authored-by: Erik Joelsson <erik.joelsson@oracle.com> Co-authored-by: Jonathan Gibbons <jonathan.gibbons@oracle.com> Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com> Co-authored-by: Magnus Ihse Bursie <magnus.ihse.bursie@oracle.com> Co-authored-by: Mandy Chung <mandy.chung@oracle.com> Co-authored-by: Mark Reinhold <mark.reinhold@oracle.com> Co-authored-by: Paul Sandoz <paul.sandoz@oracle.com> Reviewed-by: alanb, chegar, ihse, mduigou
This commit is contained in:
parent
d1c0417898
commit
3bc69d393d
12567 changed files with 5941 additions and 5903 deletions
|
@ -0,0 +1,533 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.nio.fs;
|
||||
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.*;
|
||||
import java.nio.file.spi.FileTypeDetector;
|
||||
import java.nio.channels.*;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.io.IOException;
|
||||
import java.io.FilePermission;
|
||||
import java.util.*;
|
||||
import java.security.AccessController;
|
||||
|
||||
import sun.nio.ch.ThreadPool;
|
||||
import sun.security.util.SecurityConstants;
|
||||
import static sun.nio.fs.UnixNativeDispatcher.*;
|
||||
import static sun.nio.fs.UnixConstants.*;
|
||||
|
||||
/**
|
||||
* Base implementation of FileSystemProvider
|
||||
*/
|
||||
|
||||
public abstract class UnixFileSystemProvider
|
||||
extends AbstractFileSystemProvider
|
||||
{
|
||||
private static final String USER_DIR = "user.dir";
|
||||
private final UnixFileSystem theFileSystem;
|
||||
|
||||
public UnixFileSystemProvider() {
|
||||
String userDir = System.getProperty(USER_DIR);
|
||||
theFileSystem = newFileSystem(userDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new file system using the given default directory.
|
||||
*/
|
||||
abstract UnixFileSystem newFileSystem(String dir);
|
||||
|
||||
@Override
|
||||
public final String getScheme() {
|
||||
return "file";
|
||||
}
|
||||
|
||||
private void checkUri(URI uri) {
|
||||
if (!uri.getScheme().equalsIgnoreCase(getScheme()))
|
||||
throw new IllegalArgumentException("URI does not match this provider");
|
||||
if (uri.getAuthority() != null)
|
||||
throw new IllegalArgumentException("Authority component present");
|
||||
if (uri.getPath() == null)
|
||||
throw new IllegalArgumentException("Path component is undefined");
|
||||
if (!uri.getPath().equals("/"))
|
||||
throw new IllegalArgumentException("Path component should be '/'");
|
||||
if (uri.getQuery() != null)
|
||||
throw new IllegalArgumentException("Query component present");
|
||||
if (uri.getFragment() != null)
|
||||
throw new IllegalArgumentException("Fragment component present");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final FileSystem newFileSystem(URI uri, Map<String,?> env) {
|
||||
checkUri(uri);
|
||||
throw new FileSystemAlreadyExistsException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final FileSystem getFileSystem(URI uri) {
|
||||
checkUri(uri);
|
||||
return theFileSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath(URI uri) {
|
||||
return UnixUriUtils.fromUri(theFileSystem, uri);
|
||||
}
|
||||
|
||||
UnixPath checkPath(Path obj) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException();
|
||||
if (!(obj instanceof UnixPath))
|
||||
throw new ProviderMismatchException();
|
||||
return (UnixPath)obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V extends FileAttributeView> V getFileAttributeView(Path obj,
|
||||
Class<V> type,
|
||||
LinkOption... options)
|
||||
{
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (type == BasicFileAttributeView.class)
|
||||
return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (type == PosixFileAttributeView.class)
|
||||
return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
|
||||
if (type == FileOwnerAttributeView.class)
|
||||
return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
|
||||
if (type == null)
|
||||
throw new NullPointerException();
|
||||
return (V) null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <A extends BasicFileAttributes> A readAttributes(Path file,
|
||||
Class<A> type,
|
||||
LinkOption... options)
|
||||
throws IOException
|
||||
{
|
||||
Class<? extends BasicFileAttributeView> view;
|
||||
if (type == BasicFileAttributes.class)
|
||||
view = BasicFileAttributeView.class;
|
||||
else if (type == PosixFileAttributes.class)
|
||||
view = PosixFileAttributeView.class;
|
||||
else if (type == null)
|
||||
throw new NullPointerException();
|
||||
else
|
||||
throw new UnsupportedOperationException();
|
||||
return (A) getFileAttributeView(file, view, options).readAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DynamicFileAttributeView getFileAttributeView(Path obj,
|
||||
String name,
|
||||
LinkOption... options)
|
||||
{
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (name.equals("basic"))
|
||||
return UnixFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (name.equals("posix"))
|
||||
return UnixFileAttributeViews.createPosixView(file, followLinks);
|
||||
if (name.equals("unix"))
|
||||
return UnixFileAttributeViews.createUnixView(file, followLinks);
|
||||
if (name.equals("owner"))
|
||||
return UnixFileAttributeViews.createOwnerView(file, followLinks);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileChannel newFileChannel(Path obj,
|
||||
Set<? extends OpenOption> options,
|
||||
FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
UnixPath file = checkPath(obj);
|
||||
int mode = UnixFileModeAttribute
|
||||
.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
|
||||
try {
|
||||
return UnixChannelFactory.newFileChannel(file, options, mode);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
|
||||
Set<? extends OpenOption> options,
|
||||
ExecutorService executor,
|
||||
FileAttribute<?>... attrs) throws IOException
|
||||
{
|
||||
UnixPath file = checkPath(obj);
|
||||
int mode = UnixFileModeAttribute
|
||||
.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
|
||||
ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
|
||||
try {
|
||||
return UnixChannelFactory
|
||||
.newAsynchronousFileChannel(file, options, mode, pool);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SeekableByteChannel newByteChannel(Path obj,
|
||||
Set<? extends OpenOption> options,
|
||||
FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
int mode = UnixFileModeAttribute
|
||||
.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
|
||||
try {
|
||||
return UnixChannelFactory.newFileChannel(file, options, mode);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file);
|
||||
return null; // keep compiler happy
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkDelete();
|
||||
|
||||
// need file attributes to know if file is directory
|
||||
UnixFileAttributes attrs = null;
|
||||
try {
|
||||
attrs = UnixFileAttributes.get(file, false);
|
||||
if (attrs.isDirectory()) {
|
||||
rmdir(file);
|
||||
} else {
|
||||
unlink(file);
|
||||
}
|
||||
return true;
|
||||
} catch (UnixException x) {
|
||||
// no-op if file does not exist
|
||||
if (!failIfNotExists && x.errno() == ENOENT)
|
||||
return false;
|
||||
|
||||
// DirectoryNotEmptyException if not empty
|
||||
if (attrs != null && attrs.isDirectory() &&
|
||||
(x.errno() == EEXIST || x.errno() == ENOTEMPTY))
|
||||
throw new DirectoryNotEmptyException(file.getPathForExceptionMessage());
|
||||
|
||||
x.rethrowAsIOException(file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(Path source, Path target, CopyOption... options)
|
||||
throws IOException
|
||||
{
|
||||
UnixCopyFile.copy(UnixPath.toUnixPath(source),
|
||||
UnixPath.toUnixPath(target),
|
||||
options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(Path source, Path target, CopyOption... options)
|
||||
throws IOException
|
||||
{
|
||||
UnixCopyFile.move(UnixPath.toUnixPath(source),
|
||||
UnixPath.toUnixPath(target),
|
||||
options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAccess(Path obj, AccessMode... modes) throws IOException {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
boolean e = false;
|
||||
boolean r = false;
|
||||
boolean w = false;
|
||||
boolean x = false;
|
||||
|
||||
if (modes.length == 0) {
|
||||
e = true;
|
||||
} else {
|
||||
for (AccessMode mode: modes) {
|
||||
switch (mode) {
|
||||
case READ : r = true; break;
|
||||
case WRITE : w = true; break;
|
||||
case EXECUTE : x = true; break;
|
||||
default: throw new AssertionError("Should not get here");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mode = 0;
|
||||
if (e || r) {
|
||||
file.checkRead();
|
||||
mode |= (r) ? R_OK : F_OK;
|
||||
}
|
||||
if (w) {
|
||||
file.checkWrite();
|
||||
mode |= W_OK;
|
||||
}
|
||||
if (x) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
// not cached
|
||||
sm.checkExec(file.getPathForPermissionCheck());
|
||||
}
|
||||
mode |= X_OK;
|
||||
}
|
||||
try {
|
||||
access(file, mode);
|
||||
} catch (UnixException exc) {
|
||||
exc.rethrowAsIOException(file);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameFile(Path obj1, Path obj2) throws IOException {
|
||||
UnixPath file1 = UnixPath.toUnixPath(obj1);
|
||||
if (file1.equals(obj2))
|
||||
return true;
|
||||
if (obj2 == null)
|
||||
throw new NullPointerException();
|
||||
if (!(obj2 instanceof UnixPath))
|
||||
return false;
|
||||
UnixPath file2 = (UnixPath)obj2;
|
||||
|
||||
// check security manager access to both files
|
||||
file1.checkRead();
|
||||
file2.checkRead();
|
||||
|
||||
UnixFileAttributes attrs1;
|
||||
UnixFileAttributes attrs2;
|
||||
try {
|
||||
attrs1 = UnixFileAttributes.get(file1, true);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file1);
|
||||
return false; // keep compiler happy
|
||||
}
|
||||
try {
|
||||
attrs2 = UnixFileAttributes.get(file2, true);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file2);
|
||||
return false; // keep compiler happy
|
||||
}
|
||||
return attrs1.isSameFile(attrs2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(Path obj) {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
file.checkRead();
|
||||
UnixPath name = file.getFileName();
|
||||
if (name == null)
|
||||
return false;
|
||||
return (name.asByteArray()[0] == '.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a FileStore to represent the file system where the given file
|
||||
* reside.
|
||||
*/
|
||||
abstract FileStore getFileStore(UnixPath path) throws IOException;
|
||||
|
||||
@Override
|
||||
public FileStore getFileStore(Path obj) throws IOException {
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
|
||||
file.checkRead();
|
||||
}
|
||||
return getFileStore(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createDirectory(Path obj, FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
UnixPath dir = UnixPath.toUnixPath(obj);
|
||||
dir.checkWrite();
|
||||
|
||||
int mode = UnixFileModeAttribute.toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
|
||||
try {
|
||||
mkdir(dir, mode);
|
||||
} catch (UnixException x) {
|
||||
if (x.errno() == EISDIR)
|
||||
throw new FileAlreadyExistsException(dir.toString());
|
||||
x.rethrowAsIOException(dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
|
||||
throws IOException
|
||||
{
|
||||
UnixPath dir = UnixPath.toUnixPath(obj);
|
||||
dir.checkRead();
|
||||
if (filter == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
// can't return SecureDirectoryStream on kernels that don't support openat
|
||||
// or O_NOFOLLOW
|
||||
if (!openatSupported() || O_NOFOLLOW == 0) {
|
||||
try {
|
||||
long ptr = opendir(dir);
|
||||
return new UnixDirectoryStream(dir, ptr, filter);
|
||||
} catch (UnixException x) {
|
||||
if (x.errno() == ENOTDIR)
|
||||
throw new NotDirectoryException(dir.getPathForExceptionMessage());
|
||||
x.rethrowAsIOException(dir);
|
||||
}
|
||||
}
|
||||
|
||||
// open directory and dup file descriptor for use by
|
||||
// opendir/readdir/closedir
|
||||
int dfd1 = -1;
|
||||
int dfd2 = -1;
|
||||
long dp = 0L;
|
||||
try {
|
||||
dfd1 = open(dir, O_RDONLY, 0);
|
||||
dfd2 = dup(dfd1);
|
||||
dp = fdopendir(dfd1);
|
||||
} catch (UnixException x) {
|
||||
if (dfd1 != -1)
|
||||
UnixNativeDispatcher.close(dfd1);
|
||||
if (dfd2 != -1)
|
||||
UnixNativeDispatcher.close(dfd2);
|
||||
if (x.errno() == UnixConstants.ENOTDIR)
|
||||
throw new NotDirectoryException(dir.getPathForExceptionMessage());
|
||||
x.rethrowAsIOException(dir);
|
||||
}
|
||||
return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
|
||||
throws IOException
|
||||
{
|
||||
UnixPath link = UnixPath.toUnixPath(obj1);
|
||||
UnixPath target = UnixPath.toUnixPath(obj2);
|
||||
|
||||
// no attributes supported when creating links
|
||||
if (attrs.length > 0) {
|
||||
UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE
|
||||
throw new UnsupportedOperationException("Initial file attributes" +
|
||||
"not supported when creating symbolic link");
|
||||
}
|
||||
|
||||
// permission check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new LinkPermission("symbolic"));
|
||||
link.checkWrite();
|
||||
}
|
||||
|
||||
// create link
|
||||
try {
|
||||
symlink(target.asByteArray(), link);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(link);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createLink(Path obj1, Path obj2) throws IOException {
|
||||
UnixPath link = UnixPath.toUnixPath(obj1);
|
||||
UnixPath existing = UnixPath.toUnixPath(obj2);
|
||||
|
||||
// permission check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new LinkPermission("hard"));
|
||||
link.checkWrite();
|
||||
existing.checkWrite();
|
||||
}
|
||||
try {
|
||||
link(existing, link);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(link, existing);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path readSymbolicLink(Path obj1) throws IOException {
|
||||
UnixPath link = UnixPath.toUnixPath(obj1);
|
||||
// permission check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
|
||||
SecurityConstants.FILE_READLINK_ACTION);
|
||||
sm.checkPermission(perm);
|
||||
}
|
||||
try {
|
||||
byte[] target = readlink(link);
|
||||
return new UnixPath(link.getFileSystem(), target);
|
||||
} catch (UnixException x) {
|
||||
if (x.errno() == UnixConstants.EINVAL)
|
||||
throw new NotLinkException(link.getPathForExceptionMessage());
|
||||
x.rethrowAsIOException(link);
|
||||
return null; // keep compiler happy
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code FileTypeDetector} for this platform.
|
||||
*/
|
||||
FileTypeDetector getFileTypeDetector() {
|
||||
return new AbstractFileTypeDetector() {
|
||||
@Override
|
||||
public String implProbeContentType(Path file) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code FileTypeDetector} that chains the given array of file
|
||||
* type detectors. When the {@code implProbeContentType} method is invoked
|
||||
* then each of the detectors is invoked in turn, the result from the
|
||||
* first to detect the file type is returned.
|
||||
*/
|
||||
final FileTypeDetector chain(final AbstractFileTypeDetector... detectors) {
|
||||
return new AbstractFileTypeDetector() {
|
||||
@Override
|
||||
protected String implProbeContentType(Path file) throws IOException {
|
||||
for (AbstractFileTypeDetector detector : detectors) {
|
||||
String result = detector.implProbeContentType(file);
|
||||
if (result != null && !result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue