cmSystemTools: Add GetDirCase helper function

On Linux, one can set case insensitivity on a per-directory level.
This commit is contained in:
Russell Greene
2024-12-11 10:23:53 -07:00
parent 54e998629d
commit 01d2a64980
2 changed files with 47 additions and 0 deletions

View File

@@ -118,6 +118,12 @@
# include <malloc.h> /* for malloc/free on QNX */
#endif
#ifdef __linux__
# include <linux/fs.h>
# include <sys/ioctl.h>
#endif
#if !defined(_WIN32) && !defined(__ANDROID__)
# include <sys/utsname.h>
#endif
@@ -3941,6 +3947,38 @@ std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes)
return out;
}
cm::optional<cmSystemTools::DirCase> cmSystemTools::GetDirCase(
std::string const& dir)
{
if (!cmSystemTools::FileIsDirectory(dir)) {
return cm::nullopt;
}
#if defined(_WIN32) || defined(__APPLE__)
return DirCase::Insensitive;
#elif defined(__linux__)
int fd = open(dir.c_str(), O_RDONLY);
if (fd == -1) {
// cannot open dir but it exists, assume dir is case sensitive.
return DirCase::Sensitive;
}
int attr = 0;
int ioctl_res = ioctl(fd, FS_IOC_GETFLAGS, &attr);
close(fd);
if (ioctl_res == -1) {
return DirCase::Sensitive;
}
// FS_CASEFOLD_FD from linux/fs.h, in Linux libc-dev 5.4+
// For compat with old libc-dev, define it here.
const int CMAKE_FS_CASEFOLD_FL = 0x40000000;
return (attr & CMAKE_FS_CASEFOLD_FL) != 0 ? DirCase::Insensitive
: DirCase::Sensitive;
#else
return DirCase::Sensitive;
#endif
}
cmsys::Status cmSystemTools::CreateSymlink(std::string const& origName,
std::string const& newName)
{

View File

@@ -584,6 +584,15 @@ public:
static std::string EncodeURL(std::string const& in,
bool escapeSlashes = true);
enum class DirCase
{
Sensitive,
Insensitive,
};
/** Returns nullopt when `dir` is not a valid directory */
static cm::optional<DirCase> GetDirCase(std::string const& dir);
#ifdef _WIN32
struct WindowsFileRetry
{