You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/05/26 14:50:41 UTC
mina-sshd git commit: [SSHD-475] SftpFileChannel should take into
account the open mode(s)
Repository: mina-sshd
Updated Branches:
refs/heads/master 9b60dcc53 -> f80467b7b
[SSHD-475] SftpFileChannel should take into account the open mode(s)
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/f80467b7
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/f80467b7
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/f80467b7
Branch: refs/heads/master
Commit: f80467b7be074cd0198df48347def175d08c8bfb
Parents: 9b60dcc
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Tue May 26 15:50:32 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Tue May 26 15:50:32 2015 +0300
----------------------------------------------------------------------
.../sshd/client/sftp/SftpFileChannel.java | 60 +++++++++++++++-----
.../client/sftp/SftpFileSystemProvider.java | 50 +++++++++-------
2 files changed, 77 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f80467b7/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
index 3d9244c..ddb8663 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileChannel.java
@@ -33,25 +33,29 @@ import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.sshd.client.SftpException;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
public class SftpFileChannel extends FileChannel {
private final SftpPath p;
private final Collection<SftpClient.OpenMode> modes;
private final SftpClient sftp;
- private final SftpClient.Handle handle;
+ private final SftpClient.CloseableHandle handle;
private final Object lock;
private volatile long pos;
private volatile Thread blockingThread;
public SftpFileChannel(SftpPath p, Collection<SftpClient.OpenMode> modes) throws IOException {
this.p = p;
- this.modes = modes;
+ this.modes = ValidateUtils.checkNotNull(modes, "No channel modes specified", GenericUtils.EMPTY_OBJECT_ARRAY);
sftp = p.getFileSystem().getClient();
handle = sftp.open(p.toString(), modes);
lock = new Object();
@@ -77,8 +81,11 @@ public class SftpFileChannel extends FileChannel {
return doRead(buffers, -1);
}
+ public static final Set<SftpClient.OpenMode> READ_MODES=
+ Collections.unmodifiableSet(EnumSet.of(SftpClient.OpenMode.Read));
+
protected long doRead(List<ByteBuffer> buffers, long position) throws IOException {
- ensureOpen();
+ ensureOpen(READ_MODES);
synchronized (lock) {
boolean completed = false;
boolean eof = false;
@@ -138,8 +145,12 @@ public class SftpFileChannel extends FileChannel {
return doWrite(buffers, -1);
}
+ public static final Set<SftpClient.OpenMode> WRITE_MODES=
+ Collections.unmodifiableSet(
+ EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Append, SftpClient.OpenMode.Create, SftpClient.OpenMode.Truncate));
+
protected long doWrite(List<ByteBuffer> buffers, long position) throws IOException {
- ensureOpen();
+ ensureOpen(WRITE_MODES);
synchronized (lock) {
boolean completed = false;
long curPos = position >= 0 ? position : pos;
@@ -175,7 +186,7 @@ public class SftpFileChannel extends FileChannel {
@Override
public long position() throws IOException {
- ensureOpen();
+ ensureOpen(Collections.<SftpClient.OpenMode>emptySet());
return pos;
}
@@ -184,7 +195,8 @@ public class SftpFileChannel extends FileChannel {
if (newPosition < 0) {
throw new IllegalArgumentException("position(" + p + ") illegal file channel position: " + newPosition);
}
- ensureOpen();
+
+ ensureOpen(Collections.<SftpClient.OpenMode>emptySet());
synchronized (lock) {
pos = newPosition;
return this;
@@ -193,18 +205,20 @@ public class SftpFileChannel extends FileChannel {
@Override
public long size() throws IOException {
+ ensureOpen(Collections.<SftpClient.OpenMode>emptySet());
return sftp.stat(handle).size;
}
@Override
public FileChannel truncate(long size) throws IOException {
+ ensureOpen(Collections.<SftpClient.OpenMode>emptySet());
sftp.setStat(handle, new SftpClient.Attributes().size(size));
return this;
}
@Override
public void force(boolean metaData) throws IOException {
- // ignored
+ ensureOpen(Collections.<SftpClient.OpenMode>emptySet());
}
@Override
@@ -212,7 +226,7 @@ public class SftpFileChannel extends FileChannel {
if ((position < 0) || (count < 0)) {
throw new IllegalArgumentException("transferTo(" + p + ") illegal position (" + position + ") or count (" + count + ")");
}
- ensureOpen();
+ ensureOpen(READ_MODES);
synchronized (lock) {
boolean completed = false;
boolean eof = false;
@@ -249,8 +263,9 @@ public class SftpFileChannel extends FileChannel {
if ((position < 0) || (count < 0)) {
throw new IllegalArgumentException("transferFrom(" + p + ") illegal position (" + position + ") or count (" + count + ")");
}
- ensureOpen();
- synchronized (lock) {
+ ensureOpen(WRITE_MODES);
+
+ synchronized(lock) {
boolean completed = false;
long curPos = position >= 0 ? position : pos;
try {
@@ -289,6 +304,8 @@ public class SftpFileChannel extends FileChannel {
@Override
public FileLock tryLock(final long position, final long size, boolean shared) throws IOException {
+ ensureOpen(Collections.<SftpClient.OpenMode>emptySet());
+
try {
sftp.lock(handle, position, size, 0);
} catch (SftpException e) {
@@ -297,8 +314,8 @@ public class SftpFileChannel extends FileChannel {
}
throw e;
}
- return new FileLock(this, position, size, shared) {
+ return new FileLock(this, position, size, shared) {
private final AtomicBoolean valid = new AtomicBoolean(true);
@Override
@@ -325,7 +342,7 @@ public class SftpFileChannel extends FileChannel {
}
} finally {
try {
- sftp.close(handle);
+ handle.close();
} finally {
sftp.close();
}
@@ -342,10 +359,27 @@ public class SftpFileChannel extends FileChannel {
end(completed);
}
- private void ensureOpen() throws IOException {
+ /**
+ * Checks that the channel is open and that its current mode contains
+ * at least one of the required ones
+ * @param reqModes The required modes - ignored if {@code null}/empty
+ * @throws IOException If channel not open or the required modes are not
+ * satisfied
+ */
+ private void ensureOpen(Collection<SftpClient.OpenMode> reqModes) throws IOException {
if (!isOpen()) {
throw new ClosedChannelException();
}
+
+ if (GenericUtils.size(reqModes) > 0) {
+ for (SftpClient.OpenMode m : reqModes) {
+ if (this.modes.contains(m)) {
+ return;
+ }
+ }
+
+ throw new IOException("ensureOpen(" + p + ") current channel modes (" + this.modes + ") do contain any of the required: " + reqModes);
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f80467b7/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
index 6eb2e61..b1f567b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
@@ -185,8 +185,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
@Override
public FileChannel newFileChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
- final SftpPath p = toSftpPath(path);
- final EnumSet<SftpClient.OpenMode> modes = EnumSet.noneOf(SftpClient.OpenMode.class);
+ Collection<SftpClient.OpenMode> modes = EnumSet.noneOf(SftpClient.OpenMode.class);
for (OpenOption option : options) {
if (option == StandardOpenOption.READ) {
modes.add(SftpClient.OpenMode.Read);
@@ -201,8 +200,16 @@ public class SftpFileSystemProvider extends FileSystemProvider {
} else if (option == StandardOpenOption.CREATE_NEW) {
modes.add(SftpClient.OpenMode.Create);
modes.add(SftpClient.OpenMode.Exclusive);
+ } else if (option == StandardOpenOption.SPARSE) {
+ /*
+ * As per the Javadoc:
+ *
+ * The option is ignored when the file system does not
+ * support the creation of sparse files
+ */
+ continue;
} else {
- throw new IllegalArgumentException("Unsupported open option " + option);
+ throw new IllegalArgumentException("newFileChannel(" + path + ") unsupported open option: " + option);
}
}
if (modes.isEmpty()) {
@@ -210,7 +217,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
modes.add(SftpClient.OpenMode.Write);
}
// TODO: attrs
- return new SftpFileChannel(p, modes);
+ return new SftpFileChannel(toSftpPath(path), modes);
}
@Override
@@ -467,26 +474,29 @@ public class SftpFileSystemProvider extends FileSystemProvider {
SftpPath p = toSftpPath(path);
boolean w = false;
boolean x = false;
- for (AccessMode mode : modes) {
- switch (mode) {
- case READ:
- break;
- case WRITE:
- w = true;
- break;
- case EXECUTE:
- x = true;
- break;
- default:
- throw new UnsupportedOperationException("Unsupported mode: " + mode);
+ if (GenericUtils.length(modes) > 0) {
+ for (AccessMode mode : modes) {
+ switch (mode) {
+ case READ:
+ break;
+ case WRITE:
+ w = true;
+ break;
+ case EXECUTE:
+ x = true;
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported mode: " + mode);
+ }
}
}
+
BasicFileAttributes attrs = getFileAttributeView(p, BasicFileAttributeView.class).readAttributes();
- if (attrs == null && !(p.isAbsolute() && p.getNameCount() == 0)) {
- throw new NoSuchFileException(toString());
+ if ((attrs == null) && !(p.isAbsolute() && p.getNameCount() == 0)) {
+ throw new NoSuchFileException(path.toString());
}
- if (x || w && p.getFileSystem().isReadOnly()) {
- throw new AccessDeniedException(toString());
+ if (x || (w && p.getFileSystem().isReadOnly())) {
+ throw new AccessDeniedException(path.toString());
}
}