6863864: (fs) Path.createSymbolicLink doesn't set directory flag when creating sym link to directory (win)
authoralanb
Mon, 27 Jul 2009 18:44:42 +0100
changeset 3326 31a5302fe6d4
parent 3325 0e7d9c6c9994
child 3327 82e069ae54ab
6863864: (fs) Path.createSymbolicLink doesn't set directory flag when creating sym link to directory (win) Reviewed-by: sherman
jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
jdk/test/java/nio/file/Path/Links.java
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java	Mon Jul 27 22:04:07 2009 +0800
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java	Mon Jul 27 18:44:42 2009 +0100
@@ -1177,14 +1177,20 @@
 
         /*
          * Windows treates symbolic links to directories differently than it
-         * does to other file types. For that reason we check if the exists and
-         * is a directory.
+         * does to other file types. For that reason we need to check if the
+         * target is a directory (or a directory junction).
          */
+        WindowsPath resolvedTarget;
+        if (target.type == WindowsPathType.RELATIVE) {
+            WindowsPath parent = getParent();
+            resolvedTarget = (parent == null) ? target : parent.resolve(target);
+        } else {
+            resolvedTarget = resolve(target);
+        }
         int flags = 0;
-        WindowsPath resolvedTarget =
-            WindowsPath.createFromNormalizedPath(getFileSystem(), resolve(target).path);
         try {
-            if (WindowsFileAttributes.get(resolvedTarget, true).isDirectory())
+            WindowsFileAttributes wattrs = WindowsFileAttributes.get(resolvedTarget, false);
+            if (wattrs.isDirectory() || wattrs.isDirectoryLink())
                 flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
         } catch (WindowsException x) {
             // unable to access target so assume target is not a directory
--- a/jdk/test/java/nio/file/Path/Links.java	Mon Jul 27 22:04:07 2009 +0800
+++ b/jdk/test/java/nio/file/Path/Links.java	Mon Jul 27 18:44:42 2009 +0100
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4313887 6838333
+ * @bug 4313887 6838333 6863864
  * @summary Unit test for java.nio.file.Path createSymbolicLink,
  *     readSymbolicLink, and createLink methods
  * @library ..
@@ -31,7 +31,6 @@
 import java.nio.file.*;
 import java.nio.file.attribute.*;
 import java.io.*;
-import java.util.*;
 
 public class Links {
 
@@ -47,7 +46,7 @@
      * Exercise createSymbolicLink and readLink methods
      */
     static void testSymLinks(Path dir) throws IOException {
-        Path link = dir.resolve("link");
+        final Path link = dir.resolve("link");
 
         // Check if sym links are supported
         try {
@@ -76,6 +75,63 @@
                 link.delete();
             }
         }
+
+        // Test links to directory
+        Path mydir = dir.resolve("mydir");
+        Path myfile = mydir.resolve("myfile");
+        try {
+            mydir.createDirectory();
+            myfile.createFile();
+
+            // link -> "mydir"
+            link.createSymbolicLink(mydir.getName());
+            assertTrue(link.readSymbolicLink().equals(mydir.getName()));
+
+            // Test access to directory via link
+            DirectoryStream<Path> stream = link.newDirectoryStream();
+            try {
+                boolean found = false;
+                for (Path entry: stream) {
+                    if (entry.getName().equals(myfile.getName())) {
+                        found = true;
+                        break;
+                    }
+                }
+                assertTrue(found);
+            } finally {
+                stream.close();
+            }
+
+            // Test link2 -> link -> mydir
+            final Path link2 = dir.resolve("link2");
+            Path target2 = link.getName();
+            link2.createSymbolicLink(target2);
+            try {
+                assertTrue(link2.readSymbolicLink().equals(target2));
+                link2.newDirectoryStream().close();
+            } finally {
+                link2.delete();
+            }
+
+            // Remove mydir and re-create link2 before re-creating mydir
+            // (This is a useful test on Windows to ensure that creating a
+            // sym link to a directory sym link creates the right type of link).
+            myfile.delete();
+            mydir.delete();
+            link2.createSymbolicLink(target2);
+            try {
+                assertTrue(link2.readSymbolicLink().equals(target2));
+                mydir.createDirectory();
+                link2.newDirectoryStream().close();
+            } finally {
+                link2.delete();
+            }
+
+        } finally {
+            myfile.deleteIfExists();
+            mydir.deleteIfExists();
+            link.deleteIfExists();
+        }
     }
 
     /**