diff options
author | star-dm <star-dm@yandex-team.com> | 2024-04-03 10:56:31 +0300 |
---|---|---|
committer | star-dm <star-dm@yandex-team.com> | 2024-04-03 11:09:31 +0300 |
commit | d2527272d41073b1399b902b3a59218b894c8022 (patch) | |
tree | 770382a95a6fc26aba7d037dc5d3a85b11ef404d | |
parent | e2305ee33e2fd860e215bdba2530a9a18ef6464f (diff) | |
download | ydb-d2527272d41073b1399b902b3a59218b894c8022.tar.gz |
fixed MakeTempName() for paths > MAX_PATH
added tests
fixed MakeTempName() for paths > MAX_PATH
d3aee81b508fa0de3fea66b71618981594f262e4
-rw-r--r-- | build/long-path.manifest | 8 | ||||
-rw-r--r-- | util/system/mktemp.cpp | 30 | ||||
-rw-r--r-- | util/system/mktemp_ut.cpp | 41 | ||||
-rw-r--r-- | util/system/ut/ya.make | 4 |
4 files changed, 66 insertions, 17 deletions
diff --git a/build/long-path.manifest b/build/long-path.manifest new file mode 100644 index 0000000000..1195fcc597 --- /dev/null +++ b/build/long-path.manifest @@ -0,0 +1,8 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> + <asmv3:application> + <asmv3:windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> + <ws2:longPathAware>true</ws2:longPathAware> + </asmv3:windowsSettings> + </asmv3:application> +</assembly> diff --git a/util/system/mktemp.cpp b/util/system/mktemp.cpp index 801451263e..9d914ca52b 100644 --- a/util/system/mktemp.cpp +++ b/util/system/mktemp.cpp @@ -15,7 +15,6 @@ extern "C" int mkstemps(char* path, int slen); TString MakeTempName(const char* wrkDir, const char* prefix, const char* extension) { -#ifndef _win32_ TString filePath; if (wrkDir && *wrkDir) { @@ -24,6 +23,19 @@ TString MakeTempName(const char* wrkDir, const char* prefix, const char* extensi filePath += GetSystemTempDir(); } +#ifdef _win32_ + // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea?redirectedfrom=MSDN + const unsigned int DirPathMaxLen = 247; + if (filePath.length() <= DirPathMaxLen) { + // it always takes up to 3 characters, no more + char winFilePath[MAX_PATH]; + if (GetTempFileName(filePath.c_str(), (prefix) ? (prefix) : "yan", 0, + winFilePath)) { + return winFilePath; + } + } +#endif // _win32_ + if (filePath.back() != '/') { filePath += '/'; } @@ -49,22 +61,6 @@ TString MakeTempName(const char* wrkDir, const char* prefix, const char* extensi close(fd); return filePath; } -#else - char tmpDir[MAX_PATH + 1]; // +1 -- for terminating null character - char filePath[MAX_PATH]; - const char* pDir = 0; - - if (wrkDir && *wrkDir) { - pDir = wrkDir; - } else if (GetTempPath(MAX_PATH + 1, tmpDir)) { - pDir = tmpDir; - } - - // it always takes up to 3 characters, no more - if (GetTempFileName(pDir, (prefix) ? (prefix) : "yan", 0, filePath)) { - return filePath; - } -#endif ythrow TSystemError() << "can not create temp name(" << wrkDir << ", " << prefix << ", " << extension << ")"; } diff --git a/util/system/mktemp_ut.cpp b/util/system/mktemp_ut.cpp new file mode 100644 index 0000000000..19bcf70852 --- /dev/null +++ b/util/system/mktemp_ut.cpp @@ -0,0 +1,41 @@ +#include <library/cpp/testing/unittest/registar.h> + +#include <filesystem> + +#include "tempfile.h" + +#include <util/folder/dirut.h> + +Y_UNIT_TEST_SUITE(MakeTempFileSuite) { + static const char TestDir[] = "Test"; + static const char Prefix[] = "PREFIX_____PREFIX"; + static const char Extension[] = "txt"; + static const unsigned int PathSegmentSizeNormal = 55; + static const unsigned int PathSegmentSizeLong = 255; + + Y_UNIT_TEST(TestMakeTempName) { + const TFsPath systemTemp{GetSystemTempDir()}; + UNIT_ASSERT(systemTemp.Exists()); + + for (auto dirNameLength : {PathSegmentSizeNormal, PathSegmentSizeLong}) { + const TFsPath testDir{systemTemp / TestDir}; + testDir.MkDir(); + UNIT_ASSERT(testDir.Exists()); + Y_DEFER { + std::filesystem::remove_all(testDir.c_str()); + }; + + const TString dirName(dirNameLength, 'X'); + const TFsPath dirPath = testDir / dirName; + UNIT_ASSERT(std::filesystem::create_directory(dirPath.GetPath().c_str())); + + TString tempFilePath; + try { + tempFilePath = MakeTempName(dirPath.c_str(), Prefix, Extension); + } catch (const TSystemError& ex) { + Cerr << "Unexpected exception: " << ex.what() << Endl; + } + UNIT_ASSERT(TFsPath{tempFilePath}.Exists()); + } + } +} diff --git a/util/system/ut/ya.make b/util/system/ut/ya.make index f3a170cb61..1a80772a8a 100644 --- a/util/system/ut/ya.make +++ b/util/system/ut/ya.make @@ -83,10 +83,14 @@ ENDIF() IF (OS_WINDOWS) SRCS( system/fs_win_ut.cpp + system/mktemp_ut.cpp ) DEPENDS( util/system/ut/stdin_osfhandle ) + IF (ARCH_X86_64) + WINDOWS_LONG_PATH_MANIFEST() + ENDIF() ENDIF() REQUIREMENTS(ram:12) |