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