forked from premiere/premiere-libtorrent
use UNC paths pervasively on windows
This commit is contained in:
parent
3a1e546a6c
commit
f4f1425115
|
@ -234,7 +234,6 @@ set(libtorrent_aux_include_files
|
|||
ip_notifier
|
||||
listen_socket_handle
|
||||
lsd
|
||||
max_path
|
||||
merkle
|
||||
noexcept_movable
|
||||
numeric_cast
|
||||
|
|
|
@ -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 <functional>
|
||||
#include <cstdio>
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -69,8 +69,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <sys/types.h>
|
||||
#include <dirent.h> // for DIR
|
||||
|
||||
#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH
|
||||
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -70,8 +70,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <sys/types.h>
|
||||
#include <dirent.h> // for DIR
|
||||
|
||||
#include "libtorrent/aux_/max_path.hpp" // for TORRENT_MAX_PATH
|
||||
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 <cstring>
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
|
26
src/path.cpp
26
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 <cstring>
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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[] =
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <vector>
|
||||
#include <set>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
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<int, bool> fill_current_directory_caps()
|
||||
std::tuple<int, bool> 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<char>((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<char>((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<std::string> 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<std::string> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue