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

+ +

1.56.0


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")