diff options
author | thegeorg <[email protected]> | 2023-12-13 00:08:00 +0300 |
---|---|---|
committer | thegeorg <[email protected]> | 2023-12-13 01:06:43 +0300 |
commit | a1e5a74cdd2ad797c39df87dd0cf7ae05101d45a (patch) | |
tree | 041a058ddcac1182b64e519dceec872645f9c689 | |
parent | beb99e6999dd79068f1a8ea9e311b0fa67d7d939 (diff) |
Support std::filesystem::path in TFile and TFileHandle
-rw-r--r-- | util/system/file.cpp | 98 | ||||
-rw-r--r-- | util/system/file.h | 5 |
2 files changed, 94 insertions, 9 deletions
diff --git a/util/system/file.cpp b/util/system/file.cpp index 761916efe5f..349e2a667ef 100644 --- a/util/system/file.cpp +++ b/util/system/file.cpp @@ -6,6 +6,7 @@ #include "info.h" #include <array> +#include <filesystem> #include <util/string/util.h> #include <util/string/cast.h> @@ -63,7 +64,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 std::filesystem::path& path, EOpenMode oMode) noexcept { ui32 fcMode = 0; EOpenMode createMode = oMode & MaskCreation; Y_ABORT_UNLESS(!IsStupidFlagCombination(oMode), "oMode %d makes no sense", static_cast<int>(oMode)); @@ -74,8 +86,6 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept { oMode |= ARW; } -#ifdef _win_ - switch (createMode) { case OpenExisting: fcMode = OPEN_EXISTING; @@ -111,8 +121,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 +142,45 @@ 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{ + // clang-format: off + std::filesystem::path( + std::u8string_view(reinterpret_cast<const char8_t*>(fName.data()), fName.size())), + // clang-format: on + oMode, + } +{ +} #elif defined(_unix_) +TFileHandle::TFileHandle(const std::filesystem::path& path, EOpenMode oMode) noexcept { + ui32 fcMode = 0; + Y_ABORT_UNLESS(!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 +278,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 +299,24 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept { //temp file if (Fd_ >= 0 && (oMode & Transient)) { - unlink(fName.data()); + std::filesystem::remove(path); } +} + +TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept + : TFileHandle{ + std::filesystem::path(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 +901,30 @@ 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 std::filesystem::path& path, EOpenMode oMode) + : Handle_(path, oMode) + , FileName_(path.string()) + { + if (!Handle_.IsOpen()) { + ythrow TFileError() << "can't open " << FileName_.Quote() << " with mode " << DecodeOpenMode(oMode) << " (" << Hex(oMode.ToBaseType()) << ")"; } } @@ -1102,11 +1172,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 std::filesystem::path& 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 bb42bc7697e..bf5791271df 100644 --- a/util/system/file.h +++ b/util/system/file.h @@ -4,6 +4,7 @@ #include "flock.h" #include <util/generic/flags.h> +#include <util/generic/fwd.h> #include <util/generic/ptr.h> #include <util/generic/noncopyable.h> @@ -76,7 +77,9 @@ public: other.Fd_ = INVALID_FHANDLE; } + TFileHandle(const char* fName, EOpenMode oMode) noexcept; TFileHandle(const TString& fName, EOpenMode oMode) noexcept; + TFileHandle(const std::filesystem::path& path, EOpenMode oMode) noexcept; inline ~TFileHandle() { Close(); @@ -150,7 +153,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 std::filesystem::path& path, EOpenMode oMode); ~TFile(); void Close(); |