diff options
author | thegeorg <thegeorg@yandex-team.com> | 2023-10-04 09:40:54 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2023-10-04 09:57:50 +0300 |
commit | 7f8a7705f725a78bc94ec3cf24f24efe0beeae18 (patch) | |
tree | 2b1dd24872475212d99cecb796666f7b405b788e | |
parent | a5c166c44723147521fb0b9d00a6ee48b5986ded (diff) | |
download | ydb-7f8a7705f725a78bc94ec3cf24f24efe0beeae18.tar.gz |
Support std::filesystem::path in TFile and TFileHandle
-rw-r--r-- | util/system/file.cpp | 103 | ||||
-rw-r--r-- | util/system/file.h | 13 |
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(); |