Skip to content

Commit d5baf63

Browse files
committed
Merge branch 'ps/mingw-creat-excl-fix'
Fix lockfile contention in reftable code on Windows. * ps/mingw-creat-excl-fix: compat/mingw: fix EACCESS when opening files with `O_CREAT | O_EXCL` meson: fix compat sources when compiling with MSVC
2 parents 03633a2 + 0a3dcea commit d5baf63

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

compat/mingw.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include "gettext.h"
2222
#define SECURITY_WIN32
2323
#include <sspi.h>
24+
#include <winternl.h>
25+
26+
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056)
2427

2528
#define HCAST(type, handle) ((type)(intptr_t)handle)
2629

@@ -624,6 +627,8 @@ int mingw_open (const char *filename, int oflags, ...)
624627
wchar_t wfilename[MAX_PATH];
625628
open_fn_t open_fn;
626629

630+
DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, RtlGetLastNtStatus, void);
631+
627632
va_start(args, oflags);
628633
mode = va_arg(args, int);
629634
va_end(args);
@@ -647,6 +652,21 @@ int mingw_open (const char *filename, int oflags, ...)
647652

648653
fd = open_fn(wfilename, oflags, mode);
649654

655+
/*
656+
* Internally, `_wopen()` uses the `CreateFile()` API with CREATE_NEW,
657+
* which may error out with ERROR_ACCESS_DENIED and an NtStatus of
658+
* STATUS_DELETE_PENDING when the file is scheduled for deletion via
659+
* `DeleteFileW()`. The file essentially exists, so we map errno to
660+
* EEXIST instead of EACCESS so that callers don't have to special-case
661+
* this.
662+
*
663+
* This fixes issues for example with the lockfile interface when one
664+
* process has a lock that it is about to commit or release while
665+
* another process wants to acquire it.
666+
*/
667+
if (fd < 0 && create && GetLastError() == ERROR_ACCESS_DENIED &&
668+
INIT_PROC_ADDR(RtlGetLastNtStatus) && RtlGetLastNtStatus() == STATUS_DELETE_PENDING)
669+
errno = EEXIST;
650670
if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) {
651671
DWORD attrs = GetFileAttributesW(wfilename);
652672
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))

meson.build

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,6 @@ if host_machine.system() == 'cygwin'
11151115
]
11161116
elif host_machine.system() == 'windows'
11171117
libgit_sources += [
1118-
'compat/mingw.c',
11191118
'compat/winansi.c',
11201119
'compat/win32/dirent.c',
11211120
'compat/win32/flush.c',
@@ -1142,6 +1141,9 @@ elif host_machine.system() == 'windows'
11421141
libgit_include_directories += 'compat/win32'
11431142
if compiler.get_id() == 'msvc'
11441143
libgit_include_directories += 'compat/vcbuild/include'
1144+
libgit_sources += 'compat/msvc.c'
1145+
else
1146+
libgit_sources += 'compat/mingw.c'
11451147
endif
11461148
endif
11471149

0 commit comments

Comments
 (0)