Commit 3a7d3923 authored by Tamar Christina's avatar Tamar Christina Committed by Marge Bot

Windows: make openTempFile fully atomic.

parent c76cc0c6
Pipeline #10084 failed with stages
in 408 minutes and 50 seconds
......@@ -158,6 +158,11 @@ bool getTempFileNameErrorNo (wchar_t* pathName, wchar_t* prefix,
wchar_t* suffix, uint32_t uUnique,
wchar_t* tempFileName)
{
int retry = 5;
bool success = false;
while (retry > 0 && !success)
{
// TODO: This needs to handle long file names.
if (!GetTempFileNameW(pathName, prefix, uUnique, tempFileName))
{
maperrno();
......@@ -167,7 +172,6 @@ bool getTempFileNameErrorNo (wchar_t* pathName, wchar_t* prefix,
wchar_t* drive = malloc (sizeof(wchar_t) * _MAX_DRIVE);
wchar_t* dir = malloc (sizeof(wchar_t) * _MAX_DIR);
wchar_t* fname = malloc (sizeof(wchar_t) * _MAX_FNAME);
bool success = true;
if (_wsplitpath_s (tempFileName, drive, _MAX_DRIVE, dir, _MAX_DIR,
fname, _MAX_FNAME, NULL, 0) != 0)
{
......@@ -183,13 +187,25 @@ bool getTempFileNameErrorNo (wchar_t* pathName, wchar_t* prefix,
else
swprintf_s(tempFileName, MAX_PATH, L"%s\%s\%s%s",
drive, dir, fname, suffix);
MoveFileW(temp, tempFileName);
success
= MoveFileExW(temp, tempFileName, MOVEFILE_WRITE_THROUGH
| MOVEFILE_COPY_ALLOWED) != 0;
errno = 0;
if (!success && (GetLastError () != ERROR_FILE_EXISTS || --retry < 0))
{
success = false;
maperrno ();
DeleteFileW (temp);
}
free(temp);
}
free(drive);
free(dir);
free(fname);
}
return success;
}
......
......@@ -28,6 +28,8 @@
* Add `Functor`, `Applicative`, `Monad`, `Alternative`, `MonadPlus`,
`Generic` and `Generic1` instances to `Kleisli`
* `openTempFile` is now fully atomic and thread-safe on Windows.
## 4.13.0.0 *TBA*
* Bundled with GHC *TBA*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment