aboutsummaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
Diffstat (limited to 'compat')
-rw-r--r--compat/mingw.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 939f938fe2..cf4f3c92e7 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);
/*
@@ -1225,18 +1239,16 @@ char *mingw_getcwd(char *pointer, int len)
{
wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
DWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);
+ HANDLE hnd;
if (!ret || ret >= ARRAY_SIZE(cwd)) {
errno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());
return NULL;
}
- ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
- if (!ret && GetLastError() == ERROR_ACCESS_DENIED) {
- HANDLE hnd = CreateFileW(cwd, 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (hnd == INVALID_HANDLE_VALUE)
- return NULL;
+ hnd = CreateFileW(cwd, 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hnd != INVALID_HANDLE_VALUE) {
ret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);
CloseHandle(hnd);
if (!ret || ret >= ARRAY_SIZE(wpointer))
@@ -1245,13 +1257,11 @@ char *mingw_getcwd(char *pointer, int len)
return NULL;
return pointer;
}
- if (!ret || ret >= ARRAY_SIZE(wpointer))
- return NULL;
- if (GetFileAttributesW(wpointer) == INVALID_FILE_ATTRIBUTES) {
+ if (GetFileAttributesW(cwd) == INVALID_FILE_ATTRIBUTES) {
errno = ENOENT;
return NULL;
}
- if (xwcstoutf(pointer, wpointer, len) < 0)
+ if (xwcstoutf(pointer, cwd, len) < 0)
return NULL;
convert_slashes(pointer);
return pointer;