aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2023-10-04 09:40:54 +0300
committerthegeorg <thegeorg@yandex-team.com>2023-10-04 09:57:50 +0300
commit7f8a7705f725a78bc94ec3cf24f24efe0beeae18 (patch)
tree2b1dd24872475212d99cecb796666f7b405b788e
parenta5c166c44723147521fb0b9d00a6ee48b5986ded (diff)
downloadydb-7f8a7705f725a78bc94ec3cf24f24efe0beeae18.tar.gz
Support std::filesystem::path in TFile and TFileHandle
-rw-r--r--util/system/file.cpp103
-rw-r--r--util/system/file.h13
2 files changed, 107 insertions, 9 deletions
diff --git a/util/system/file.cpp b/util/system/file.cpp
index 4a261d020c..814b538b6f 100644
--- a/util/system/file.cpp
+++ b/util/system/file.cpp
@@ -63,7 +63,18 @@ static bool IsStupidFlagCombination(EOpenMode oMode) {
return (oMode & (CreateAlways | ForAppend)) == (CreateAlways | ForAppend) || (oMode & (TruncExisting | ForAppend)) == (TruncExisting | ForAppend) || (oMode & (CreateNew | ForAppend)) == (CreateNew | ForAppend);
}
-TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept {
+#if defined(_win_)
+
+static SECURITY_ATTRIBUTES ConvertToSecAttrs(EOpenMode oMode) {
+ bool closeOnExec = (oMode & CloseOnExec);
+ SECURITY_ATTRIBUTES secAttrs;
+ secAttrs.bInheritHandle = closeOnExec ? FALSE : TRUE;
+ secAttrs.lpSecurityDescriptor = nullptr;
+ secAttrs.nLength = sizeof(secAttrs);
+ return secAttrs;
+}
+
+TFileHandle::TFileHandle(const StdFilesystemPath& path, EOpenMode oMode) noexcept {
ui32 fcMode = 0;
EOpenMode createMode = oMode & MaskCreation;
Y_VERIFY(!IsStupidFlagCombination(oMode), "oMode %d makes no sense", static_cast<int>(oMode));
@@ -74,8 +85,6 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept {
oMode |= ARW;
}
-#ifdef _win_
-
switch (createMode) {
case OpenExisting:
fcMode = OPEN_EXISTING;
@@ -111,8 +120,6 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept {
faMode &= ~FILE_WRITE_DATA;
}
- bool inheritHandle = !(oMode & CloseOnExec);
-
ui32 shMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
ui32 attrMode = FILE_ATTRIBUTE_NORMAL;
@@ -134,14 +141,43 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept {
attrMode |= /*FILE_FLAG_NO_BUFFERING |*/ FILE_FLAG_WRITE_THROUGH;
}
- Fd_ = NFsPrivate::CreateFileWithUtf8Name(fName, faMode, shMode, fcMode, attrMode, inheritHandle);
+ SECURITY_ATTRIBUTES secAttrs = ConvertToSecAttrs(oMode);
+
+ Fd_ = ::CreateFileW(
+ path.c_str(),
+ faMode,
+ shMode,
+ &secAttrs,
+ fcMode,
+ attrMode,
+ /* hTemplateHandle = */ nullptr);
if ((oMode & ::ForAppend) && (Fd_ != INVALID_FHANDLE)) {
::SetFilePointer(Fd_, 0, 0, FILE_END);
}
+}
+
+TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept
+ : TFileHandle{
+ std::filesystem::path(
+ std::u8string_view(reinterpret_cast<const char8_t*>(fName.data()), fName.size())),
+ oMode,
+ }
+{
+}
#elif defined(_unix_)
+TFileHandle::TFileHandle(const StdFilesystemPath& path, EOpenMode oMode) noexcept {
+ ui32 fcMode = 0;
+ Y_VERIFY(!IsStupidFlagCombination(oMode), "oMode %d makes no sense", static_cast<int>(oMode));
+ if (!(oMode & MaskRW)) {
+ oMode |= RdWr;
+ }
+ if (!(oMode & AMask)) {
+ oMode |= ARW;
+ }
+ EOpenMode createMode = oMode & MaskCreation;
switch (createMode) {
case OpenExisting:
fcMode = 0;
@@ -239,7 +275,7 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept {
}
do {
- Fd_ = ::open(fName.data(), fcMode, permMode);
+ Fd_ = ::open(path.c_str(), fcMode, permMode);
} while (Fd_ == -1 && errno == EINTR);
#if HAVE_POSIX_FADVISE
@@ -260,11 +296,28 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept {
//temp file
if (Fd_ >= 0 && (oMode & Transient)) {
- unlink(fName.data());
+ #if defined(_ios_) && defined(USE_STL_SYSTEM)
+ ::unlink(path.c_str());
+ #else
+ std::filesystem::remove(path);
+ #endif
}
+}
+
+TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept
+ : TFileHandle{
+ StdFilesystemPath(fName.ConstRef()),
+ oMode,
+ }
+{
+}
#else
#error unsupported platform
#endif
+
+TFileHandle::TFileHandle(const char* fName, EOpenMode oMode) noexcept
+ : TFileHandle(TString(fName), oMode)
+{
}
bool TFileHandle::Close() noexcept {
@@ -849,12 +902,34 @@ public:
{
}
+ inline TImpl(const char* fName, EOpenMode oMode)
+ : Handle_(fName, oMode)
+ , FileName_(fName)
+ {
+ if (!Handle_.IsOpen()) {
+ ythrow TFileError() << "can't open " << FileName_.Quote() << " with mode " << DecodeOpenMode(oMode) << " (" << Hex(oMode.ToBaseType()) << ")";
+ }
+ }
+
inline TImpl(const TString& fName, EOpenMode oMode)
: Handle_(fName, oMode)
, FileName_(fName)
{
if (!Handle_.IsOpen()) {
- ythrow TFileError() << "can't open " << fName.Quote() << " with mode " << DecodeOpenMode(oMode) << " (" << Hex(oMode.ToBaseType()) << ")";
+ ythrow TFileError() << "can't open " << FileName_.Quote() << " with mode " << DecodeOpenMode(oMode) << " (" << Hex(oMode.ToBaseType()) << ")";
+ }
+ }
+
+ inline TImpl(const StdFilesystemPath& path, EOpenMode oMode)
+ : Handle_(path, oMode)
+#if defined(_ios_) && defined(USE_STL_SYSTEM)
+ , FileName_(path)
+#else
+ , FileName_(path.string())
+#endif
+ {
+ if (!Handle_.IsOpen()) {
+ ythrow TFileError() << "can't open " << FileName_.Quote() << " with mode " << DecodeOpenMode(oMode) << " (" << Hex(oMode.ToBaseType()) << ")";
}
}
@@ -1102,11 +1177,21 @@ TFile::TFile(FHANDLE fd, const TString& name)
{
}
+TFile::TFile(const char* fName, EOpenMode oMode)
+ : Impl_(new TImpl(fName, oMode))
+{
+}
+
TFile::TFile(const TString& fName, EOpenMode oMode)
: Impl_(new TImpl(fName, oMode))
{
}
+TFile::TFile(const StdFilesystemPath& path, EOpenMode oMode)
+ : Impl_(new TImpl(path, oMode))
+{
+}
+
TFile::~TFile() = default;
void TFile::Close() {
diff --git a/util/system/file.h b/util/system/file.h
index bb42bc7697..6b5e51cb59 100644
--- a/util/system/file.h
+++ b/util/system/file.h
@@ -8,6 +8,15 @@
#include <util/generic/noncopyable.h>
#include <cstdio>
+#include <filesystem>
+
+#if defined(_ios_) && defined(USE_STL_SYSTEM)
+// Workaround for
+// std::filesystem::path is unavailable: introduced in iOS 13.0
+using StdFilesystemPath = std::string;
+#else
+using StdFilesystemPath = std::filesystem::path;
+#endif
enum EOpenModeFlag {
OpenExisting = 0, // Opens a file. It fails if the file does not exist.
@@ -76,7 +85,9 @@ public:
other.Fd_ = INVALID_FHANDLE;
}
+ TFileHandle(const char* fName, EOpenMode oMode) noexcept;
TFileHandle(const TString& fName, EOpenMode oMode) noexcept;
+ TFileHandle(const StdFilesystemPath& path, EOpenMode oMode) noexcept;
inline ~TFileHandle() {
Close();
@@ -150,7 +161,9 @@ public:
/// Takes ownership of handle, so closes it when the last holder of descriptor dies.
explicit TFile(FHANDLE fd);
TFile(FHANDLE fd, const TString& fname);
+ TFile(const char* fName, EOpenMode oMode);
TFile(const TString& fName, EOpenMode oMode);
+ TFile(const StdFilesystemPath& path, EOpenMode oMode);
~TFile();
void Close();