diff --git a/main/src/hadd.cxx b/main/src/hadd.cxx index 89df5631919eb..7cf380c75ac86 100644 --- a/main/src/hadd.cxx +++ b/main/src/hadd.cxx @@ -614,6 +614,20 @@ static Int_t ParseFilterFile(const std::optional &filterFileName, return 0; } +static bool FilesAreEquivalent(std::string_view source, std::string_view target) +{ + const bool sourceIsLocal = source.find_first_of("://") == std::string_view::npos; + const bool targetIsLocal = target.find_first_of("://") == std::string_view::npos; + if (sourceIsLocal != targetIsLocal) + return false; + + // We cannot use std::filesystem functions for remote files. + if (!sourceIsLocal) + return source == target; + + return std::filesystem::exists(target) && std::filesystem::equivalent(source, target); +} + int main(int argc, char **argv) { InitLog("hadd", kDefaultHaddVerbosity); @@ -718,7 +732,7 @@ int main(int argc, char **argv) << (argv[a] + 1) << std::endl; if (!args.fSkipErrors) return 1; - } else if (std::filesystem::exists(targetname) && std::filesystem::equivalent(line, targetname)) { + } else if (FilesAreEquivalent(line, targetname)) { Err() << "file " << line << " cannot be both the target and an input!\n"; if (!args.fSkipErrors) return 1; @@ -729,12 +743,12 @@ int main(int argc, char **argv) } } } else { - const std::string line = argv[a]; - if (gSystem->AccessPathName(line.c_str(), kReadPermission) == kTRUE) { + const char *line = argv[a]; + if (gSystem->AccessPathName(line, kReadPermission) == kTRUE) { Err() << "could not validate argument \"" << line << "\" as input file " << std::endl; if (!args.fSkipErrors) return 1; - } else if (std::filesystem::exists(targetname) && std::filesystem::equivalent(line, targetname)) { + } else if (FilesAreEquivalent(line, targetname)) { Err() << "file " << line << " cannot be both the target and an input!\n"; if (!args.fSkipErrors) return 1; diff --git a/roottest/root/io/hadd/CMakeLists.txt b/roottest/root/io/hadd/CMakeLists.txt index 486b033b07183..2efff2d957cae 100644 --- a/roottest/root/io/hadd/CMakeLists.txt +++ b/roottest/root/io/hadd/CMakeLists.txt @@ -251,8 +251,22 @@ ROOTTEST_ADD_TEST(test_hadd_args_quieter ################################################################ configure_file(file1_20706.root . COPYONLY) configure_file(file2_20706.root . COPYONLY) +configure_file(filelist_20872.txt . COPYONLY) ROOTTEST_ADD_TEST(test_hadd_regr_20706 PRECMD ${CMAKE_COMMAND} -E rm -f merged_20706.root COMMAND ${ROOT_hadd_CMD} -f merged_20706.root file1_20706.root file2_20706.root ) + +if(davix AND NOT MSVC) +ROOTTEST_ADD_TEST(test_hadd_regr_20872 + PRECMD ${CMAKE_COMMAND} -E rm -f merged_20872.root + COMMAND ${ROOT_hadd_CMD} -f merged_20872.root root://eospublic.cern.ch//eos/root-eos/h1/dstarmb.root +) + +ROOTTEST_ADD_TEST(test_hadd_regr_20872_2 + PRECMD ${CMAKE_COMMAND} -E rm -f merged_20872_2.root + COMMAND ${ROOT_hadd_CMD} -f root://eospublic.cern.ch//eos/root-eos/h1/dstarmb.root @filelist_20872.txt + PASSREGEX "root://eospublic.cern.ch//eos/root-eos/h1/dstarmb.root cannot be both the target and an input!" +) +endif() diff --git a/roottest/root/io/hadd/filelist_20872.txt b/roottest/root/io/hadd/filelist_20872.txt new file mode 100644 index 0000000000000..e8e923f71578f --- /dev/null +++ b/roottest/root/io/hadd/filelist_20872.txt @@ -0,0 +1,2 @@ +root://eospublic.cern.ch//eos/root-eos/h1/dstarmb.root +root://eospublic.cern.ch//eos/root-eos/h1/dstarmb.root