Skip to content

Commit d28cc4d

Browse files
committed
mingw: special-case open(symlink, O_CREAT | O_EXCL)
The `_wopen()` function would gladly follow a symbolic link to a non-existent file and create it when given above-mentioned flags. Git expects the `open()` call to fail, though. So let's add yet another work-around to pretend that Windows behaves like Linux. This is required to let t4115.8(--reject removes .rej symlink if it exists) pass on Windows when enabling the MSYS2 runtime's symbolic link support. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 4b555ea commit d28cc4d

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

compat/mingw.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ int mingw_open (const char *filename, int oflags, ...)
858858
int fd, create = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
859859
wchar_t wfilename[MAX_LONG_PATH];
860860
open_fn_t open_fn;
861+
WIN32_FILE_ATTRIBUTE_DATA fdata;
861862

862863
DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, RtlGetLastNtStatus, void);
863864

@@ -891,6 +892,19 @@ int mingw_open (const char *filename, int oflags, ...)
891892
else if (xutftowcs_long_path(wfilename, filename) < 0)
892893
return -1;
893894

895+
/*
896+
* When `symlink` exists and is a symbolic link pointing to a
897+
* non-existing file, `_wopen(symlink, O_CREAT | O_EXCL)` would
898+
* create that file. Not what we want: Linux would say `EEXIST`
899+
* in that instance, which is therefore what Git expects.
900+
*/
901+
if (create &&
902+
GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata) &&
903+
(fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
904+
errno = EEXIST;
905+
return -1;
906+
}
907+
894908
fd = open_fn(wfilename, oflags, mode);
895909

896910
/*

0 commit comments

Comments
 (0)