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+
3843void 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+
534555int 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 ;
0 commit comments