# HG changeset patch # User bpb # Date 1528382609 25200 # Node ID 3111982511eec57b77ddb28b2ebd00458c76a026 # Parent 39ca7558bc43fd56ca914f5c4909201d7af87ae0 8201407: Files.move throws DirectoryNonEmptyException when moving directory across file system Reviewed-by: alanb diff -r 39ca7558bc43 -r 3111982511ee src/java.base/share/classes/java/nio/file/Files.java --- a/src/java.base/share/classes/java/nio/file/Files.java Thu Jun 07 15:10:06 2018 +0200 +++ b/src/java.base/share/classes/java/nio/file/Files.java Thu Jun 07 07:43:29 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1391,8 +1391,9 @@ * specific exception) * @throws DirectoryNotEmptyException * the {@code REPLACE_EXISTING} option is specified but the file - * cannot be replaced because it is a non-empty directory - * (optional specific exception) + * cannot be replaced because it is a non-empty directory, or the + * source is a non-empty directory containing entries that would + * be required to be moved (optional specific exceptions) * @throws AtomicMoveNotSupportedException * if the options array contains the {@code ATOMIC_MOVE} option but * the file cannot be moved as an atomic file system operation. diff -r 39ca7558bc43 -r 3111982511ee src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java --- a/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java Thu Jun 07 15:10:06 2018 +0200 +++ b/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java Thu Jun 07 07:43:29 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -373,6 +373,22 @@ } } + // throw a DirectoryNotEmpty exception if appropriate + static void ensureEmptyDir(UnixPath dir) throws IOException { + try { + long ptr = opendir(dir); + try (UnixDirectoryStream stream = + new UnixDirectoryStream(dir, ptr, e -> true)) { + if (stream.iterator().hasNext()) { + throw new DirectoryNotEmptyException( + dir.getPathForExceptionMessage()); + } + } + } catch (UnixException e) { + e.rethrowAsIOException(dir); + } + } + // move file from source to target static void move(UnixPath source, UnixPath target, CopyOption... options) throws IOException @@ -465,6 +481,7 @@ // copy source to target if (sourceAttrs.isDirectory()) { + ensureEmptyDir(source); copyDirectory(source, sourceAttrs, target, flags); } else { if (sourceAttrs.isSymbolicLink()) { diff -r 39ca7558bc43 -r 3111982511ee src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java Thu Jun 07 15:10:06 2018 +0200 +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java Thu Jun 07 07:43:29 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -249,6 +249,17 @@ } } + // throw a DirectoryNotEmpty exception if not empty + static void ensureEmptyDir(WindowsPath dir) throws IOException { + try (WindowsDirectoryStream dirStream = + new WindowsDirectoryStream(dir, (e) -> true)) { + if (dirStream.iterator().hasNext()) { + throw new DirectoryNotEmptyException( + dir.getPathForExceptionMessage()); + } + } + } + /** * Move file from source to target */ @@ -407,6 +418,7 @@ // create new directory or directory junction try { if (sourceAttrs.isDirectory()) { + ensureEmptyDir(source); CreateDirectory(targetPath, 0L); } else { String linkTarget = WindowsLinkSupport.readLink(source); diff -r 39ca7558bc43 -r 3111982511ee test/jdk/java/nio/file/Files/CopyAndMove.java --- a/test/jdk/java/nio/file/Files/CopyAndMove.java Thu Jun 07 15:10:06 2018 +0200 +++ b/test/jdk/java/nio/file/Files/CopyAndMove.java Thu Jun 07 07:43:29 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 6917021 7006126 6950237 8006645 + * @bug 4313887 6838333 6917021 7006126 6950237 8006645 8201407 * @summary Unit test for java.nio.file.Files copy and move methods (use -Dseed=X to set PRNG seed) * @library .. /test/lib * @build jdk.test.lib.RandomFactory @@ -448,6 +448,10 @@ moveAndVerify(source, target); throw new RuntimeException("IOException expected"); } catch (IOException x) { + if (!(x instanceof DirectoryNotEmptyException)) { + throw new RuntimeException + ("DirectoryNotEmptyException expected", x); + } } delete(source.resolve("foo")); delete(source);