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

Print this page




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.nio.fs;
  27 
  28 import java.nio.file.*;
  29 import java.nio.file.attribute.*;
  30 import java.nio.file.spi.FileSystemProvider;
  31 import java.nio.channels.*;
  32 import java.net.URI;
  33 import java.util.concurrent.ExecutorService;
  34 import java.io.IOException;

  35 import java.util.*;

  36 
  37 import sun.nio.ch.ThreadPool;



  38 
  39 /**
  40  * Base implementation of FileSystemProvider
  41  */
  42 
  43 public abstract class UnixFileSystemProvider
  44     extends FileSystemProvider
  45 {
  46     private static final String USER_DIR = "user.dir";
  47     private final UnixFileSystem theFileSystem;
  48 
  49     public UnixFileSystemProvider() {
  50         String userDir = System.getProperty(USER_DIR);
  51         theFileSystem = newFileSystem(userDir);
  52     }
  53 
  54     /**
  55      * Constructs a new file system using the given default directory.
  56      */
  57     abstract UnixFileSystem newFileSystem(String dir);
  58 
  59     @Override
  60     public final String getScheme() {
  61         return "file";
  62     }
  63 
  64     private void checkUri(URI uri) {


  76             throw new IllegalArgumentException("Fragment component present");
  77     }
  78 
  79     @Override
  80     public final FileSystem newFileSystem(URI uri, Map<String,?> env) {
  81         checkUri(uri);
  82         throw new FileSystemAlreadyExistsException();
  83     }
  84 
  85     @Override
  86     public final FileSystem getFileSystem(URI uri) {
  87         checkUri(uri);
  88         return theFileSystem;
  89     }
  90 
  91     @Override
  92     public Path getPath(URI uri) {
  93         return UnixUriUtils.fromUri(theFileSystem, uri);
  94     }
  95 
  96     protected UnixPath checkPath(Path obj) {
  97         if (obj == null)
  98             throw new NullPointerException();
  99         if (!(obj instanceof UnixPath))
 100             throw new ProviderMismatchException();
 101         return (UnixPath)obj;
 102     }
 103 














 104     @Override
























































 105     public FileChannel newFileChannel(Path obj,
 106                                       Set<? extends OpenOption> options,
 107                                       FileAttribute<?>... attrs)
 108         throws IOException
 109     {
 110         UnixPath file = checkPath(obj);
 111         int mode = UnixFileModeAttribute
 112             .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
 113         try {
 114             return UnixChannelFactory.newFileChannel(file, options, mode);
 115         } catch (UnixException x) {
 116             x.rethrowAsIOException(file);
 117             return null;
 118         }
 119     }
 120 
 121     @Override
 122     public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
 123                                                               Set<? extends OpenOption> options,
 124                                                               ExecutorService executor,
 125                                                               FileAttribute<?>... attrs) throws IOException
 126     {
 127         UnixPath file = checkPath(obj);
 128         int mode = UnixFileModeAttribute
 129             .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
 130         ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
 131         try {
 132             return UnixChannelFactory
 133                 .newAsynchronousFileChannel(file, options, mode, pool);
 134         } catch (UnixException x) {
 135             x.rethrowAsIOException(file);
 136             return null;
 137         }
 138     }











































































































































































































































































































 139 }


  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.nio.fs;
  27 
  28 import java.nio.file.*;
  29 import java.nio.file.attribute.*;

  30 import java.nio.channels.*;
  31 import java.net.URI;
  32 import java.util.concurrent.ExecutorService;
  33 import java.io.IOException;
  34 import java.io.FilePermission;
  35 import java.util.*;
  36 import java.security.AccessController;
  37 
  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.*;
  42 
  43 /**
  44  * Base implementation of FileSystemProvider
  45  */
  46 
  47 public abstract class UnixFileSystemProvider
  48     extends AbstractFileSystemProvider
  49 {
  50     private static final String USER_DIR = "user.dir";
  51     private final UnixFileSystem theFileSystem;
  52 
  53     public UnixFileSystemProvider() {
  54         String userDir = System.getProperty(USER_DIR);
  55         theFileSystem = newFileSystem(userDir);
  56     }
  57 
  58     /**
  59      * Constructs a new file system using the given default directory.
  60      */
  61     abstract UnixFileSystem newFileSystem(String dir);
  62 
  63     @Override
  64     public final String getScheme() {
  65         return "file";
  66     }
  67 
  68     private void checkUri(URI uri) {


  80             throw new IllegalArgumentException("Fragment component present");
  81     }
  82 
  83     @Override
  84     public final FileSystem newFileSystem(URI uri, Map<String,?> env) {
  85         checkUri(uri);
  86         throw new FileSystemAlreadyExistsException();
  87     }
  88 
  89     @Override
  90     public final FileSystem getFileSystem(URI uri) {
  91         checkUri(uri);
  92         return theFileSystem;
  93     }
  94 
  95     @Override
  96     public Path getPath(URI uri) {
  97         return UnixUriUtils.fromUri(theFileSystem, uri);
  98     }  
  99 
 100     UnixPath checkPath(Path obj) {
 101         if (obj == null)
 102             throw new NullPointerException();
 103         if (!(obj instanceof UnixPath))
 104             throw new ProviderMismatchException();
 105         return (UnixPath)obj;
 106     }
 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 
 178     @Override
 179     public FileChannel newFileChannel(Path obj,
 180                                       Set<? extends OpenOption> options,
 181                                       FileAttribute<?>... attrs)
 182         throws IOException
 183     {
 184         UnixPath file = checkPath(obj);
 185         int mode = UnixFileModeAttribute
 186             .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
 187         try {
 188             return UnixChannelFactory.newFileChannel(file, options, mode);
 189         } catch (UnixException x) {
 190             x.rethrowAsIOException(file);
 191             return null;
 192         }
 193     }
 194 
 195     @Override
 196     public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
 197                                                               Set<? extends OpenOption> options,
 198                                                               ExecutorService executor,
 199                                                               FileAttribute<?>... attrs) throws IOException
 200     {
 201         UnixPath file = checkPath(obj);
 202         int mode = UnixFileModeAttribute
 203             .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
 204         ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
 205         try {
 206             return UnixChannelFactory
 207                 .newAsynchronousFileChannel(file, options, mode, pool);
 208         } catch (UnixException x) {
 209             x.rethrowAsIOException(file);
 210             return null;
 211         }
 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     }    
 512 }