Skip to content

Commit fa0c282

Browse files
committed
mingw: implement lock_or_unlock_fd_for_appending()
For some reason, t/t5552-skipping-fetch-negotiator.sh fails particularly often on Windows due to racy tracing where the `git upload-pack` and the `git fetch` processes compete for the same file. We just introduced a remedy that uses fcntl(), but Windows does not have fcntl(). So let's implement an alternative. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent a199046 commit fa0c282

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

compat/mingw.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,25 @@ int mingw_chmod(const char *filename, int mode)
514514
return _wchmod(wfilename, mode);
515515
}
516516

517+
int mingw_lock_or_unlock_fd_for_appending(int fd, int lock_it)
518+
{
519+
HANDLE handle = (HANDLE)_get_osfhandle(fd);
520+
OVERLAPPED overlapped = { 0 };
521+
DWORD err;
522+
523+
if (!lock_it && UnlockFileEx(handle, 0, -1, 0, &overlapped))
524+
return 0;
525+
if (lock_it &&
526+
LockFileEx(handle, LOCKFILE_EXCLUSIVE_LOCK, 0, -1, 0, &overlapped))
527+
return 0;
528+
529+
err = GetLastError();
530+
/* LockFileEx() cannot lock pipes */
531+
errno = err == ERROR_INVALID_FUNCTION ?
532+
EBADF : err_win_to_posix(GetLastError());
533+
return -1;
534+
}
535+
517536
/*
518537
* The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
519538
* Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.

compat/mingw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ HANDLE winansi_get_osfhandle(int fd);
397397
* git specific compatibility
398398
*/
399399

400+
int mingw_lock_or_unlock_fd_for_appending(int fd, int lock_it);
401+
#define lock_or_unlock_fd_for_appending mingw_lock_or_unlock_fd_for_appending
402+
400403
#define has_dos_drive_prefix(path) \
401404
(isalpha(*(path)) && (path)[1] == ':' ? 2 : 0)
402405
int mingw_skip_dos_drive_prefix(char **path);

0 commit comments

Comments
 (0)