27
27
28
28
#define HCAST (type , handle ) ((type)(intptr_t)handle)
29
29
30
- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
31
-
32
30
void open_in_gdb (void )
33
31
{
34
32
static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -204,15 +202,12 @@ static int read_yes_no_answer(void)
204
202
return -1 ;
205
203
}
206
204
207
- static int ask_yes_no_if_possible (const char * format , ... )
205
+ static int ask_yes_no_if_possible (const char * format , va_list args )
208
206
{
209
207
char question [4096 ];
210
208
const char * retry_hook ;
211
- va_list args ;
212
209
213
- va_start (args , format );
214
210
vsnprintf (question , sizeof (question ), format , args );
215
- va_end (args );
216
211
217
212
retry_hook = mingw_getenv ("GIT_ASK_YESNO" );
218
213
if (retry_hook ) {
@@ -237,6 +232,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
237
232
}
238
233
}
239
234
235
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
236
+ {
237
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
238
+ va_list args ;
239
+ int result , saved_errno = errno ;
240
+
241
+ if ((* tries ) < ARRAY_SIZE (delay )) {
242
+ /*
243
+ * We assume that some other process had the file open at the wrong
244
+ * moment and retry. In order to give the other process a higher
245
+ * chance to complete its operation, we give up our time slice now.
246
+ * If we have to retry again, we do sleep a bit.
247
+ */
248
+ Sleep (delay [* tries ]);
249
+ (* tries )++ ;
250
+ return 1 ;
251
+ }
252
+
253
+ va_start (args , format );
254
+ result = ask_yes_no_if_possible (format , args );
255
+ va_end (args );
256
+ errno = saved_errno ;
257
+ return result ;
258
+ }
259
+
240
260
/* Windows only */
241
261
enum hide_dotfiles_type {
242
262
HIDE_DOTFILES_FALSE = 0 ,
@@ -339,34 +359,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
339
359
340
360
int mingw_unlink (const char * pathname )
341
361
{
342
- int ret , tries = 0 ;
362
+ int tries = 0 ;
343
363
wchar_t wpathname [MAX_LONG_PATH ];
344
364
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
345
365
return -1 ;
346
366
347
367
if (DeleteFileW (wpathname ))
348
368
return 0 ;
349
369
350
- /* read-only files cannot be removed */
351
- _wchmod (wpathname , 0666 );
352
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
370
+ do {
371
+ /* read-only files cannot be removed */
372
+ _wchmod (wpathname , 0666 );
373
+ if (!_wunlink (wpathname ))
374
+ return 0 ;
353
375
if (!is_file_in_use_error (GetLastError ()))
354
376
break ;
355
- /*
356
- * We assume that some other process had the source or
357
- * destination file open at the wrong moment and retry.
358
- * In order to give the other process a higher chance to
359
- * complete its operation, we give up our time slice now.
360
- * If we have to retry again, we do sleep a bit.
361
- */
362
- Sleep (delay [tries ]);
363
- tries ++ ;
364
- }
365
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
366
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
367
- "Should I try again?" , pathname ))
368
- ret = _wunlink (wpathname );
369
- return ret ;
377
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
378
+ "Should I try again?" , pathname ));
379
+ return -1 ;
370
380
}
371
381
372
382
static int is_dir_empty (const wchar_t * wpath )
@@ -393,7 +403,7 @@ static int is_dir_empty(const wchar_t *wpath)
393
403
394
404
int mingw_rmdir (const char * pathname )
395
405
{
396
- int ret , tries = 0 ;
406
+ int tries = 0 ;
397
407
wchar_t wpathname [MAX_LONG_PATH ];
398
408
struct stat st ;
399
409
@@ -419,7 +429,11 @@ int mingw_rmdir(const char *pathname)
419
429
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
420
430
return -1 ;
421
431
422
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
432
+ do {
433
+ if (!_wrmdir (wpathname )) {
434
+ invalidate_lstat_cache ();
435
+ return 0 ;
436
+ }
423
437
if (!is_file_in_use_error (GetLastError ()))
424
438
errno = err_win_to_posix (GetLastError ());
425
439
if (errno != EACCES )
@@ -428,23 +442,9 @@ int mingw_rmdir(const char *pathname)
428
442
errno = ENOTEMPTY ;
429
443
break ;
430
444
}
431
- /*
432
- * We assume that some other process had the source or
433
- * destination file open at the wrong moment and retry.
434
- * In order to give the other process a higher chance to
435
- * complete its operation, we give up our time slice now.
436
- * If we have to retry again, we do sleep a bit.
437
- */
438
- Sleep (delay [tries ]);
439
- tries ++ ;
440
- }
441
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
442
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
443
- "Should I try again?" , pathname ))
444
- ret = _wrmdir (wpathname );
445
- if (!ret )
446
- invalidate_lstat_cache ();
447
- return ret ;
445
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
446
+ "Should I try again?" , pathname ));
447
+ return -1 ;
448
448
}
449
449
450
450
static inline int needs_hiding (const char * path )
@@ -2683,20 +2683,8 @@ int mingw_rename(const char *pold, const char *pnew)
2683
2683
SetFileAttributesW (wpnew , attrs );
2684
2684
}
2685
2685
}
2686
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2687
- /*
2688
- * We assume that some other process had the source or
2689
- * destination file open at the wrong moment and retry.
2690
- * In order to give the other process a higher chance to
2691
- * complete its operation, we give up our time slice now.
2692
- * If we have to retry again, we do sleep a bit.
2693
- */
2694
- Sleep (delay [tries ]);
2695
- tries ++ ;
2696
- goto repeat ;
2697
- }
2698
2686
if (gle == ERROR_ACCESS_DENIED &&
2699
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2687
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2700
2688
"Should I try again?" , pold , pnew ))
2701
2689
goto repeat ;
2702
2690
0 commit comments