Skip to content

Commit 30a431f

Browse files
committed
mingw: Fix unlink for open files
Fixes git#1653 Signed-off-by: Orgad Shaneh <orgads@gmail.com>
1 parent 1454f0a commit 30a431f

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

compat/mingw.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,17 @@
2929
#include <sspi.h>
3030
#include <wchar.h>
3131
#include <winioctl.h>
32+
#include <ktmw32.h>
3233
#include <winternl.h>
3334

3435
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056)
3536

3637
#define HCAST(type, handle) ((type)(intptr_t)handle)
3738

39+
#ifndef ERROR_TRANSACTIONAL_CONFLICT
40+
#define ERROR_TRANSACTIONAL_CONFLICT 6800
41+
#endif
42+
3843
void open_in_gdb(void)
3944
{
4045
static struct child_process cp = CHILD_PROCESS_INIT;
@@ -162,6 +167,7 @@ int err_win_to_posix(DWORD winerr)
162167
case ERROR_WAIT_NO_CHILDREN: error = ECHILD; break;
163168
case ERROR_WRITE_FAULT: error = EIO; break;
164169
case ERROR_WRITE_PROTECT: error = EROFS; break;
170+
case ERROR_TRANSACTIONAL_CONFLICT: error = EPERM; break;
165171
}
166172
return error;
167173
}
@@ -171,6 +177,7 @@ static inline int is_file_in_use_error(DWORD errcode)
171177
switch (errcode) {
172178
case ERROR_SHARING_VIOLATION:
173179
case ERROR_ACCESS_DENIED:
180+
case ERROR_TRANSACTIONAL_CONFLICT:
174181
return 1;
175182
}
176183

@@ -531,6 +538,20 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
531538
return wbuf;
532539
}
533540

541+
static int do_unlink(const wchar_t *wpathname)
542+
{
543+
#if _WIN32_WINNT >= 0x0600
544+
HANDLE transaction = CreateTransaction(NULL, 0, 0, 0, 0, 0, NULL);
545+
BOOL result = DeleteFileTransactedW(wpathname, transaction);
546+
if (result)
547+
CommitTransaction(transaction);
548+
CloseHandle(transaction);
549+
return result ? 0 : -1;
550+
#else
551+
return _wunlink(wpathname);
552+
#endif
553+
}
554+
534555
int mingw_unlink(const char *pathname, int handle_in_use_error)
535556
{
536557
int tries = 0;
@@ -544,7 +565,7 @@ int mingw_unlink(const char *pathname, int handle_in_use_error)
544565
do {
545566
/* read-only files cannot be removed */
546567
_wchmod(wpathname, 0666);
547-
if (!_wunlink(wpathname))
568+
if (!do_unlink(wpathname))
548569
return 0;
549570
if (!is_file_in_use_error(GetLastError()))
550571
break;

config.mak.uname

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ ifeq ($(uname_S),MINGW)
733733
compat/win32/pthread.o compat/win32/syslog.o \
734734
compat/win32/dirent.o compat/win32/fscache.o compat/win32/wsl.o
735735
BASIC_CFLAGS += -DWIN32
736-
EXTLIBS += -lws2_32
736+
EXTLIBS += -lws2_32 -lktmw32
737737
GITLIBS += git.res
738738
PTHREAD_LIBS =
739739
RC = windres -O coff

0 commit comments

Comments
 (0)