diff -r 115e09b7a004 -r 3acf8e5e2ca0 jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java Sun Feb 15 12:25:54 2009 +0000 @@ -0,0 +1,380 @@ +/* + * Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.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.*; +import java.io.IOException; +import java.util.*; +import java.util.regex.Pattern; +import java.security.AccessController; +import sun.security.action.GetPropertyAction; + +/** + * Base implementation of FileSystem for Unix-like implementations. + */ + +abstract class UnixFileSystem + extends FileSystem +{ + private final UnixFileSystemProvider provider; + private final byte[] defaultDirectory; + private final boolean needToResolveAgainstDefaultDirectory; + private final UnixPath rootDirectory; + + // package-private + UnixFileSystem(UnixFileSystemProvider provider, String dir) { + this.provider = provider; + this.defaultDirectory = UnixPath.normalizeAndCheck(dir).getBytes(); + if (this.defaultDirectory[0] != '/') { + throw new RuntimeException("default directory must be absolute"); + } + + // if process-wide chdir is allowed or default directory is not the + // process working directory then paths must be resolved against the + // default directory. + String propValue = AccessController.doPrivileged( + new GetPropertyAction("sun.nio.fs.chdirAllowed", "false")); + boolean chdirAllowed = (propValue.length() == 0) ? + true : Boolean.valueOf(propValue); + if (chdirAllowed) { + this.needToResolveAgainstDefaultDirectory = true; + } else { + byte[] cwd = UnixNativeDispatcher.getcwd(); + boolean defaultIsCwd = (cwd.length == defaultDirectory.length); + if (defaultIsCwd) { + for (int i=0; i getRootDirectories() { + final List allowedList = + Collections.unmodifiableList(Arrays.asList((Path)rootDirectory)); + return new Iterable() { + public Iterator iterator() { + try { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkRead(rootDirectory.toString()); + return allowedList.iterator(); + } catch (SecurityException x) { + List disallowed = Collections.emptyList(); + return disallowed.iterator(); + } + } + }; + } + + /** + * Returns object to iterate over entries in mounttab or equivalent + */ + abstract Iterable getMountEntries(); + + /** + * Returns a FileStore to represent the file system where the given file + * reside. + */ + abstract FileStore getFileStore(UnixPath path) throws IOException; + + /** + * Returns a FileStore to represent the file system for the given mount + * mount. + */ + abstract FileStore getFileStore(UnixMountEntry entry) throws IOException; + + /** + * Iterator returned by getFileStores method. + */ + private class FileStoreIterator implements Iterator { + private final Iterator entries; + private FileStore next; + + FileStoreIterator() { + this.entries = getMountEntries().iterator(); + } + + private FileStore readNext() { + assert Thread.holdsLock(this); + for (;;) { + if (!entries.hasNext()) + return null; + UnixMountEntry entry = entries.next(); + + // skip entries with the "ignore" option + if (entry.isIgnored()) + continue; + + // check permission to read mount point + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + try { + sm.checkRead(new String(entry.dir())); + } catch (SecurityException x) { + continue; + } + } + try { + return getFileStore(entry); + } catch (IOException ignore) { + // ignore as per spec + } + } + } + + @Override + public synchronized boolean hasNext() { + if (next != null) + return true; + next = readNext(); + return next != null; + } + + @Override + public synchronized FileStore next() { + if (next == null) + next = readNext(); + if (next == null) { + throw new NoSuchElementException(); + } else { + FileStore result = next; + next = null; + return result; + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + @Override + public final Iterable getFileStores() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + try { + sm.checkPermission(new RuntimePermission("getFileStoreAttributes")); + } catch (SecurityException se) { + return Collections.emptyList(); + } + } + return new Iterable() { + public Iterator iterator() { + return new FileStoreIterator(); + } + }; + } + + @Override + public final UnixPath getPath(String path) { + return new UnixPath(this, path); + } + + @Override + public PathMatcher getPathMatcher(String syntaxAndInput) { + int pos = syntaxAndInput.indexOf(':'); + if (pos <= 0 || pos == syntaxAndInput.length()) + throw new IllegalArgumentException(); + String syntax = syntaxAndInput.substring(0, pos); + String input = syntaxAndInput.substring(pos+1); + + String expr; + if (syntax.equals(GLOB_SYNTAX)) { + expr = Globs.toUnixRegexPattern(input); + } else { + if (syntax.equals(REGEX_SYNTAX)) { + expr = input; + } else { + throw new UnsupportedOperationException("Syntax '" + syntax + + "' not recognized"); + } + } + + // return matcher + final Pattern pattern = Pattern.compile(expr); + return new PathMatcher() { + @Override + public boolean matches(Path path) { + return pattern.matcher(path.toString()).matches(); + } + }; + } + private static final String GLOB_SYNTAX = "glob"; + private static final String REGEX_SYNTAX = "regex"; + + protected 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; + } + + @SuppressWarnings("unchecked") + protected V newFileAttributeView(Class view, + UnixPath file, + LinkOption... options) + { + if (view == null) + throw new NullPointerException(); + boolean followLinks = followLinks(options); + Class c = view; + if (c == BasicFileAttributeView.class) + return (V) UnixFileAttributeViews.createBasicView(file, followLinks); + if (c == PosixFileAttributeView.class) + return (V) UnixFileAttributeViews.createPosixView(file, followLinks); + if (c == FileOwnerAttributeView.class) + return (V) UnixFileAttributeViews.createOwnerView(file, followLinks); + return (V) null; + } + + static List standardFileAttributeViews() { + return Arrays.asList("basic", "posix", "unix", "owner"); + } + + protected FileAttributeView newFileAttributeView(String name, + UnixPath file, + LinkOption... options) + { + 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 final UserPrincipalLookupService getUserPrincipalLookupService() { + return theLookupService; + } + + private static final UserPrincipalLookupService theLookupService = + new UserPrincipalLookupService() { + @Override + public UserPrincipal lookupPrincipalByName(String name) + throws IOException + { + return UnixUserPrincipals.lookupUser(name); + } + + @Override + public GroupPrincipal lookupPrincipalByGroupName(String group) + throws IOException + { + return UnixUserPrincipals.lookupGroup(group); + } + }; +}