jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
changeset 8158 77d9c0f1c19f
parent 5506 202f599c92aa
child 9035 1255eb81cc2f
child 9025 a72fc1fc4b71
equal deleted inserted replaced
7988:d31b7cc371ef 8158:77d9c0f1c19f
    25 
    25 
    26 package sun.nio.fs;
    26 package sun.nio.fs;
    27 
    27 
    28 import java.nio.file.*;
    28 import java.nio.file.*;
    29 import java.nio.file.attribute.*;
    29 import java.nio.file.attribute.*;
    30 import java.nio.file.spi.FileSystemProvider;
       
    31 import java.nio.channels.*;
    30 import java.nio.channels.*;
    32 import java.net.URI;
    31 import java.net.URI;
    33 import java.util.concurrent.ExecutorService;
    32 import java.util.concurrent.ExecutorService;
    34 import java.io.IOException;
    33 import java.io.IOException;
       
    34 import java.io.FilePermission;
    35 import java.util.*;
    35 import java.util.*;
       
    36 import java.security.AccessController;
    36 
    37 
    37 import sun.nio.ch.ThreadPool;
    38 import sun.nio.ch.ThreadPool;
       
    39 import sun.security.util.SecurityConstants;
       
    40 import static sun.nio.fs.UnixNativeDispatcher.*;
       
    41 import static sun.nio.fs.UnixConstants.*;
    38 
    42 
    39 /**
    43 /**
    40  * Base implementation of FileSystemProvider
    44  * Base implementation of FileSystemProvider
    41  */
    45  */
    42 
    46 
    43 public abstract class UnixFileSystemProvider
    47 public abstract class UnixFileSystemProvider
    44     extends FileSystemProvider
    48     extends AbstractFileSystemProvider
    45 {
    49 {
    46     private static final String USER_DIR = "user.dir";
    50     private static final String USER_DIR = "user.dir";
    47     private final UnixFileSystem theFileSystem;
    51     private final UnixFileSystem theFileSystem;
    48 
    52 
    49     public UnixFileSystemProvider() {
    53     public UnixFileSystemProvider() {
    91     @Override
    95     @Override
    92     public Path getPath(URI uri) {
    96     public Path getPath(URI uri) {
    93         return UnixUriUtils.fromUri(theFileSystem, uri);
    97         return UnixUriUtils.fromUri(theFileSystem, uri);
    94     }
    98     }
    95 
    99 
    96     protected UnixPath checkPath(Path obj) {
   100     UnixPath checkPath(Path obj) {
    97         if (obj == null)
   101         if (obj == null)
    98             throw new NullPointerException();
   102             throw new NullPointerException();
    99         if (!(obj instanceof UnixPath))
   103         if (!(obj instanceof UnixPath))
   100             throw new ProviderMismatchException();
   104             throw new ProviderMismatchException();
   101         return (UnixPath)obj;
   105         return (UnixPath)obj;
   102     }
   106     }
   103 
   107 
       
   108     boolean followLinks(LinkOption... options) {
       
   109         boolean followLinks = true;
       
   110         for (LinkOption option: options) {
       
   111             if (option == LinkOption.NOFOLLOW_LINKS) {
       
   112                 followLinks = false;
       
   113                 continue;
       
   114             }
       
   115             if (option == null)
       
   116                 throw new NullPointerException();
       
   117             throw new AssertionError("Should not get here");
       
   118         }
       
   119         return followLinks;
       
   120     }
       
   121 
       
   122     @Override
       
   123     @SuppressWarnings("unchecked")
       
   124     public <V extends FileAttributeView> V getFileAttributeView(Path obj,
       
   125                                                                 Class<V> type,
       
   126                                                                 LinkOption... options)
       
   127     {
       
   128         UnixPath file = UnixPath.toUnixPath(obj);
       
   129         boolean followLinks =  followLinks(options);
       
   130         if (type == BasicFileAttributeView.class)
       
   131             return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
       
   132         if (type == PosixFileAttributeView.class)
       
   133             return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
       
   134         if (type == FileOwnerAttributeView.class)
       
   135             return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
       
   136         if (type == null)
       
   137             throw new NullPointerException();
       
   138         return (V) null;
       
   139     }
       
   140 
       
   141     @Override
       
   142     @SuppressWarnings("unchecked")
       
   143     public <A extends BasicFileAttributes> A readAttributes(Path file,
       
   144                                                                Class<A> type,
       
   145                                                                LinkOption... options)
       
   146         throws IOException
       
   147     {
       
   148         Class<? extends BasicFileAttributeView> view;
       
   149         if (type == BasicFileAttributes.class)
       
   150             view = BasicFileAttributeView.class;
       
   151         else if (type == PosixFileAttributes.class)
       
   152             view = PosixFileAttributeView.class;
       
   153         else if (type == null)
       
   154             throw new NullPointerException();
       
   155         else
       
   156             throw new UnsupportedOperationException();
       
   157         return (A) getFileAttributeView(file, view, options).readAttributes();
       
   158     }
       
   159 
       
   160     @Override
       
   161     protected DynamicFileAttributeView getFileAttributeView(Path obj,
       
   162                                                             String name,
       
   163                                                             LinkOption... options)
       
   164     {
       
   165         UnixPath file = UnixPath.toUnixPath(obj);
       
   166         boolean followLinks = followLinks(options);
       
   167         if (name.equals("basic"))
       
   168             return UnixFileAttributeViews.createBasicView(file, followLinks);
       
   169         if (name.equals("posix"))
       
   170             return UnixFileAttributeViews.createPosixView(file, followLinks);
       
   171         if (name.equals("unix"))
       
   172             return UnixFileAttributeViews.createUnixView(file, followLinks);
       
   173         if (name.equals("owner"))
       
   174             return UnixFileAttributeViews.createOwnerView(file, followLinks);
       
   175         return null;
       
   176     }
       
   177 
   104     @Override
   178     @Override
   105     public FileChannel newFileChannel(Path obj,
   179     public FileChannel newFileChannel(Path obj,
   106                                       Set<? extends OpenOption> options,
   180                                       Set<? extends OpenOption> options,
   107                                       FileAttribute<?>... attrs)
   181                                       FileAttribute<?>... attrs)
   108         throws IOException
   182         throws IOException
   134         } catch (UnixException x) {
   208         } catch (UnixException x) {
   135             x.rethrowAsIOException(file);
   209             x.rethrowAsIOException(file);
   136             return null;
   210             return null;
   137         }
   211         }
   138     }
   212     }
       
   213 
       
   214 
       
   215     @Override
       
   216     public SeekableByteChannel newByteChannel(Path obj,
       
   217                                               Set<? extends OpenOption> options,
       
   218                                               FileAttribute<?>... attrs)
       
   219          throws IOException
       
   220     {
       
   221         UnixPath file = UnixPath.toUnixPath(obj);
       
   222         int mode = UnixFileModeAttribute
       
   223             .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
       
   224         try {
       
   225             return UnixChannelFactory.newFileChannel(file, options, mode);
       
   226         } catch (UnixException x) {
       
   227             x.rethrowAsIOException(file);
       
   228             return null;  // keep compiler happy
       
   229         }
       
   230     }
       
   231 
       
   232     @Override
       
   233     boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
       
   234         UnixPath file = UnixPath.toUnixPath(obj);
       
   235         file.checkDelete();
       
   236 
       
   237         // need file attributes to know if file is directory
       
   238         UnixFileAttributes attrs = null;
       
   239         try {
       
   240             attrs = UnixFileAttributes.get(file, false);
       
   241             if (attrs.isDirectory()) {
       
   242                 rmdir(file);
       
   243             } else {
       
   244                 unlink(file);
       
   245             }
       
   246             return true;
       
   247         } catch (UnixException x) {
       
   248             // no-op if file does not exist
       
   249             if (!failIfNotExists && x.errno() == ENOENT)
       
   250                 return false;
       
   251 
       
   252             // DirectoryNotEmptyException if not empty
       
   253             if (attrs != null && attrs.isDirectory() &&
       
   254                 (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
       
   255                 throw new DirectoryNotEmptyException(file.getPathForExecptionMessage());
       
   256 
       
   257             x.rethrowAsIOException(file);
       
   258             return false;
       
   259         }
       
   260     }
       
   261 
       
   262     @Override
       
   263     public void copy(Path source, Path target, CopyOption... options)
       
   264         throws IOException
       
   265     {
       
   266         UnixCopyFile.copy(UnixPath.toUnixPath(source),
       
   267                           UnixPath.toUnixPath(target),
       
   268                           options);
       
   269     }
       
   270 
       
   271     @Override
       
   272     public void move(Path source, Path target, CopyOption... options)
       
   273         throws IOException
       
   274     {
       
   275         UnixCopyFile.move(UnixPath.toUnixPath(source),
       
   276                           UnixPath.toUnixPath(target),
       
   277                           options);
       
   278     }
       
   279 
       
   280     @Override
       
   281     public void checkAccess(Path obj, AccessMode... modes) throws IOException {
       
   282         UnixPath file = UnixPath.toUnixPath(obj);
       
   283         boolean e = false;
       
   284         boolean r = false;
       
   285         boolean w = false;
       
   286         boolean x = false;
       
   287 
       
   288         if (modes.length == 0) {
       
   289             e = true;
       
   290         } else {
       
   291             for (AccessMode mode: modes) {
       
   292                 switch (mode) {
       
   293                     case READ : r = true; break;
       
   294                     case WRITE : w = true; break;
       
   295                     case EXECUTE : x = true; break;
       
   296                     default: throw new AssertionError("Should not get here");
       
   297                 }
       
   298             }
       
   299         }
       
   300 
       
   301         int mode = 0;
       
   302         if (e || r) {
       
   303             file.checkRead();
       
   304             mode |= (r) ? R_OK : F_OK;
       
   305         }
       
   306         if (w) {
       
   307             file.checkWrite();
       
   308             mode |= W_OK;
       
   309         }
       
   310         if (x) {
       
   311             SecurityManager sm = System.getSecurityManager();
       
   312             if (sm != null) {
       
   313                 // not cached
       
   314                 sm.checkExec(file.getPathForPermissionCheck());
       
   315             }
       
   316             mode |= X_OK;
       
   317         }
       
   318         try {
       
   319             access(file, mode);
       
   320         } catch (UnixException exc) {
       
   321             exc.rethrowAsIOException(file);
       
   322         }
       
   323     }
       
   324 
       
   325     @Override
       
   326     public boolean isSameFile(Path obj1, Path obj2) throws IOException {
       
   327         UnixPath file1 = UnixPath.toUnixPath(obj1);
       
   328         if (file1.equals(obj2))
       
   329             return true;
       
   330         if (obj2 == null)
       
   331             throw new NullPointerException();
       
   332         if (!(obj2 instanceof UnixPath))
       
   333             return false;
       
   334         UnixPath file2 = (UnixPath)obj2;
       
   335 
       
   336         // check security manager access to both files
       
   337         file1.checkRead();
       
   338         file2.checkRead();
       
   339 
       
   340         UnixFileAttributes attrs1;
       
   341         UnixFileAttributes attrs2;
       
   342         try {
       
   343              attrs1 = UnixFileAttributes.get(file1, true);
       
   344         } catch (UnixException x) {
       
   345             x.rethrowAsIOException(file1);
       
   346             return false;    // keep compiler happy
       
   347         }
       
   348         try {
       
   349             attrs2 = UnixFileAttributes.get(file2, true);
       
   350         } catch (UnixException x) {
       
   351             x.rethrowAsIOException(file2);
       
   352             return false;    // keep compiler happy
       
   353         }
       
   354         return attrs1.isSameFile(attrs2);
       
   355     }
       
   356 
       
   357     @Override
       
   358     public boolean isHidden(Path obj) {
       
   359         UnixPath file = UnixPath.toUnixPath(obj);
       
   360         file.checkRead();
       
   361         UnixPath name = file.getFileName();
       
   362         if (name == null)
       
   363             return false;
       
   364         return (name.asByteArray()[0] == '.');
       
   365     }
       
   366 
       
   367     /**
       
   368      * Returns a FileStore to represent the file system where the given file
       
   369      * reside.
       
   370      */
       
   371     abstract FileStore getFileStore(UnixPath path) throws IOException;
       
   372 
       
   373     @Override
       
   374     public FileStore getFileStore(Path obj) throws IOException {
       
   375         UnixPath file = UnixPath.toUnixPath(obj);
       
   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
       
   392             .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
       
   393         try {
       
   394             mkdir(dir, mode);
       
   395         } catch (UnixException x) {
       
   396             x.rethrowAsIOException(dir);
       
   397         }
       
   398     }
       
   399 
       
   400 
       
   401     @Override
       
   402     public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
       
   403         throws IOException
       
   404     {
       
   405         UnixPath dir = UnixPath.toUnixPath(obj);
       
   406         dir.checkRead();
       
   407         if (filter == null)
       
   408             throw new NullPointerException();
       
   409 
       
   410         // can't return SecureDirectoryStream on kernels that don't support
       
   411         // openat, etc.
       
   412         if (!supportsAtSysCalls()) {
       
   413             try {
       
   414                 long ptr = opendir(dir);
       
   415                 return new UnixDirectoryStream(dir, ptr, filter);
       
   416             } catch (UnixException x) {
       
   417                 if (x.errno() == ENOTDIR)
       
   418                     throw new NotDirectoryException(dir.getPathForExecptionMessage());
       
   419                 x.rethrowAsIOException(dir);
       
   420             }
       
   421         }
       
   422 
       
   423         // open directory and dup file descriptor for use by
       
   424         // opendir/readdir/closedir
       
   425         int dfd1 = -1;
       
   426         int dfd2 = -1;
       
   427         long dp = 0L;
       
   428         try {
       
   429             dfd1 = open(dir, O_RDONLY, 0);
       
   430             dfd2 = dup(dfd1);
       
   431             dp = fdopendir(dfd1);
       
   432         } catch (UnixException x) {
       
   433             if (dfd1 != -1)
       
   434                 UnixNativeDispatcher.close(dfd1);
       
   435             if (dfd2 != -1)
       
   436                 UnixNativeDispatcher.close(dfd2);
       
   437             if (x.errno() == UnixConstants.ENOTDIR)
       
   438                 throw new NotDirectoryException(dir.getPathForExecptionMessage());
       
   439             x.rethrowAsIOException(dir);
       
   440         }
       
   441         return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
       
   442     }
       
   443 
       
   444     @Override
       
   445     public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
       
   446         throws IOException
       
   447     {
       
   448         UnixPath link = UnixPath.toUnixPath(obj1);
       
   449         UnixPath target = UnixPath.toUnixPath(obj2);
       
   450 
       
   451         // no attributes supported when creating links
       
   452         if (attrs.length > 0) {
       
   453             UnixFileModeAttribute.toUnixMode(0, attrs);  // may throw NPE or UOE
       
   454             throw new UnsupportedOperationException("Initial file attributes" +
       
   455                 "not supported when creating symbolic link");
       
   456         }
       
   457 
       
   458         // permission check
       
   459         SecurityManager sm = System.getSecurityManager();
       
   460         if (sm != null) {
       
   461             sm.checkPermission(new LinkPermission("symbolic"));
       
   462             link.checkWrite();
       
   463         }
       
   464 
       
   465         // create link
       
   466         try {
       
   467             symlink(target.asByteArray(), link);
       
   468         } catch (UnixException x) {
       
   469             x.rethrowAsIOException(link);
       
   470         }
       
   471     }
       
   472 
       
   473     @Override
       
   474     public void createLink(Path obj1, Path obj2) throws IOException {
       
   475         UnixPath link = UnixPath.toUnixPath(obj1);
       
   476         UnixPath existing = UnixPath.toUnixPath(obj2);
       
   477 
       
   478         // permission check
       
   479         SecurityManager sm = System.getSecurityManager();
       
   480         if (sm != null) {
       
   481             sm.checkPermission(new LinkPermission("hard"));
       
   482             link.checkWrite();
       
   483             existing.checkWrite();
       
   484         }
       
   485         try {
       
   486             link(existing, link);
       
   487         } catch (UnixException x) {
       
   488             x.rethrowAsIOException(link, existing);
       
   489         }
       
   490     }
       
   491 
       
   492     @Override
       
   493     public Path readSymbolicLink(Path obj1) throws IOException {
       
   494         UnixPath link = UnixPath.toUnixPath(obj1);
       
   495         // permission check
       
   496         SecurityManager sm = System.getSecurityManager();
       
   497         if (sm != null) {
       
   498             FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
       
   499                 SecurityConstants.FILE_READLINK_ACTION);
       
   500             AccessController.checkPermission(perm);
       
   501         }
       
   502         try {
       
   503             byte[] target = readlink(link);
       
   504             return new UnixPath(link.getFileSystem(), target);
       
   505         } catch (UnixException x) {
       
   506            if (x.errno() == UnixConstants.EINVAL)
       
   507                 throw new NotLinkException(link.getPathForExecptionMessage());
       
   508             x.rethrowAsIOException(link);
       
   509             return null;    // keep compiler happy
       
   510         }
       
   511     }
   139 }
   512 }