diff --git a/doc/release_history.html b/doc/release_history.html
index 9ca9740..639566d 100644
--- a/doc/release_history.html
+++ b/doc/release_history.html
@@ -36,6 +36,19 @@
+
1.56.1
+
+ - The Windows implementation now treats NTFS directory junctions (also known
+ as junctions, also known as mount points) as symlinks. This has the effect of
+ treating directory junctions as directories, and thus supporting all
+ operations suitable for directories. This resolves
+ #9016. Directory
+ junctions are very similar to symlinks, but may have performance or other
+ advantages in some situations. They can be created from the command line with
+ "
mklink /j link target
". There is no plan for Boost.Filesystem to
+ be able to create them directly other than by calling std::system()
.
+
+
1.56.0
- Reorganize
recursive_directory_iterator::increment
, adding an
@@ -225,7 +238,7 @@
Revised
-22 July, 2014
+25 July, 2014
© Copyright Beman Dawes, 2011
Use, modification, and distribution are subject to the Boost Software
License, Version 1.0. See
diff --git a/src/operations.cpp b/src/operations.cpp
index 09b8853..d004e08 100644
--- a/src/operations.cpp
+++ b/src/operations.cpp
@@ -53,6 +53,7 @@
#endif
#include
+#define BOOST_FILEYSTEM_INCLUDE_IOSTREAM
#ifdef BOOST_FILEYSTEM_INCLUDE_IOSTREAM
# include
#endif
@@ -586,9 +587,18 @@ namespace
BOOL result = ::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(),
MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRetLen, NULL);
if (!result) return false;
-
- return reinterpret_cast(buf.get())
- ->ReparseTag == IO_REPARSE_TAG_SYMLINK;
+
+ return reinterpret_cast(buf.get())->ReparseTag
+ == IO_REPARSE_TAG_SYMLINK
+ // Issue 9016 asked that NTFS directory junctions be recognized as directories.
+ // That is equivalent to recognizing them as symlinks, and then the normal symlink
+ // mechanism will take care of recognizing them as directories.
+ //
+ // Directory junctions are very similar to symlinks, but have some performance
+ // and other advantages over symlinks. They can be created from the command line
+ // with "mklink /j junction-name target-path".
+ || reinterpret_cast(buf.get())->ReparseTag
+ == IO_REPARSE_TAG_MOUNT_POINT; // aka "directory junction" or "junction"
}
inline std::size_t get_full_path_name(
diff --git a/test/operations_test.cpp b/test/operations_test.cpp
index a7ef18e..5ab2e92 100644
--- a/test/operations_test.cpp
+++ b/test/operations_test.cpp
@@ -1684,6 +1684,61 @@ namespace
== "c:/foo");
BOOST_TEST(fs::system_complete(fs::path("//share")).generic_string()
== "//share");
+
+ // Issue 9016 asked that NTFS directory junctions be recognized as directories.
+ // That is equivalent to recognizing them as symlinks, and then the normal symlink
+ // mechanism will take care of recognizing them as directories.
+ //
+ // Directory junctions are very similar to symlinks, but have some performance
+ // and other advantages over symlinks. They can be created from the command line
+ // with "mklink /j junction-name target-path".
+
+ if (create_symlink_ok) // only if symlinks supported
+ {
+ cout << " directory junction tests..." << endl;
+ BOOST_TEST(fs::exists(dir));
+ BOOST_TEST(fs::exists(dir / "d1f1"));
+
+ fs::path junc(dir / "junc");
+ std::string cmd = "pushd ";
+ cmd += dir.string();
+ std::system(cmd.c_str());
+ std::system("mklink /j junc d1");
+ std::system("popd");
+
+ BOOST_TEST(fs::exists(junc));
+ BOOST_TEST(fs::is_symlink(junc));
+ BOOST_TEST(fs::is_directory(junc));
+ BOOST_TEST(!fs::is_regular_file(junc));
+ BOOST_TEST(fs::exists(junc / "d1f1"));
+ BOOST_TEST(fs::is_regular_file(junc / "d1f1"));
+
+ int count = 0;
+ for (fs::directory_iterator itr(junc);
+ itr != fs::directory_iterator(); ++itr)
+ {
+ cout << itr->path() << endl;
+ ++count;
+ }
+ BOOST_TEST(count > 0);
+
+ fs::path new_junc(dir / "new-junc");
+ fs::rename(junc, new_junc);
+ BOOST_TEST(!fs::exists(junc));
+ BOOST_TEST(fs::exists(new_junc));
+ BOOST_TEST(fs::is_symlink(new_junc));
+ BOOST_TEST(fs::is_directory(new_junc));
+ BOOST_TEST(!fs::is_regular_file(new_junc));
+ BOOST_TEST(fs::exists(new_junc / "d1f1"));
+ BOOST_TEST(fs::is_regular_file(new_junc / "d1f1"));
+
+ fs::remove(new_junc);
+ BOOST_TEST(!fs::exists(new_junc / "d1f1"));
+ BOOST_TEST(!fs::exists(new_junc));
+ BOOST_TEST(fs::exists(dir));
+ BOOST_TEST(fs::exists(dir / "d1f1"));
+ }
+
} // Windows
else if (platform == "POSIX")