aboutsummaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-12-18 08:20:25 +0900
committerJunio C Hamano <gitster@pobox.com>2025-12-18 08:20:25 +0900
commit3d86511c12a6136d57fadea7638630550a6deeac (patch)
tree1346325386b1babd8fd4b4495d788a9198d31367 /compat
parente7ef0ca622016d12a85836928a03959de4537c2f (diff)
parentef6dd000ad813fc34a05c4b9055578df13a2eaa6 (diff)
downloadgit-3d86511c12a6136d57fadea7638630550a6deeac.tar.xz
Merge branch 'js/test-symlink-windows' into js/prep-symlink-windows
* js/test-symlink-windows: t7800: work around the MSYS path conversion on Windows t6423: introduce Windows-specific handling for symlinking to /dev/null t1305: skip symlink tests that do not apply to Windows t1006: accommodate for symlink support in MSYS2 t0600: fix incomplete prerequisite for a test case t0301: another fix for Windows compatibility t0001: handle `diff --no-index` gracefully mingw: special-case `open(symlink, O_CREAT | O_EXCL)` apply: symbolic links lack a "trustable executable bit" t9700: accommodate for Windows paths
Diffstat (limited to 'compat')
-rw-r--r--compat/mingw.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 939f938fe2..f09b49ff21 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -629,6 +629,7 @@ int mingw_open (const char *filename, int oflags, ...)
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);
@@ -653,6 +654,19 @@ int mingw_open (const char *filename, int oflags, ...)
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);
/*