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 MSVCmain
commit
d5baf636a4
|
@ -21,6 +21,9 @@
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#define SECURITY_WIN32
|
#define SECURITY_WIN32
|
||||||
#include <sspi.h>
|
#include <sspi.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
|
||||||
|
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056)
|
||||||
|
|
||||||
#define HCAST(type, handle) ((type)(intptr_t)handle)
|
#define HCAST(type, handle) ((type)(intptr_t)handle)
|
||||||
|
|
||||||
|
@ -624,6 +627,8 @@ int mingw_open (const char *filename, int oflags, ...)
|
||||||
wchar_t wfilename[MAX_PATH];
|
wchar_t wfilename[MAX_PATH];
|
||||||
open_fn_t open_fn;
|
open_fn_t open_fn;
|
||||||
|
|
||||||
|
DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, RtlGetLastNtStatus, void);
|
||||||
|
|
||||||
va_start(args, oflags);
|
va_start(args, oflags);
|
||||||
mode = va_arg(args, int);
|
mode = va_arg(args, int);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
@ -647,6 +652,21 @@ int mingw_open (const char *filename, int oflags, ...)
|
||||||
|
|
||||||
fd = open_fn(wfilename, oflags, mode);
|
fd = open_fn(wfilename, oflags, mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internally, `_wopen()` uses the `CreateFile()` API with CREATE_NEW,
|
||||||
|
* which may error out with ERROR_ACCESS_DENIED and an NtStatus of
|
||||||
|
* STATUS_DELETE_PENDING when the file is scheduled for deletion via
|
||||||
|
* `DeleteFileW()`. The file essentially exists, so we map errno to
|
||||||
|
* EEXIST instead of EACCESS so that callers don't have to special-case
|
||||||
|
* this.
|
||||||
|
*
|
||||||
|
* This fixes issues for example with the lockfile interface when one
|
||||||
|
* process has a lock that it is about to commit or release while
|
||||||
|
* another process wants to acquire it.
|
||||||
|
*/
|
||||||
|
if (fd < 0 && create && GetLastError() == ERROR_ACCESS_DENIED &&
|
||||||
|
INIT_PROC_ADDR(RtlGetLastNtStatus) && RtlGetLastNtStatus() == STATUS_DELETE_PENDING)
|
||||||
|
errno = EEXIST;
|
||||||
if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) {
|
if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) {
|
||||||
DWORD attrs = GetFileAttributesW(wfilename);
|
DWORD attrs = GetFileAttributesW(wfilename);
|
||||||
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
|
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
|
|
@ -1115,7 +1115,6 @@ if host_machine.system() == 'cygwin'
|
||||||
]
|
]
|
||||||
elif host_machine.system() == 'windows'
|
elif host_machine.system() == 'windows'
|
||||||
libgit_sources += [
|
libgit_sources += [
|
||||||
'compat/mingw.c',
|
|
||||||
'compat/winansi.c',
|
'compat/winansi.c',
|
||||||
'compat/win32/dirent.c',
|
'compat/win32/dirent.c',
|
||||||
'compat/win32/flush.c',
|
'compat/win32/flush.c',
|
||||||
|
@ -1142,6 +1141,9 @@ elif host_machine.system() == 'windows'
|
||||||
libgit_include_directories += 'compat/win32'
|
libgit_include_directories += 'compat/win32'
|
||||||
if compiler.get_id() == 'msvc'
|
if compiler.get_id() == 'msvc'
|
||||||
libgit_include_directories += 'compat/vcbuild/include'
|
libgit_include_directories += 'compat/vcbuild/include'
|
||||||
|
libgit_sources += 'compat/msvc.c'
|
||||||
|
else
|
||||||
|
libgit_sources += 'compat/mingw.c'
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue