jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java
changeset 6537 7aa4e7bb5dae
parent 5506 202f599c92aa
child 7668 d4a77089c587
equal deleted inserted replaced
6535:77ffd0e75bfb 6537:7aa4e7bb5dae
    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.util.Iterator;
    29 import java.util.Iterator;
    30 import java.util.ConcurrentModificationException;
       
    31 import java.util.NoSuchElementException;
    30 import java.util.NoSuchElementException;
    32 import java.util.concurrent.locks.*;
    31 import java.util.concurrent.locks.*;
    33 import java.io.IOException;
    32 import java.io.IOException;
    34 import static sun.nio.fs.UnixNativeDispatcher.*;
    33 import static sun.nio.fs.UnixNativeDispatcher.*;
    35 
    34 
   137         private boolean atEof;
   136         private boolean atEof;
   138 
   137 
   139         // next entry to return
   138         // next entry to return
   140         private Path nextEntry;
   139         private Path nextEntry;
   141 
   140 
   142         // previous entry returned by next method (needed by remove method)
       
   143         private Path prevEntry;
       
   144 
       
   145         UnixDirectoryIterator(DirectoryStream<Path> stream) {
   141         UnixDirectoryIterator(DirectoryStream<Path> stream) {
   146             atEof = false;
   142             atEof = false;
   147             this.stream = stream;
   143             this.stream = stream;
   148         }
   144         }
   149 
   145 
   166                 byte[] nameAsBytes = null;
   162                 byte[] nameAsBytes = null;
   167 
   163 
   168                 // prevent close while reading
   164                 // prevent close while reading
   169                 readLock().lock();
   165                 readLock().lock();
   170                 try {
   166                 try {
   171                     if (isClosed)
   167                     if (isOpen()) {
   172                         throwAsConcurrentModificationException(new
       
   173                             ClosedDirectoryStreamException());
       
   174                     try {
       
   175                         nameAsBytes = readdir(dp);
   168                         nameAsBytes = readdir(dp);
   176                     } catch (UnixException x) {
       
   177                         try {
       
   178                             x.rethrowAsIOException(dir);
       
   179                         } catch (IOException ioe) {
       
   180                             throwAsConcurrentModificationException(ioe);
       
   181                         }
       
   182                     }
   169                     }
       
   170                 } catch (UnixException x) {
       
   171                     IOException ioe = x.asIOException(dir);
       
   172                     throw new DirectoryIteratorException(ioe);
   183                 } finally {
   173                 } finally {
   184                     readLock().unlock();
   174                     readLock().unlock();
   185                 }
   175                 }
   186 
   176 
   187                 // EOF
   177                 // EOF
   188                 if (nameAsBytes == null) {
   178                 if (nameAsBytes == null) {
       
   179                     atEof = true;
   189                     return null;
   180                     return null;
   190                 }
   181                 }
   191 
   182 
   192                 // ignore "." and ".."
   183                 // ignore "." and ".."
   193                 if (!isSelfOrParent(nameAsBytes)) {
   184                 if (!isSelfOrParent(nameAsBytes)) {
   196                     // return entry if no filter or filter accepts it
   187                     // return entry if no filter or filter accepts it
   197                     try {
   188                     try {
   198                         if (filter == null || filter.accept(entry))
   189                         if (filter == null || filter.accept(entry))
   199                             return entry;
   190                             return entry;
   200                     } catch (IOException ioe) {
   191                     } catch (IOException ioe) {
   201                         throwAsConcurrentModificationException(ioe);
   192                         throw new DirectoryIteratorException(ioe);
   202                     }
   193                     }
   203                 }
   194                 }
   204             }
   195             }
   205         }
   196         }
   206 
   197 
   207         @Override
   198         @Override
   208         public synchronized boolean hasNext() {
   199         public synchronized boolean hasNext() {
   209             if (nextEntry == null && !atEof) {
   200             if (nextEntry == null && !atEof)
   210                 nextEntry = readNextEntry();
   201                 nextEntry = readNextEntry();
   211 
       
   212                 // at EOF?
       
   213                 if (nextEntry == null)
       
   214                     atEof = true;
       
   215             }
       
   216             return nextEntry != null;
   202             return nextEntry != null;
   217         }
   203         }
   218 
   204 
   219         @Override
   205         @Override
   220         public synchronized Path next() {
   206         public synchronized Path next() {
   221             if (nextEntry == null) {
   207             Path result;
   222                 if (!atEof) {
   208             if (nextEntry == null && !atEof) {
   223                     nextEntry = readNextEntry();
   209                 result = readNextEntry();
   224                 }
   210             } else {
   225                 if (nextEntry == null) {
   211                 result = nextEntry;
   226                     atEof = true;
   212                 nextEntry = null;
   227                     throw new NoSuchElementException();
   213             }
   228                 }
   214             if (result == null)
   229             }
   215                 throw new NoSuchElementException();
   230             prevEntry = nextEntry;
   216             return result;
   231             nextEntry = null;
       
   232             return prevEntry;
       
   233         }
   217         }
   234 
   218 
   235         @Override
   219         @Override
   236         public void remove() {
   220         public void remove() {
   237             if (isClosed) {
   221             throw new UnsupportedOperationException();
   238                 throwAsConcurrentModificationException(new
   222         }
   239                     ClosedDirectoryStreamException());
   223     }
   240             }
       
   241             Path entry;
       
   242             synchronized (this) {
       
   243                 if (prevEntry == null)
       
   244                     throw new IllegalStateException("No previous entry to remove");
       
   245                 entry = prevEntry;
       
   246                 prevEntry = null;
       
   247             }
       
   248 
       
   249             // use (race-free) unlinkat if available
       
   250             try {
       
   251                 if (stream instanceof UnixSecureDirectoryStream) {
       
   252                     ((UnixSecureDirectoryStream)stream)
       
   253                         .implDelete(entry.getName(), false, 0);
       
   254                 } else {
       
   255                     entry.delete();
       
   256                 }
       
   257             } catch (IOException ioe) {
       
   258                 throwAsConcurrentModificationException(ioe);
       
   259             } catch (SecurityException se) {
       
   260                 throwAsConcurrentModificationException(se);
       
   261             }
       
   262         }
       
   263     }
       
   264 
       
   265     private static void throwAsConcurrentModificationException(Throwable t) {
       
   266         ConcurrentModificationException cme = new ConcurrentModificationException();
       
   267         cme.initCause(t);
       
   268         throw cme;
       
   269     }
       
   270 
       
   271 }
   224 }