Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java
32288 views
/*1* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import java.nio.file.*;28import java.util.Iterator;29import java.util.NoSuchElementException;30import java.util.concurrent.locks.*;31import java.io.IOException;32import static sun.nio.fs.UnixNativeDispatcher.*;3334/**35* Unix implementation of java.nio.file.DirectoryStream36*/3738class UnixDirectoryStream39implements DirectoryStream<Path>40{41// path to directory when originally opened42private final UnixPath dir;4344// directory pointer (returned by opendir)45private final long dp;4647// filter (may be null)48private final DirectoryStream.Filter<? super Path> filter;4950// used to coorindate closing of directory stream51private final ReentrantReadWriteLock streamLock =52new ReentrantReadWriteLock(true);5354// indicates if directory stream is open (synchronize on closeLock)55private volatile boolean isClosed;5657// directory iterator58private Iterator<Path> iterator;5960/**61* Initializes a new instance62*/63UnixDirectoryStream(UnixPath dir, long dp, DirectoryStream.Filter<? super Path> filter) {64this.dir = dir;65this.dp = dp;66this.filter = filter;67}6869protected final UnixPath directory() {70return dir;71}7273protected final Lock readLock() {74return streamLock.readLock();75}7677protected final Lock writeLock() {78return streamLock.writeLock();79}8081protected final boolean isOpen() {82return !isClosed;83}8485protected final boolean closeImpl() throws IOException {86if (!isClosed) {87isClosed = true;88try {89closedir(dp);90} catch (UnixException x) {91throw new IOException(x.errorString());92}93return true;94} else {95return false;96}97}9899@Override100public void close()101throws IOException102{103writeLock().lock();104try {105closeImpl();106} finally {107writeLock().unlock();108}109}110111protected final Iterator<Path> iterator(DirectoryStream<Path> ds) {112if (isClosed) {113throw new IllegalStateException("Directory stream is closed");114}115synchronized (this) {116if (iterator != null)117throw new IllegalStateException("Iterator already obtained");118iterator = new UnixDirectoryIterator(ds);119return iterator;120}121}122123@Override124public Iterator<Path> iterator() {125return iterator(this);126}127128/**129* Iterator implementation130*/131private class UnixDirectoryIterator implements Iterator<Path> {132private final DirectoryStream<Path> stream;133134// true when at EOF135private boolean atEof;136137// next entry to return138private Path nextEntry;139140UnixDirectoryIterator(DirectoryStream<Path> stream) {141atEof = false;142this.stream = stream;143}144145// Return true if file name is "." or ".."146private boolean isSelfOrParent(byte[] nameAsBytes) {147if (nameAsBytes[0] == '.') {148if ((nameAsBytes.length == 1) ||149(nameAsBytes.length == 2 && nameAsBytes[1] == '.')) {150return true;151}152}153return false;154}155156// Returns next entry (or null)157private Path readNextEntry() {158assert Thread.holdsLock(this);159160for (;;) {161byte[] nameAsBytes = null;162163// prevent close while reading164readLock().lock();165try {166if (isOpen()) {167nameAsBytes = readdir(dp);168}169} catch (UnixException x) {170IOException ioe = x.asIOException(dir);171throw new DirectoryIteratorException(ioe);172} finally {173readLock().unlock();174}175176// EOF177if (nameAsBytes == null) {178atEof = true;179return null;180}181182// ignore "." and ".."183if (!isSelfOrParent(nameAsBytes)) {184Path entry = dir.resolve(nameAsBytes);185186// return entry if no filter or filter accepts it187try {188if (filter == null || filter.accept(entry))189return entry;190} catch (IOException ioe) {191throw new DirectoryIteratorException(ioe);192}193}194}195}196197@Override198public synchronized boolean hasNext() {199if (nextEntry == null && !atEof)200nextEntry = readNextEntry();201return nextEntry != null;202}203204@Override205public synchronized Path next() {206Path result;207if (nextEntry == null && !atEof) {208result = readNextEntry();209} else {210result = nextEntry;211nextEntry = null;212}213if (result == null)214throw new NoSuchElementException();215return result;216}217218@Override219public void remove() {220throw new UnsupportedOperationException();221}222}223}224225226