src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java

Print this page

        

*** 25,49 **** package sun.nio.fs; import java.nio.file.*; import java.nio.file.attribute.*; - import java.nio.file.spi.FileSystemProvider; import java.nio.channels.*; import java.net.URI; import java.util.concurrent.ExecutorService; import java.io.IOException; import java.util.*; import sun.nio.ch.ThreadPool; /** * Base implementation of FileSystemProvider */ public abstract class UnixFileSystemProvider ! extends FileSystemProvider { private static final String USER_DIR = "user.dir"; private final UnixFileSystem theFileSystem; public UnixFileSystemProvider() { --- 25,53 ---- package sun.nio.fs; import java.nio.file.*; import java.nio.file.attribute.*; 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() {
*** 91,109 **** @Override public Path getPath(URI uri) { return UnixUriUtils.fromUri(theFileSystem, uri); } ! protected UnixPath checkPath(Path obj) { if (obj == null) throw new NullPointerException(); if (!(obj instanceof UnixPath)) throw new ProviderMismatchException(); return (UnixPath)obj; } @Override public FileChannel newFileChannel(Path obj, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException { --- 95,183 ---- @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; } + boolean followLinks(LinkOption... options) { + boolean followLinks = true; + for (LinkOption option: options) { + if (option == LinkOption.NOFOLLOW_LINKS) { + followLinks = false; + continue; + } + if (option == null) + throw new NullPointerException(); + throw new AssertionError("Should not get here"); + } + return followLinks; + } + @Override + @SuppressWarnings("unchecked") + public <V extends FileAttributeView> V getFileAttributeView(Path obj, + Class<V> type, + LinkOption... options) + { + UnixPath file = UnixPath.toUnixPath(obj); + boolean followLinks = 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 = 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 {
*** 134,139 **** --- 208,512 ---- } 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.getPathForExecptionMessage()); + + 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) { + 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, etc. + if (!supportsAtSysCalls()) { + try { + long ptr = opendir(dir); + return new UnixDirectoryStream(dir, ptr, filter); + } catch (UnixException x) { + if (x.errno() == ENOTDIR) + throw new NotDirectoryException(dir.getPathForExecptionMessage()); + 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.getPathForExecptionMessage()); + 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); + AccessController.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.getPathForExecptionMessage()); + x.rethrowAsIOException(link); + return null; // keep compiler happy + } + } }