1 //  Boost operations_test.cpp  ---------------------------------------------------------//
2 
3 //  Copyright Alexander Grund 2020
4 
5 //  Distributed under the Boost Software License, Version 1.0.
6 //  See http://www.boost.org/LICENSE_1_0.txt
7 
8 //  Library home page: http://www.boost.org/libs/filesystem
9 
10 #include <iostream>
11 
12 #if defined(BOOST_FILESYSTEM_HAS_MKLINK)
13 
14 #include <boost/filesystem.hpp>
15 #include <boost/system/error_code.hpp>
16 #include <boost/core/lightweight_test.hpp>
17 #include <cstdlib>
18 #include <vector>
19 
20 namespace fs = boost::filesystem;
21 
22 struct TmpDir
23 {
24   fs::path path;
TmpDirTmpDir25   TmpDir(const fs::path& base): path(fs::absolute(base) / fs::unique_path())
26   {
27     fs::create_directories(path);
28   }
~TmpDirTmpDir29   ~TmpDir()
30   {
31     boost::system::error_code ec;
32     fs::remove_all(path, ec);
33   }
34 };
35 
36 // Test fs::canonical for various path in a Windows directory junction point
37 // This failed before due to broken handling of absolute paths and ignored ReparseTag
main()38 int main()
39 {
40 
41   const fs::path cwd = fs::current_path();
42   const TmpDir tmp(cwd);
43   const fs::path junction = tmp.path / "junction";
44   const fs::path real = tmp.path / "real";
45   const fs::path subDir = "sub";
46   fs::create_directories(real / subDir);
47   fs::current_path(tmp.path);
48   BOOST_TEST(std::system("mklink /j junction real") == 0);
49   BOOST_TEST(fs::exists(junction));
50 
51   // Due to a bug there was a dependency on the current path so try the below for all:
52   std::vector<fs::path> paths;
53   paths.push_back(cwd);
54   paths.push_back(junction);
55   paths.push_back(real);
56   paths.push_back(junction / subDir);
57   paths.push_back(real / subDir);
58   for (std::vector<fs::path>::iterator it = paths.begin(); it != paths.end(); ++it)
59   {
60     std::cout << "Testing in " << *it << std::endl;
61     fs::current_path(*it);
62 
63     // Used by canonical, must work too
64     BOOST_TEST(fs::read_symlink(junction) == real);
65 
66     BOOST_TEST(fs::canonical(junction) == real);
67     BOOST_TEST(fs::canonical(junction / subDir) == real / subDir);
68   }
69 
70   // Restore the original current directory so that temp directory can be removed
71   fs::current_path(cwd);
72 
73   return boost::report_errors();
74 }
75 
76 #else // defined(BOOST_FILESYSTEM_HAS_MKLINK)
77 
main()78 int main()
79 {
80   std::cout << "Skipping test as the target system does not support mklink." << std::endl;
81   return 0;
82 }
83 
84 #endif // defined(BOOST_FILESYSTEM_HAS_MKLINK)
85 
86