add workarounds for UNC path bugs in std::filesystem::exists() on mingw

The mingw implementation of `std::filesystem::exists()` doesn't work
for UNC paths, even if the referenced file or directory exists. However,
both `std::filesystem::is_directory()` and
`std::filesystem::is_regular_file()` do work; so let's use those
instead of `…exists()`.

The result was that mkvmerge & MKVToolNix GUI couldn't find base
directories for Blu-rays & DVDs when UNC paths were used.

Corresponding gcc bug:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99311

Part of the fix of #3037.
This commit is contained in:
Moritz Bunkus 2021-03-01 23:07:16 +01:00
parent 0c50b9f1c9
commit 0e7473d5ad
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
13 changed files with 20 additions and 21 deletions

View File

@ -132,7 +132,7 @@ locate_and_parse(std::filesystem::path const &location) {
return {};
auto disc_library_dir = base_dir / "META" / "DL";
if (!std::filesystem::exists(disc_library_dir) || !std::filesystem::is_directory(disc_library_dir))
if (!std::filesystem::is_directory(disc_library_dir))
return {};
mxdebug_if(debug, fmt::format("found DL directory at {}\n", disc_library_dir));
@ -170,7 +170,7 @@ locate_and_parse_for_language(std::filesystem::path const &location,
return {};
auto disc_library_file = base_dir / "META" / "DL" / fmt::format("bdmt_{}.xml", language);
if (!std::filesystem::exists(disc_library_file))
if (!std::filesystem::is_regular_file(disc_library_file))
return {};
mxdebug_if(debug, fmt::format("found DL file for language {} at {}\n", language, disc_library_file));

View File

@ -70,7 +70,7 @@ locate_and_parse_for_title(std::filesystem::path const &location,
return {};
auto track_chapter_names_dir = base_dir / "META" / "TN";
if (!std::filesystem::exists(track_chapter_names_dir) || !std::filesystem::is_directory(track_chapter_names_dir))
if (!std::filesystem::is_directory(track_chapter_names_dir))
return {};
mxdebug_if(debug, fmt::format("found TN directory at {}\n", track_chapter_names_dir));

View File

@ -58,7 +58,7 @@ find_other_file_impl(std::filesystem::path const &reference_file_name,
return {};
auto file_name = base_dir / other_file_name;
if (std::filesystem::exists(file_name))
if (std::filesystem::is_regular_file(file_name))
return file_name;
return {};

View File

@ -136,10 +136,9 @@ maybe_parse_dvd(std::string const &file_name,
if (mtx::regex::match(cleaned_file_name, mtx::regex::jp::Regex{"\\.(bup|ifo|vob)$", "i"}))
dvd_dir = dvd_dir.parent_path();
else if ( !std::filesystem::exists(dvd_dir)
|| !std::filesystem::is_directory(dvd_dir)
|| ( !std::filesystem::exists(dvd_dir / "VIDEO_TS.IFO")
&& !std::filesystem::exists(dvd_dir / "VIDEO_TS" / "VIDEO_TS.IFO")))
else if ( !std::filesystem::is_directory(dvd_dir)
|| ( !std::filesystem::is_regular_file(dvd_dir / "VIDEO_TS.IFO")
&& !std::filesystem::is_regular_file(dvd_dir / "VIDEO_TS" / "VIDEO_TS.IFO")))
return {};
auto titles_and_timestamps = parse_dvd(dvd_dir.u8string());

View File

@ -66,7 +66,7 @@ get_application_data_folder() {
// If $HOME/.mkvtoolnix exists already then keep using it to avoid
// losing existing user configuration.
auto old_default_folder = mtx::fs::to_path(home) / ".mkvtoolnix";
if (std::filesystem::exists(old_default_folder))
if (std::filesystem::is_directory(old_default_folder))
return old_default_folder;
// If XDG_CONFIG_HOME is set then use that folder.
@ -114,7 +114,7 @@ get_current_exe_path([[maybe_unused]] std::string const &argv0) {
#else // SYS_APPLE
auto exe = mtx::fs::to_path("/proc/self/exe");
if (std::filesystem::exists(exe)) {
if (std::filesystem::is_regular_file(exe)) {
auto exe_path = std::filesystem::read_symlink(exe);
return mtx::fs::absolute(exe_path).parent_path();
@ -124,7 +124,7 @@ get_current_exe_path([[maybe_unused]] std::string const &argv0) {
return std::filesystem::current_path();
exe = mtx::fs::absolute(argv0);
if (std::filesystem::exists(exe))
if (std::filesystem::is_regular_file(exe))
return exe.parent_path();
return std::filesystem::current_path();

View File

@ -169,7 +169,7 @@ get_current_exe_path(std::string const &) {
bool
is_installed() {
auto file_to_test = get_installation_path() / "data" / "portable-app";
return !std::filesystem::exists(file_to_test);
return !std::filesystem::is_regular_file(file_to_test);
}
uint64_t

View File

@ -101,7 +101,7 @@ file_target_c::file_target_c(std::filesystem::path file_name)
if (!mtx::fs::is_absolute(m_file_name))
m_file_name = std::filesystem::temp_directory_path() / m_file_name;
if (std::filesystem::exists(m_file_name)) {
if (std::filesystem::is_regular_file(m_file_name)) {
std::error_code ec;
std::filesystem::remove(m_file_name, ec);
}
@ -110,7 +110,7 @@ file_target_c::file_target_c(std::filesystem::path file_name)
void
file_target_c::log_line(std::string const &message) {
try {
mm_text_io_c out(std::make_shared<mm_file_io_c>(m_file_name.u8string(), std::filesystem::exists(m_file_name) ? MODE_WRITE : MODE_CREATE));
mm_text_io_c out(std::make_shared<mm_file_io_c>(m_file_name.u8string(), std::filesystem::is_regular_file(m_file_name) ? MODE_WRITE : MODE_CREATE));
out.setFilePointer(0, libebml::seek_end);
out.puts(format_line(message));
} catch (mtx::mm_io::exception &ex) {

View File

@ -84,7 +84,7 @@ mm_file_io_private_c::mm_file_io_private_c(std::string const &p_file_name,
void
mm_file_io_c::prepare_path(const std::string &path) {
auto directory = mtx::fs::to_path(path).parent_path();
if (directory.empty() || std::filesystem::exists(directory))
if (directory.empty() || std::filesystem::is_directory(directory))
return;
std::error_code error_code;

View File

@ -204,7 +204,7 @@ mm_file_io_c::prepare_path(std::string const &path) {
auto directory = mtx::fs::to_path(normalized_path).parent_path();
if (directory.empty() || std::filesystem::exists(directory))
if (directory.empty() || std::filesystem::is_directory(directory))
return;
auto is_unc = normalized_path.substr(0, 2) == "\\\\"s;
@ -230,7 +230,7 @@ mm_file_io_c::prepare_path(std::string const &path) {
}
for (auto itr = to_check.rbegin(), end = to_check.rend(); itr != end; ++itr) {
if (std::filesystem::exists(*itr))
if (std::filesystem::is_directory(*itr))
continue;
std::error_code error_code;

View File

@ -258,7 +258,7 @@ extract_cli_parser_c::set_cli_mode() {
mxdebug_if(m_debug, fmt::format("set_cli_mode: new mode is single\n"));
} else if (std::filesystem::exists(mtx::fs::to_path(m_current_arg))) {
} else if (std::filesystem::is_regular_file(mtx::fs::to_path(m_current_arg))) {
m_cli_type = cli_type_e::multiple;
m_options.m_file_name = m_current_arg;

View File

@ -567,7 +567,7 @@ Tab::addAttachmentsFromIdentifiedBluray(mtx::bluray::disc_library::info_t const
fileName = thumbnail.m_file_name;
}
if (fileName.empty() || !std::filesystem::exists(fileName))
if (fileName.empty() || !std::filesystem::is_regular_file(fileName))
return;
auto attachment = prepareFileForAttaching(Q(fileName.u8string()), true);

View File

@ -39,7 +39,7 @@ sanitizeDirectory(QString const &directory,
auto newPath = oldPath;
auto ec = std::error_code{};
while ( !(std::filesystem::exists(newPath, ec) && std::filesystem::is_directory(newPath, ec))
while ( !std::filesystem::is_directory(newPath, ec)
&& !newPath.parent_path().empty()
&& (newPath.parent_path() != newPath))
newPath = newPath.parent_path();

View File

@ -902,7 +902,7 @@ Settings::exeWithPath(QString const &exe) {
#endif // SYS_WINDOWS
for (auto const &potentialExe : potentialExes)
if (std::filesystem::exists(potentialExe))
if (std::filesystem::is_regular_file(potentialExe))
return QDir::toNativeSeparators(to_qs(potentialExe.u8string()));
auto location = QStandardPaths::findExecutable(to_qs(program.u8string()));