From 5178e7cb0b08dc06d3f9a4f52711e270c5eb30da Mon Sep 17 00:00:00 2001 From: jfrijters Date: Wed, 26 Aug 2015 10:19:11 +0000 Subject: [PATCH] Implemented atomic file move (on Windows). --- openjdk/sun/nio/fs/NetFileSystemProvider.java | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/openjdk/sun/nio/fs/NetFileSystemProvider.java b/openjdk/sun/nio/fs/NetFileSystemProvider.java index 999c1231..b49c6cd6 100644 --- a/openjdk/sun/nio/fs/NetFileSystemProvider.java +++ b/openjdk/sun/nio/fs/NetFileSystemProvider.java @@ -36,6 +36,8 @@ import cli.System.IO.FileMode; import cli.System.IO.FileShare; import cli.System.IO.FileStream; import cli.System.IO.FileOptions; +import cli.System.Runtime.InteropServices.DllImportAttribute; +import cli.System.Runtime.InteropServices.Marshal; import cli.System.Security.AccessControl.FileSystemRights; import com.sun.nio.file.ExtendedOpenOption; import java.io.FileDescriptor; @@ -628,6 +630,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider NetPath nsource = NetPath.from(source); NetPath ntarget = NetPath.from(target); boolean overwrite = false; + boolean atomicMove = false; for (CopyOption opt : options) { if (opt == StandardCopyOption.REPLACE_EXISTING) @@ -636,7 +639,14 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider } else if (opt == StandardCopyOption.ATOMIC_MOVE) { - throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option"); + if (WINDOWS) + { + atomicMove = true; + } + else + { + throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option"); + } } else { @@ -651,6 +661,36 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider sm.checkRead(nsource.path); sm.checkWrite(ntarget.path); } + if (atomicMove) + { + int MOVEFILE_REPLACE_EXISTING = 1; + if (MoveFileEx(nsource.path, ntarget.path, MOVEFILE_REPLACE_EXISTING) == 0) + { + final int ERROR_FILE_NOT_FOUND = 2; + final int ERROR_PATH_NOT_FOUND = 3; + final int ERROR_ACCESS_DENIED = 5; + final int ERROR_NOT_SAME_DEVICE = 17; + final int ERROR_FILE_EXISTS = 80; + final int ERROR_ALREADY_EXISTS = 183; + int lastError = Marshal.GetLastWin32Error(); + switch (lastError) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + throw new NoSuchFileException(nsource.path, ntarget.path, null); + case ERROR_ACCESS_DENIED: + throw new AccessDeniedException(nsource.path, ntarget.path, null); + case ERROR_NOT_SAME_DEVICE: + throw new AtomicMoveNotSupportedException(nsource.path, ntarget.path, "Unsupported copy option"); + case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: + throw new FileAlreadyExistsException(nsource.path, ntarget.path, null); + default: + throw new FileSystemException(nsource.path, ntarget.path, "Error " + lastError); + } + } + return; + } try { if (false) throw new cli.System.ArgumentException(); @@ -711,6 +751,9 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider } } + @DllImportAttribute.Annotation(value="kernel32", SetLastError=true) + private static native int MoveFileEx(String lpExistingFileName, String lpNewFileName, int dwFlags); + public boolean isSameFile(Path path, Path path2) throws IOException { if (path.equals(path2))