aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstar-dm <star-dm@yandex-team.com>2024-04-03 10:56:31 +0300
committerstar-dm <star-dm@yandex-team.com>2024-04-03 11:09:31 +0300
commitd2527272d41073b1399b902b3a59218b894c8022 (patch)
tree770382a95a6fc26aba7d037dc5d3a85b11ef404d
parente2305ee33e2fd860e215bdba2530a9a18ef6464f (diff)
downloadydb-d2527272d41073b1399b902b3a59218b894c8022.tar.gz
fixed MakeTempName() for paths > MAX_PATH
added tests fixed MakeTempName() for paths > MAX_PATH d3aee81b508fa0de3fea66b71618981594f262e4
-rw-r--r--build/long-path.manifest8
-rw-r--r--util/system/mktemp.cpp30
-rw-r--r--util/system/mktemp_ut.cpp41
-rw-r--r--util/system/ut/ya.make4
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)