Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
32288 views
/*1* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import java.nio.file.*;28import java.nio.file.attribute.*;29import java.nio.file.spi.FileTypeDetector;30import java.nio.channels.*;31import java.net.URI;32import java.util.concurrent.ExecutorService;33import java.io.IOException;34import java.io.FilePermission;35import java.util.*;36import java.security.AccessController;3738import sun.nio.ch.ThreadPool;39import sun.security.util.SecurityConstants;40import static sun.nio.fs.UnixNativeDispatcher.*;41import static sun.nio.fs.UnixConstants.*;4243/**44* Base implementation of FileSystemProvider45*/4647public abstract class UnixFileSystemProvider48extends AbstractFileSystemProvider49{50private static final String USER_DIR = "user.dir";51private final UnixFileSystem theFileSystem;5253public UnixFileSystemProvider() {54String userDir = System.getProperty(USER_DIR);55theFileSystem = newFileSystem(userDir);56}5758/**59* Constructs a new file system using the given default directory.60*/61abstract UnixFileSystem newFileSystem(String dir);6263@Override64public final String getScheme() {65return "file";66}6768private void checkUri(URI uri) {69if (!uri.getScheme().equalsIgnoreCase(getScheme()))70throw new IllegalArgumentException("URI does not match this provider");71if (uri.getAuthority() != null)72throw new IllegalArgumentException("Authority component present");73if (uri.getPath() == null)74throw new IllegalArgumentException("Path component is undefined");75if (!uri.getPath().equals("/"))76throw new IllegalArgumentException("Path component should be '/'");77if (uri.getQuery() != null)78throw new IllegalArgumentException("Query component present");79if (uri.getFragment() != null)80throw new IllegalArgumentException("Fragment component present");81}8283@Override84public final FileSystem newFileSystem(URI uri, Map<String,?> env) {85checkUri(uri);86throw new FileSystemAlreadyExistsException();87}8889@Override90public final FileSystem getFileSystem(URI uri) {91checkUri(uri);92return theFileSystem;93}9495@Override96public Path getPath(URI uri) {97return UnixUriUtils.fromUri(theFileSystem, uri);98}99100UnixPath checkPath(Path obj) {101if (obj == null)102throw new NullPointerException();103if (!(obj instanceof UnixPath))104throw new ProviderMismatchException();105return (UnixPath)obj;106}107108@Override109@SuppressWarnings("unchecked")110public <V extends FileAttributeView> V getFileAttributeView(Path obj,111Class<V> type,112LinkOption... options)113{114UnixPath file = UnixPath.toUnixPath(obj);115boolean followLinks = Util.followLinks(options);116if (type == BasicFileAttributeView.class)117return (V) UnixFileAttributeViews.createBasicView(file, followLinks);118if (type == PosixFileAttributeView.class)119return (V) UnixFileAttributeViews.createPosixView(file, followLinks);120if (type == FileOwnerAttributeView.class)121return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);122if (type == null)123throw new NullPointerException();124return (V) null;125}126127@Override128@SuppressWarnings("unchecked")129public <A extends BasicFileAttributes> A readAttributes(Path file,130Class<A> type,131LinkOption... options)132throws IOException133{134Class<? extends BasicFileAttributeView> view;135if (type == BasicFileAttributes.class)136view = BasicFileAttributeView.class;137else if (type == PosixFileAttributes.class)138view = PosixFileAttributeView.class;139else if (type == null)140throw new NullPointerException();141else142throw new UnsupportedOperationException();143return (A) getFileAttributeView(file, view, options).readAttributes();144}145146@Override147protected DynamicFileAttributeView getFileAttributeView(Path obj,148String name,149LinkOption... options)150{151UnixPath file = UnixPath.toUnixPath(obj);152boolean followLinks = Util.followLinks(options);153if (name.equals("basic"))154return UnixFileAttributeViews.createBasicView(file, followLinks);155if (name.equals("posix"))156return UnixFileAttributeViews.createPosixView(file, followLinks);157if (name.equals("unix"))158return UnixFileAttributeViews.createUnixView(file, followLinks);159if (name.equals("owner"))160return UnixFileAttributeViews.createOwnerView(file, followLinks);161return null;162}163164@Override165public FileChannel newFileChannel(Path obj,166Set<? extends OpenOption> options,167FileAttribute<?>... attrs)168throws IOException169{170UnixPath file = checkPath(obj);171int mode = UnixFileModeAttribute172.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);173try {174return UnixChannelFactory.newFileChannel(file, options, mode);175} catch (UnixException x) {176x.rethrowAsIOException(file);177return null;178}179}180181@Override182public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,183Set<? extends OpenOption> options,184ExecutorService executor,185FileAttribute<?>... attrs) throws IOException186{187UnixPath file = checkPath(obj);188int mode = UnixFileModeAttribute189.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);190ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);191try {192return UnixChannelFactory193.newAsynchronousFileChannel(file, options, mode, pool);194} catch (UnixException x) {195x.rethrowAsIOException(file);196return null;197}198}199200201@Override202public SeekableByteChannel newByteChannel(Path obj,203Set<? extends OpenOption> options,204FileAttribute<?>... attrs)205throws IOException206{207UnixPath file = UnixPath.toUnixPath(obj);208int mode = UnixFileModeAttribute209.toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);210try {211return UnixChannelFactory.newFileChannel(file, options, mode);212} catch (UnixException x) {213x.rethrowAsIOException(file);214return null; // keep compiler happy215}216}217218@Override219boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {220UnixPath file = UnixPath.toUnixPath(obj);221file.checkDelete();222223// need file attributes to know if file is directory224UnixFileAttributes attrs = null;225try {226attrs = UnixFileAttributes.get(file, false);227if (attrs.isDirectory()) {228rmdir(file);229} else {230unlink(file);231}232return true;233} catch (UnixException x) {234// no-op if file does not exist235if (!failIfNotExists && x.errno() == ENOENT)236return false;237238// DirectoryNotEmptyException if not empty239if (attrs != null && attrs.isDirectory() &&240(x.errno() == EEXIST || x.errno() == ENOTEMPTY))241throw new DirectoryNotEmptyException(file.getPathForExceptionMessage());242243x.rethrowAsIOException(file);244return false;245}246}247248@Override249public void copy(Path source, Path target, CopyOption... options)250throws IOException251{252UnixCopyFile.copy(UnixPath.toUnixPath(source),253UnixPath.toUnixPath(target),254options);255}256257@Override258public void move(Path source, Path target, CopyOption... options)259throws IOException260{261UnixCopyFile.move(UnixPath.toUnixPath(source),262UnixPath.toUnixPath(target),263options);264}265266@Override267public void checkAccess(Path obj, AccessMode... modes) throws IOException {268UnixPath file = UnixPath.toUnixPath(obj);269boolean e = false;270boolean r = false;271boolean w = false;272boolean x = false;273274if (modes.length == 0) {275e = true;276} else {277for (AccessMode mode: modes) {278switch (mode) {279case READ : r = true; break;280case WRITE : w = true; break;281case EXECUTE : x = true; break;282default: throw new AssertionError("Should not get here");283}284}285}286287int mode = 0;288if (e || r) {289file.checkRead();290mode |= (r) ? R_OK : F_OK;291}292if (w) {293file.checkWrite();294mode |= W_OK;295}296if (x) {297SecurityManager sm = System.getSecurityManager();298if (sm != null) {299// not cached300sm.checkExec(file.getPathForPermissionCheck());301}302mode |= X_OK;303}304try {305access(file, mode);306} catch (UnixException exc) {307exc.rethrowAsIOException(file);308}309}310311@Override312public boolean isSameFile(Path obj1, Path obj2) throws IOException {313UnixPath file1 = UnixPath.toUnixPath(obj1);314if (file1.equals(obj2))315return true;316if (obj2 == null)317throw new NullPointerException();318if (!(obj2 instanceof UnixPath))319return false;320UnixPath file2 = (UnixPath)obj2;321322// check security manager access to both files323file1.checkRead();324file2.checkRead();325326UnixFileAttributes attrs1;327UnixFileAttributes attrs2;328try {329attrs1 = UnixFileAttributes.get(file1, true);330} catch (UnixException x) {331x.rethrowAsIOException(file1);332return false; // keep compiler happy333}334try {335attrs2 = UnixFileAttributes.get(file2, true);336} catch (UnixException x) {337x.rethrowAsIOException(file2);338return false; // keep compiler happy339}340return attrs1.isSameFile(attrs2);341}342343@Override344public boolean isHidden(Path obj) {345UnixPath file = UnixPath.toUnixPath(obj);346file.checkRead();347UnixPath name = file.getFileName();348if (name == null)349return false;350return (name.asByteArray()[0] == '.');351}352353/**354* Returns a FileStore to represent the file system where the given file355* reside.356*/357abstract FileStore getFileStore(UnixPath path) throws IOException;358359@Override360public FileStore getFileStore(Path obj) throws IOException {361UnixPath file = UnixPath.toUnixPath(obj);362SecurityManager sm = System.getSecurityManager();363if (sm != null) {364sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));365file.checkRead();366}367return getFileStore(file);368}369370@Override371public void createDirectory(Path obj, FileAttribute<?>... attrs)372throws IOException373{374UnixPath dir = UnixPath.toUnixPath(obj);375dir.checkWrite();376377int mode = UnixFileModeAttribute.toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);378try {379mkdir(dir, mode);380} catch (UnixException x) {381if (x.errno() == EISDIR)382throw new FileAlreadyExistsException(dir.toString());383x.rethrowAsIOException(dir);384}385}386387388@Override389public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)390throws IOException391{392UnixPath dir = UnixPath.toUnixPath(obj);393dir.checkRead();394if (filter == null)395throw new NullPointerException();396397// can't return SecureDirectoryStream on kernels that don't support openat398// or O_NOFOLLOW399if (!openatSupported() || O_NOFOLLOW == 0) {400try {401long ptr = opendir(dir);402return new UnixDirectoryStream(dir, ptr, filter);403} catch (UnixException x) {404if (x.errno() == ENOTDIR)405throw new NotDirectoryException(dir.getPathForExceptionMessage());406x.rethrowAsIOException(dir);407}408}409410// open directory and dup file descriptor for use by411// opendir/readdir/closedir412int dfd1 = -1;413int dfd2 = -1;414long dp = 0L;415try {416dfd1 = open(dir, O_RDONLY, 0);417dfd2 = dup(dfd1);418dp = fdopendir(dfd1);419} catch (UnixException x) {420if (dfd1 != -1)421UnixNativeDispatcher.close(dfd1);422if (dfd2 != -1)423UnixNativeDispatcher.close(dfd2);424if (x.errno() == UnixConstants.ENOTDIR)425throw new NotDirectoryException(dir.getPathForExceptionMessage());426x.rethrowAsIOException(dir);427}428return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);429}430431@Override432public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)433throws IOException434{435UnixPath link = UnixPath.toUnixPath(obj1);436UnixPath target = UnixPath.toUnixPath(obj2);437438// no attributes supported when creating links439if (attrs.length > 0) {440UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE441throw new UnsupportedOperationException("Initial file attributes" +442"not supported when creating symbolic link");443}444445// permission check446SecurityManager sm = System.getSecurityManager();447if (sm != null) {448sm.checkPermission(new LinkPermission("symbolic"));449link.checkWrite();450}451452// create link453try {454symlink(target.asByteArray(), link);455} catch (UnixException x) {456x.rethrowAsIOException(link);457}458}459460@Override461public void createLink(Path obj1, Path obj2) throws IOException {462UnixPath link = UnixPath.toUnixPath(obj1);463UnixPath existing = UnixPath.toUnixPath(obj2);464465// permission check466SecurityManager sm = System.getSecurityManager();467if (sm != null) {468sm.checkPermission(new LinkPermission("hard"));469link.checkWrite();470existing.checkWrite();471}472try {473link(existing, link);474} catch (UnixException x) {475x.rethrowAsIOException(link, existing);476}477}478479@Override480public Path readSymbolicLink(Path obj1) throws IOException {481UnixPath link = UnixPath.toUnixPath(obj1);482// permission check483SecurityManager sm = System.getSecurityManager();484if (sm != null) {485FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),486SecurityConstants.FILE_READLINK_ACTION);487sm.checkPermission(perm);488}489try {490byte[] target = readlink(link);491return new UnixPath(link.getFileSystem(), target);492} catch (UnixException x) {493if (x.errno() == UnixConstants.EINVAL)494throw new NotLinkException(link.getPathForExceptionMessage());495x.rethrowAsIOException(link);496return null; // keep compiler happy497}498}499500/**501* Returns a {@code FileTypeDetector} for this platform.502*/503FileTypeDetector getFileTypeDetector() {504return new AbstractFileTypeDetector() {505@Override506public String implProbeContentType(Path file) {507return null;508}509};510}511512/**513* Returns a {@code FileTypeDetector} that chains the given array of file514* type detectors. When the {@code implProbeContentType} method is invoked515* then each of the detectors is invoked in turn, the result from the516* first to detect the file type is returned.517*/518final FileTypeDetector chain(final AbstractFileTypeDetector... detectors) {519return new AbstractFileTypeDetector() {520@Override521protected String implProbeContentType(Path file) throws IOException {522for (AbstractFileTypeDetector detector : detectors) {523String result = detector.implProbeContentType(file);524if (result != null && !result.isEmpty()) {525return result;526}527}528return null;529}530};531}532}533534535