From f4f1425115b1336c50fbe52ba1b5674b80c89ed1 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 2 Jul 2017 11:39:06 -0400 Subject: [PATCH] use UNC paths pervasively on windows --- CMakeLists.txt | 1 - examples/make_torrent.cpp | 16 ++- include/libtorrent/Makefile.am | 1 - include/libtorrent/aux_/escape_string.hpp | 3 +- include/libtorrent/aux_/max_path.hpp | 67 ---------- include/libtorrent/aux_/path.hpp | 2 - include/libtorrent/config.hpp | 8 +- include/libtorrent/file.hpp | 2 - src/alert.cpp | 1 - src/create_torrent.cpp | 10 +- src/file.cpp | 7 +- src/path.cpp | 26 ++-- src/storage.cpp | 5 +- src/torrent.cpp | 2 +- src/torrent_info.cpp | 2 + test/main.cpp | 5 +- test/setup_transfer.cpp | 5 +- test/test_file.cpp | 146 +++++++++++++--------- 18 files changed, 130 insertions(+), 179 deletions(-) delete mode 100644 include/libtorrent/aux_/max_path.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 944602bae..49e33d0b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,7 +234,6 @@ set(libtorrent_aux_include_files ip_notifier listen_socket_handle lsd - max_path merkle noexcept_movable numeric_cast diff --git a/examples/make_torrent.cpp b/examples/make_torrent.cpp index bd619d6a2..f3063987a 100644 --- a/examples/make_torrent.cpp +++ b/examples/make_torrent.cpp @@ -36,7 +36,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/storage.hpp" #include "libtorrent/hasher.hpp" #include "libtorrent/create_torrent.hpp" -#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH #include #include @@ -259,17 +258,24 @@ int main(int argc_, char const* argv_[]) try if (full_path[0] != '/') #endif { - char cwd[TORRENT_MAX_PATH]; + char cwd[2048]; #ifdef TORRENT_WINDOWS - _getcwd(cwd, sizeof(cwd)); - full_path = cwd + ("\\" + full_path); +#define getcwd_ _getcwd #else - char const* ret = getcwd(cwd, sizeof(cwd)); +#define getcwd_ getcwd +#endif + + char const* ret = getcwd_(cwd, sizeof(cwd)); if (ret == nullptr) { std::cerr << "failed to get current working directory: " << strerror(errno) << "\n"; return 1; } + +#undef getcwd_ +#ifdef TORRENT_WINDOWS + full_path = cwd + ("\\" + full_path); +#else full_path = cwd + ("/" + full_path); #endif } diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index 266cfaaa4..a28d8c7e3 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -178,7 +178,6 @@ nobase_include_HEADERS = \ aux_/generate_peer_id.hpp \ aux_/io.hpp \ aux_/listen_socket_handle.hpp \ - aux_/max_path.hpp \ aux_/path.hpp \ aux_/merkle.hpp \ aux_/session_call.hpp \ diff --git a/include/libtorrent/aux_/escape_string.hpp b/include/libtorrent/aux_/escape_string.hpp index da5dd7037..8fddf39a9 100644 --- a/include/libtorrent/aux_/escape_string.hpp +++ b/include/libtorrent/aux_/escape_string.hpp @@ -64,7 +64,8 @@ namespace libtorrent { TORRENT_EXTRA_EXPORT std::string maybe_url_encode(std::string const& url); TORRENT_EXTRA_EXPORT string_view trim(string_view); - TORRENT_EXTRA_EXPORT string_view::size_type find(string_view haystack, string_view needle, string_view::size_type pos); + TORRENT_EXTRA_EXPORT string_view::size_type find(string_view haystack + , string_view needle, string_view::size_type pos); #if TORRENT_ABI_VERSION == 1 // deprecated in 1.2 diff --git a/include/libtorrent/aux_/max_path.hpp b/include/libtorrent/aux_/max_path.hpp deleted file mode 100644 index af970fc62..000000000 --- a/include/libtorrent/aux_/max_path.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - -Copyright (c) 2016, Arvid Norberg -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef TORRENT_MAX_PATH_HPP_INCLUDED -#define TORRENT_MAX_PATH_HPP_INCLUDED - -// on windows, NAME_MAX refers to Unicode characters -// on linux it refers to bytes (utf-8 encoded) -// TODO: Make this count Unicode characters instead of bytes on windows - -// windows -#if defined FILENAME_MAX -#define TORRENT_MAX_PATH FILENAME_MAX - -// beos -#elif defined B_PATH_NAME_LENGTH -#define TORRENT_MAX_PATH B_PATH_NAME_LENGTH - -// solaris -#elif defined MAXPATH -#define TORRENT_MAX_PATH MAXPATH - -// none of the above -#else -// this is the maximum number of characters in a -// path element / filename on windows and also on many filesystems commonly used -// on linux -#define TORRENT_MAX_PATH 255 - -#ifdef _MSC_VER -#pragma message ( "unknown platform, assuming the longest path is 255" ) -#else -#warning "unknown platform, assuming the longest path is 255" -#endif - -#endif // FILENAME_MAX - -#endif // TORRENT_MAX_PATH_HPP_INCLUDED diff --git a/include/libtorrent/aux_/path.hpp b/include/libtorrent/aux_/path.hpp index 3d852d13e..fef71c68b 100644 --- a/include/libtorrent/aux_/path.hpp +++ b/include/libtorrent/aux_/path.hpp @@ -69,8 +69,6 @@ POSSIBILITY OF SUCH DAMAGE. #include #include // for DIR -#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH - #undef _FILE_OFFSET_BITS #endif diff --git a/include/libtorrent/config.hpp b/include/libtorrent/config.hpp index 3a265c955..7af286615 100644 --- a/include/libtorrent/config.hpp +++ b/include/libtorrent/config.hpp @@ -229,9 +229,7 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_USE_GETADAPTERSADDRESSES 1 #define TORRENT_HAS_SALEN 0 #define TORRENT_USE_GETIPFORWARDTABLE 1 -#ifndef TORRENT_USE_UNC_PATHS -# define TORRENT_USE_UNC_PATHS 1 -#endif +#define TORRENT_USE_UNC_PATHS 1 // these are emulated on windows #define TORRENT_USE_PREADV 1 #define TORRENT_USE_PWRITEV 1 @@ -273,9 +271,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #define TORRENT_USE_RLIMIT 0 #define TORRENT_HAS_FALLOCATE 0 -#ifndef TORRENT_USE_UNC_PATHS -# define TORRENT_USE_UNC_PATHS 1 -#endif +#define TORRENT_USE_UNC_PATHS 1 // these are emulated on windows #define TORRENT_USE_PREADV 1 #define TORRENT_USE_PWRITEV 1 diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index 70e9903e1..cce185a66 100644 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -70,8 +70,6 @@ POSSIBILITY OF SUCH DAMAGE. #include #include // for DIR -#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH - #undef _FILE_OFFSET_BITS #endif diff --git a/src/alert.cpp b/src/alert.cpp index 513587821..c774633b9 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -51,7 +51,6 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "libtorrent/aux_/escape_string.hpp" // for convert_from_native -#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH namespace libtorrent { diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index 23ac38f33..5305345cf 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -32,7 +32,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/create_torrent.hpp" #include "libtorrent/utf8.hpp" -#include "libtorrent/aux_/escape_string.hpp" // for convert_to_wstring #include "libtorrent/disk_io_thread.hpp" #include "libtorrent/aux_/merkle.hpp" // for merkle_*() #include "libtorrent/torrent_info.hpp" @@ -69,16 +68,17 @@ namespace { file_flags_t get_file_attributes(std::string const& p) { + auto const path = convert_to_native_path_string(p); + #ifdef TORRENT_WINDOWS WIN32_FILE_ATTRIBUTE_DATA attr; - std::wstring path = convert_to_wstring(p); GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &attr); if (attr.dwFileAttributes == INVALID_FILE_ATTRIBUTES) return {}; if (attr.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) return file_storage::flag_hidden; return {}; #else struct ::stat s; - if (::lstat(convert_to_native(p).c_str(), &s) < 0) return {}; + if (::lstat(path.c_str(), &s) < 0) return {}; file_flags_t file_attr = {}; if (s.st_mode & S_IXUSR) file_attr |= file_storage::flag_executable; @@ -94,12 +94,12 @@ namespace { constexpr int MAX_SYMLINK_PATH = 200; char buf[MAX_SYMLINK_PATH]; - std::string f = convert_to_native(path); + std::string f = convert_to_native_path_string(path); int char_read = int(readlink(f.c_str(), buf, MAX_SYMLINK_PATH)); if (char_read < 0) return ""; if (char_read < MAX_SYMLINK_PATH) buf[char_read] = 0; else buf[0] = 0; - return convert_from_native(buf); + return convert_from_native_path(buf); } #endif diff --git a/src/file.cpp b/src/file.cpp index 16f76b874..b232e160d 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -84,13 +84,10 @@ struct iovec #include "libtorrent/aux_/alloca.hpp" #include "libtorrent/file.hpp" -#include "libtorrent/aux_/path.hpp" +#include "libtorrent/aux_/path.hpp" // for convert_to_native_path_string #include "libtorrent/string_util.hpp" -#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH #include -// for convert_to_wstring and convert_to_native -#include "libtorrent/aux_/escape_string.hpp" #include "libtorrent/assert.hpp" #include "libtorrent/aux_/throw.hpp" @@ -391,7 +388,7 @@ static_assert(!(open_mode::sparse & open_mode::attribute_mask), "internal flags #ifdef TORRENT_WINDOWS return convert_from_native_path(m_fd.cFileName); #else - return convert_from_native(m_name); + return convert_from_native_path(m_name.c_str()); #endif } diff --git a/src/path.cpp b/src/path.cpp index 19e15ff2e..4f083b554 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -71,11 +71,9 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/aux_/path.hpp" #include "libtorrent/file.hpp" // for directory #include "libtorrent/string_util.hpp" -#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH #include -// for convert_to_wstring and convert_to_native -#include "libtorrent/aux_/escape_string.hpp" +#include "libtorrent/aux_/escape_string.hpp" // for convert_to_native #include "libtorrent/assert.hpp" #include "libtorrent/aux_/throw.hpp" @@ -132,7 +130,11 @@ namespace libtorrent { } #if defined TORRENT_WINDOWS - std::string convert_from_native_path(wchar_t const* s) { return convert_from_wstring(s); } + std::string convert_from_native_path(wchar_t const* s) + { + if (s[0] == L'\\' && s[1] == L'\\' && s[2] == L'?' && s[3] == L'\\') s += 4; + return convert_from_wstring(s); + } #else std::string convert_from_native_path(char const* s) { return convert_from_native(s); } #endif @@ -165,23 +167,13 @@ namespace { native_path_string convert_to_native_path_string(std::string const& path) { -#ifdef TORRENT_WINDOWS #if TORRENT_USE_UNC_PATHS - std::string prepared_path; // UNC paths must be absolute // network paths are already UNC paths - if (path.substr(0,2) == "\\\\") - prepared_path = path; - else - { - std::string sep_path = path; - std::replace(sep_path.begin(), sep_path.end(), '/', '\\'); - prepared_path = "\\\\?\\" + (is_complete(sep_path) ? sep_path : complete(sep_path)); - } -#else - std::string prepared_path = path; + std::string prepared_path = complete(path); + if (prepared_path.substr(0,2) != "\\\\") + prepared_path = "\\\\?\\" + prepared_path; std::replace(prepared_path.begin(), prepared_path.end(), '/', '\\'); -#endif return convert_to_wstring(prepared_path); #else // TORRENT_WINDOWS diff --git a/src/storage.cpp b/src/storage.cpp index 252598fa1..c19f4a13d 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -73,8 +73,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/disk_buffer_holder.hpp" #include "libtorrent/stat_cache.hpp" #include "libtorrent/hex.hpp" // to_hex -// for convert_to_wstring and convert_to_native -#include "libtorrent/aux_/escape_string.hpp" +//#include "libtorrent/aux_/escape_string.hpp" namespace libtorrent { @@ -233,7 +232,7 @@ namespace libtorrent { #ifdef TORRENT_WINDOWS // don't do full file allocations on network drives - std::wstring file_name = convert_to_wstring(m_save_path); + auto const file_name = convert_to_native_path_string(m_save_path); int const drive_type = GetDriveTypeW(file_name.c_str()); if (drive_type == DRIVE_REMOTE) diff --git a/src/torrent.cpp b/src/torrent.cpp index 066c0cf13..cef3ae2c1 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -8155,7 +8155,7 @@ bool is_downloading_state(int const st) if (m_storage && file >= file_index_t(0)) { file_storage const& st = m_torrent_file->files(); - return combine_path(m_save_path, st.file_path(file)); + return st.file_path(file, m_save_path); } else { diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 8bd4983a7..df5d4873a 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -192,6 +192,8 @@ namespace libtorrent { } #if !TORRENT_USE_UNC_PATHS && defined TORRENT_WINDOWS +#pragma message ("building for windows without UNC paths is deprecated") + // if we're not using UNC paths on windows, there // are certain filenames we're not allowed to use static const char const* reserved_names[] = diff --git a/test/main.cpp b/test/main.cpp index c38a3bf63..2e68ffeb2 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -230,12 +230,12 @@ void change_directory(std::string const& f, error_code& ec) { ec.clear(); + native_path_string const n = convert_to_native_path_string(f); + #ifdef TORRENT_WINDOWS - native_path_string const n = convert_to_wstring(f); if (SetCurrentDirectoryW(n.c_str()) == 0) ec.assign(GetLastError(), system_category()); #else - native_path_string const n = convert_to_native_path_string(f); int ret = ::chdir(n.c_str()); if (ret != 0) ec.assign(errno, system_category()); @@ -430,6 +430,7 @@ int EXPORT main(int argc, char const* argv[]) return 1; } + std::printf("cwd: %s\n", unit_dir.c_str()); unit_test_t& t = _g_unit_tests[i]; if (redirect_stdout || redirect_stderr) diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index 15882cac7..b1868489b 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -810,7 +810,8 @@ setup_transfer(lt::session* ses1, lt::session* ses2, lt::session* ses3 { error_code ec; create_directory("tmp1" + suffix, ec); - std::ofstream file(combine_path("tmp1" + suffix, "temporary").c_str()); + std::string const file_path = combine_path("tmp1" + suffix, "temporary"); + std::ofstream file(file_path.c_str()); t = ::create_torrent(&file, "temporary", piece_size, 9, false); file.close(); if (clear_files) @@ -818,7 +819,7 @@ setup_transfer(lt::session* ses1, lt::session* ses2, lt::session* ses3 remove_all(combine_path("tmp2" + suffix, "temporary"), ec); remove_all(combine_path("tmp3" + suffix, "temporary"), ec); } - std::printf("generated torrent: %s tmp1%s/temporary\n", aux::to_hex(t->info_hash()).c_str(), suffix.c_str()); + std::printf("generated torrent: %s %s\n", aux::to_hex(t->info_hash()).c_str(), file_path.c_str()); } else { diff --git a/test/test_file.cpp b/test/test_file.cpp index 936e402f1..72705940d 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include using namespace lt; @@ -56,11 +57,13 @@ int touch_file(std::string const& filename, int size) file f; error_code ec; if (!f.open(filename, open_mode::write_only, ec)) return -1; + TEST_EQUAL(ec, error_code()); if (ec) return -1; iovec_t b = {v}; std::int64_t written = f.writev(0, b, ec); if (written != int(v.size())) return -3; if (ec) return -3; + TEST_EQUAL(ec, error_code()); return 0; } @@ -447,31 +450,31 @@ TORRENT_TEST(stat_file) TEST_EQUAL(ec, boost::system::errc::no_such_file_or_directory); } -// specificaly UNC tests +// UNC tests #if TORRENT_USE_UNC_PATHS namespace { -std::tuple fill_current_directory_caps() +std::tuple current_directory_caps() { #ifdef TORRENT_WINDOWS - error_code ec; - DWORD dw_maximum_component_length; - DWORD dw_file_system_flags; - if (!GetVolumeInformationA(nullptr, nullptr, 0, nullptr, &dw_maximum_component_length, &dw_file_system_flags, nullptr, 0)) + DWORD maximum_component_length = FILENAME_MAX; + DWORD file_system_flags = 0; + if (GetVolumeInformation(nullptr + , nullptr, 0, nullptr + , &maximum_component_length, &file_system_flags, nullptr, 0) == 0) { - ec.assign(GetLastError(), system_category()); - std::printf("GetVolumeInformation: [%s] %s\n" - , ec.category().name(), ec.message().c_str()); - return std::make_tuple(0, false); + error_code ec(GetLastError(), system_category()); + std::printf("GetVolumeInformation: [%s : %d] %s\n" + , ec.category().name(), ec.value(), ec.message().c_str()); + // ignore errors, this is best-effort } - int maximum_component_length = int(dw_maximum_component_length); - bool support_hard_links = ((dw_file_system_flags & FILE_SUPPORTS_HARD_LINKS) != 0); - return std::make_tuple(maximum_component_length, support_hard_links); + bool const support_hard_links = ((file_system_flags & FILE_SUPPORTS_HARD_LINKS) != 0); + return std::make_tuple(int(maximum_component_length), support_hard_links); #else - return std::make_tuple(TORRENT_MAX_PATH, true); + return std::make_tuple(255, true); #endif } -} +} // anonymous namespace TORRENT_TEST(unc_tests) { @@ -497,7 +500,7 @@ TORRENT_TEST(unc_tests) for (std::string special_name : special_names) { - TEST_EQUAL(touch_file(special_name, 10), 0); + touch_file(special_name, 10); TEST_CHECK(lt::exists(special_name)); lt::remove(special_name, ec); TEST_EQUAL(ec, error_code()); @@ -506,61 +509,88 @@ TORRENT_TEST(unc_tests) int maximum_component_length; bool support_hard_links; - std::tie(maximum_component_length, support_hard_links) = fill_current_directory_caps(); + std::tie(maximum_component_length, support_hard_links) = current_directory_caps(); - if (maximum_component_length > 0) + std::cout << "max file path component length: " << maximum_component_length << "\n" + << "support hard links: " << (support_hard_links?"yes":"no") << "\n"; + + std::string long_dir_name; + maximum_component_length -= 12; + long_dir_name.resize(size_t(maximum_component_length)); + for (int i = 0; i < maximum_component_length; ++i) + long_dir_name[i] = static_cast((i % 26) + 'A'); + + std::string long_file_name1 = combine_path(long_dir_name, long_dir_name); + long_file_name1.back() = '1'; + std::string long_file_name2 = long_file_name1; + long_file_name2.back() = '2'; + + lt::create_directory(long_dir_name, ec); + TEST_EQUAL(ec, error_code()); + if (ec) { - std::string long_component_name; - long_component_name.resize(size_t(maximum_component_length)); - for (int i = 0; i < maximum_component_length; ++i) - long_component_name[i] = static_cast((i % 26) + 'A'); + std::cout << "create_directory \"" << long_dir_name << "\" failed: " << ec.message() << "\n"; + std::wcout << convert_to_native_path_string(long_dir_name) << L"\n"; + } + TEST_CHECK(lt::exists(long_dir_name)); + TEST_CHECK(lt::is_directory(long_dir_name, ec)); + TEST_EQUAL(ec, error_code()); + if (ec) + { + std::cout << "is_directory \"" << long_dir_name << "\" failed " << ec.message() << "\n"; + std::wcout << convert_to_native_path_string(long_dir_name) << L"\n"; + } - std::string long_file_name1 = combine_path(long_component_name, long_component_name); - long_file_name1.back() = '1'; - std::string long_file_name2 { long_file_name1 }; - long_file_name2.back() = '2'; + touch_file(long_file_name1, 10); + TEST_CHECK(lt::exists(long_file_name1)); - lt::create_directory(long_component_name, ec); - TEST_EQUAL(ec, error_code()); - TEST_CHECK(lt::exists(long_component_name)); - TEST_CHECK(lt::is_directory(long_component_name, ec)); + lt::rename(long_file_name1, long_file_name2, ec); + TEST_EQUAL(ec, error_code()); + if (ec) + { + std::cout << "rename \"" << long_file_name1 << "\" failed " << ec.message() << "\n"; + std::wcout << convert_to_native_path_string(long_file_name1) << L"\n"; + } + TEST_CHECK(!lt::exists(long_file_name1)); + TEST_CHECK(lt::exists(long_file_name2)); - TEST_EQUAL(touch_file(long_file_name1, 10), 0); - TEST_CHECK(lt::exists(long_file_name1)); + lt::copy_file(long_file_name2, long_file_name1, ec); + TEST_EQUAL(ec, error_code()); + if (ec) + { + std::cout << "copy_file \"" << long_file_name2 << "\" failed " << ec.message() << "\n"; + std::wcout << convert_to_native_path_string(long_file_name2) << L"\n"; + } + TEST_CHECK(lt::exists(long_file_name1)); - lt::rename(long_file_name1, long_file_name2, ec); - TEST_EQUAL(ec, error_code()); - TEST_CHECK(!lt::exists(long_file_name1)); - TEST_CHECK(lt::exists(long_file_name2)); + std::set files; - lt::copy_file(long_file_name2, long_file_name1, ec); + for (lt::directory i(long_dir_name, ec); !i.done(); i.next(ec)) + { + std::string f = i.file(); + files.insert(f); + } + + TEST_EQUAL(files.size(), 4); + + lt::remove(long_file_name1, ec); + TEST_EQUAL(ec, error_code()); + if (ec) + { + std::cout << "remove \"" << long_file_name1 << "\" failed " << ec.message() << "\n"; + std::wcout << convert_to_native_path_string(long_file_name1) << L"\n"; + } + TEST_CHECK(!lt::exists(long_file_name1)); + + if (support_hard_links) + { + lt::hard_link(long_file_name2, long_file_name1, ec); TEST_EQUAL(ec, error_code()); TEST_CHECK(lt::exists(long_file_name1)); - std::set files; - - for (lt::directory i(long_component_name, ec); !i.done(); i.next(ec)) - { - std::string f = i.file(); - files.insert(f); - } - - TEST_EQUAL(files.size(), 4); - lt::remove(long_file_name1, ec); TEST_EQUAL(ec, error_code()); TEST_CHECK(!lt::exists(long_file_name1)); - - if (support_hard_links) - { - lt::hard_link(long_file_name2, long_file_name1, ec); - TEST_EQUAL(ec, error_code()); - TEST_CHECK(lt::exists(long_file_name1)); - - lt::remove(long_file_name1, ec); - TEST_EQUAL(ec, error_code()); - TEST_CHECK(!lt::exists(long_file_name1)); - } } }