Skip to content

Commit f10d602

Browse files
Copilotcsyongheexpipiplus1
authored
Use 64-bit stat on Windows for large files (#9631)
- [x] Review failing CI logs and identify root cause - [x] Fix Windows unit test compile failure - [x] Run formatting and targeted tests - [ ] Run code review and security scan, then reply to PR comment <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Replace calls to `_wstat32` in `File::exists` and in `slang-io.h/cpp`.</issue_title> > <issue_description>These functions will return false on file sizes bigger than 2gb. We should be calling _wstat64 instead.</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > <comment_new><author>@bmillsNV</author><body> > @csyonghe next steps?</body></comment_new> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #9533 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/shader-slang/slang/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: csyonghe <2652293+csyonghe@users.noreply.github.com> Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com> Co-authored-by: expipiplus1 <857308+expipiplus1@users.noreply.github.com>
1 parent e21bc1b commit f10d602

File tree

2 files changed

+109
-5
lines changed

2 files changed

+109
-5
lines changed

source/core/slang-io.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ namespace Slang
186186
bool File::exists(const String& fileName)
187187
{
188188
#ifdef _WIN32
189-
struct _stat32 statVar;
190-
return ::_wstat32(((String)fileName).toWString(), &statVar) != -1;
189+
struct _stat64 statVar;
190+
return ::_wstat64(((String)fileName).toWString(), &statVar) != -1;
191191
#else
192192
struct stat statVar;
193193
return ::stat(fileName.getBuffer(), &statVar) == 0;
@@ -642,8 +642,8 @@ bool Path::createDirectoryRecursive(const String& path)
642642
{
643643
#ifdef _WIN32
644644
// https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx
645-
struct _stat32 statVar;
646-
if (::_wstat32(String(path).toWString(), &statVar) == 0)
645+
struct _stat64 statVar;
646+
if (::_wstat64(String(path).toWString(), &statVar) == 0)
647647
{
648648
if (statVar.st_mode & _S_IFDIR)
649649
{

tools/slang-unit-test/unit-test-io.cpp

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
#include "../../source/core/slang-io.h"
44
#include "unit-test/slang-unit-test.h"
55

6+
#if SLANG_WINDOWS_FAMILY
7+
#include <windows.h>
8+
#include <winioctl.h>
9+
#endif
10+
#include <limits>
11+
612
using namespace Slang;
713

814
static SlangResult _checkGenerateTemporary()
@@ -16,7 +22,7 @@ static SlangResult _checkGenerateTemporary()
1622
String path;
1723
SLANG_RETURN_ON_FAIL(File::generateTemporary(toSlice("slang-check"), path));
1824

19-
// The path should exist exist
25+
// The path should exist
2026
SLANG_CHECK(File::exists(path));
2127

2228
if (paths.contains(path))
@@ -57,7 +63,105 @@ static SlangResult _checkGenerateTemporary()
5763
return SLANG_OK;
5864
}
5965

66+
#if SLANG_WINDOWS_FAMILY
67+
static SlangResult _setSparseFileSize(const String& path, Int64 size)
68+
{
69+
HANDLE handle = ::CreateFileW(
70+
path.toWString(),
71+
GENERIC_WRITE,
72+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
73+
nullptr,
74+
OPEN_ALWAYS,
75+
FILE_ATTRIBUTE_NORMAL,
76+
nullptr);
77+
if (handle == INVALID_HANDLE_VALUE)
78+
{
79+
return SLANG_FAIL;
80+
}
81+
82+
SlangResult result = SLANG_OK;
83+
DWORD bytesReturned = 0;
84+
if (!::DeviceIoControl(
85+
handle,
86+
FSCTL_SET_SPARSE,
87+
nullptr,
88+
0,
89+
nullptr,
90+
0,
91+
&bytesReturned,
92+
nullptr))
93+
{
94+
result = SLANG_FAIL;
95+
goto cleanup;
96+
}
97+
98+
LARGE_INTEGER offset;
99+
offset.QuadPart = size;
100+
if (!::SetFilePointerEx(handle, offset, nullptr, FILE_BEGIN))
101+
{
102+
result = SLANG_FAIL;
103+
goto cleanup;
104+
}
105+
if (!::SetEndOfFile(handle))
106+
{
107+
result = SLANG_FAIL;
108+
goto cleanup;
109+
}
110+
111+
cleanup:
112+
::CloseHandle(handle);
113+
return result;
114+
}
115+
116+
static SlangResult _checkLargeFileExists()
117+
{
118+
String path;
119+
SLANG_RETURN_ON_FAIL(File::generateTemporary(toSlice("slang-large"), path));
120+
121+
const Int64 kTwoGB = Int64(2) * 1024 * 1024 * 1024;
122+
const Int64 kOneKB = 1024;
123+
const Int64 kLargeFileSize = kTwoGB + kOneKB;
124+
const SlangPathType kInvalidPathType =
125+
static_cast<SlangPathType>(std::numeric_limits<SlangPathTypeIntegral>::max());
126+
SlangPathType pathType = kInvalidPathType;
127+
SlangResult pathTypeResult = SLANG_FAIL;
128+
SlangResult result = SLANG_OK;
129+
if (SLANG_FAILED(_setSparseFileSize(path, kLargeFileSize)))
130+
{
131+
result = SLANG_FAIL;
132+
goto cleanup;
133+
}
134+
135+
SLANG_CHECK(File::exists(path));
136+
137+
pathTypeResult = Path::getPathType(path, &pathType);
138+
if (SLANG_FAILED(pathTypeResult))
139+
{
140+
result = pathTypeResult;
141+
goto cleanup;
142+
}
143+
SLANG_CHECK(pathType == SLANG_PATH_TYPE_FILE);
144+
145+
cleanup:
146+
SlangResult removeResult = File::remove(path);
147+
if (SLANG_FAILED(removeResult))
148+
{
149+
return removeResult;
150+
}
151+
return result;
152+
}
153+
#endif
154+
60155
SLANG_UNIT_TEST(io)
61156
{
62157
SLANG_CHECK(SLANG_SUCCEEDED(_checkGenerateTemporary()));
63158
}
159+
160+
SLANG_UNIT_TEST(ioLargeFileExists)
161+
{
162+
#if SLANG_WINDOWS_FAMILY
163+
SLANG_CHECK(SLANG_SUCCEEDED(_checkLargeFileExists()));
164+
#else
165+
SLANG_IGNORE_TEST
166+
#endif
167+
}

0 commit comments

Comments
 (0)