int fd, create = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
wchar_t wfilename[MAX_PATH];
open_fn_t open_fn;
+ WIN32_FILE_ATTRIBUTE_DATA fdata;
DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, RtlGetLastNtStatus, void);
else if (xutftowcs_path(wfilename, filename) < 0)
return -1;
+ /*
+ * When `symlink` exists and is a symbolic link pointing to a
+ * non-existing file, `_wopen(symlink, O_CREAT | O_EXCL)` would
+ * create that file. Not what we want: Linux would say `EEXIST`
+ * in that instance, which is therefore what Git expects.
+ */
+ if (create &&
+ GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata) &&
+ (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
+ errno = EEXIST;
+ return -1;
+ }
+
fd = open_fn(wfilename, oflags, mode);
/*