18a8a3430d
Reworked remove() operation to separate POSIX and Windows implementations. On Windows, if the file to be removed is read-only, try to reset the read-only attribute before deleting the file. If deleting fails (other than because the file is already deleted), try to restore the read-only attribute. As a side effect, we were able to remove an implementation detail value from the file_type enum that was used by the old remove() implementation. Added a test for remove() on a read-only file on Windows. Also added tests for remove_all(), including for cases with symlinks, hardlinks and read-only files. Also, corrected mklink /J argument in tests. The command accepts /j (lowercase) to the same effect, but the formal help lists /J (uppercase) to create junctions. Reported in https://github.com/boostorg/filesystem/issues/216.
86 lines
2.4 KiB
C++
86 lines
2.4 KiB
C++
// Boost operations_test.cpp ---------------------------------------------------------//
|
|
|
|
// Copyright Alexander Grund 2020
|
|
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// See http://www.boost.org/LICENSE_1_0.txt
|
|
|
|
// Library home page: http://www.boost.org/libs/filesystem
|
|
|
|
#include <iostream>
|
|
|
|
#if defined(BOOST_FILESYSTEM_HAS_MKLINK)
|
|
|
|
#include <boost/filesystem.hpp>
|
|
#include <boost/system/error_code.hpp>
|
|
#include <boost/core/lightweight_test.hpp>
|
|
#include <cstdlib>
|
|
#include <vector>
|
|
|
|
namespace fs = boost::filesystem;
|
|
|
|
struct TmpDir
|
|
{
|
|
fs::path path;
|
|
TmpDir(const fs::path& base) :
|
|
path(fs::absolute(base) / fs::unique_path())
|
|
{
|
|
fs::create_directories(path);
|
|
}
|
|
~TmpDir()
|
|
{
|
|
boost::system::error_code ec;
|
|
fs::remove_all(path, ec);
|
|
}
|
|
};
|
|
|
|
// Test fs::canonical for various path in a Windows directory junction point
|
|
// This failed before due to broken handling of absolute paths and ignored ReparseTag
|
|
int main()
|
|
{
|
|
|
|
const fs::path cwd = fs::current_path();
|
|
const TmpDir tmp(cwd);
|
|
const fs::path junction = tmp.path / "junction";
|
|
const fs::path real = tmp.path / "real";
|
|
const fs::path subDir = "sub";
|
|
fs::create_directories(real / subDir);
|
|
fs::current_path(tmp.path);
|
|
BOOST_TEST(std::system("mklink /J junction real") == 0);
|
|
BOOST_TEST(fs::exists(junction));
|
|
|
|
// Due to a bug there was a dependency on the current path so try the below for all:
|
|
std::vector< fs::path > paths;
|
|
paths.push_back(cwd);
|
|
paths.push_back(junction);
|
|
paths.push_back(real);
|
|
paths.push_back(junction / subDir);
|
|
paths.push_back(real / subDir);
|
|
for (std::vector< fs::path >::iterator it = paths.begin(); it != paths.end(); ++it)
|
|
{
|
|
std::cout << "Testing in " << *it << std::endl;
|
|
fs::current_path(*it);
|
|
|
|
// Used by canonical, must work too
|
|
BOOST_TEST(fs::read_symlink(junction) == real);
|
|
|
|
BOOST_TEST(fs::canonical(junction) == real);
|
|
BOOST_TEST(fs::canonical(junction / subDir) == real / subDir);
|
|
}
|
|
|
|
// Restore the original current directory so that temp directory can be removed
|
|
fs::current_path(cwd);
|
|
|
|
return boost::report_errors();
|
|
}
|
|
|
|
#else // defined(BOOST_FILESYSTEM_HAS_MKLINK)
|
|
|
|
int main()
|
|
{
|
|
std::cout << "Skipping test as the target system does not support mklink." << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
#endif // defined(BOOST_FILESYSTEM_HAS_MKLINK)
|