30
30
31
31
#define HCAST (type , handle ) ((type)(intptr_t)handle)
32
32
33
- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
34
-
35
33
void open_in_gdb (void )
36
34
{
37
35
static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -207,15 +205,12 @@ static int read_yes_no_answer(void)
207
205
return -1 ;
208
206
}
209
207
210
- static int ask_yes_no_if_possible (const char * format , ... )
208
+ static int ask_yes_no_if_possible (const char * format , va_list args )
211
209
{
212
210
char question [4096 ];
213
211
const char * retry_hook ;
214
- va_list args ;
215
212
216
- va_start (args , format );
217
213
vsnprintf (question , sizeof (question ), format , args );
218
- va_end (args );
219
214
220
215
retry_hook = mingw_getenv ("GIT_ASK_YESNO" );
221
216
if (retry_hook ) {
@@ -240,6 +235,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
240
235
}
241
236
}
242
237
238
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
239
+ {
240
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
241
+ va_list args ;
242
+ int result , saved_errno = errno ;
243
+
244
+ if ((* tries ) < ARRAY_SIZE (delay )) {
245
+ /*
246
+ * We assume that some other process had the file open at the wrong
247
+ * moment and retry. In order to give the other process a higher
248
+ * chance to complete its operation, we give up our time slice now.
249
+ * If we have to retry again, we do sleep a bit.
250
+ */
251
+ Sleep (delay [* tries ]);
252
+ (* tries )++ ;
253
+ return 1 ;
254
+ }
255
+
256
+ va_start (args , format );
257
+ result = ask_yes_no_if_possible (format , args );
258
+ va_end (args );
259
+ errno = saved_errno ;
260
+ return result ;
261
+ }
262
+
243
263
/* Windows only */
244
264
enum hide_dotfiles_type {
245
265
HIDE_DOTFILES_FALSE = 0 ,
@@ -332,37 +352,27 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
332
352
333
353
int mingw_unlink (const char * pathname , int handle_in_use_error )
334
354
{
335
- int ret , tries = 0 ;
355
+ int tries = 0 ;
336
356
wchar_t wpathname [MAX_LONG_PATH ];
337
357
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
338
358
return -1 ;
339
359
340
360
if (DeleteFileW (wpathname ))
341
361
return 0 ;
342
362
343
- /* read-only files cannot be removed */
344
- _wchmod (wpathname , 0666 );
345
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
363
+ do {
364
+ /* read-only files cannot be removed */
365
+ _wchmod (wpathname , 0666 );
366
+ if (!_wunlink (wpathname ))
367
+ return 0 ;
346
368
if (!is_file_in_use_error (GetLastError ()))
347
369
break ;
348
370
if (!handle_in_use_error )
349
- return ret ;
371
+ return -1 ;
350
372
351
- /*
352
- * We assume that some other process had the source or
353
- * destination file open at the wrong moment and retry.
354
- * In order to give the other process a higher chance to
355
- * complete its operation, we give up our time slice now.
356
- * If we have to retry again, we do sleep a bit.
357
- */
358
- Sleep (delay [tries ]);
359
- tries ++ ;
360
- }
361
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
362
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
363
- "Should I try again?" , pathname ))
364
- ret = _wunlink (wpathname );
365
- return ret ;
373
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
374
+ "Should I try again?" , pathname ));
375
+ return -1 ;
366
376
}
367
377
368
378
static int is_dir_empty (const wchar_t * wpath )
@@ -389,7 +399,7 @@ static int is_dir_empty(const wchar_t *wpath)
389
399
390
400
int mingw_rmdir (const char * pathname )
391
401
{
392
- int ret , tries = 0 ;
402
+ int tries = 0 ;
393
403
wchar_t wpathname [MAX_LONG_PATH ];
394
404
struct stat st ;
395
405
@@ -415,7 +425,11 @@ int mingw_rmdir(const char *pathname)
415
425
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
416
426
return -1 ;
417
427
418
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
428
+ do {
429
+ if (!_wrmdir (wpathname )) {
430
+ invalidate_lstat_cache ();
431
+ return 0 ;
432
+ }
419
433
if (!is_file_in_use_error (GetLastError ()))
420
434
errno = err_win_to_posix (GetLastError ());
421
435
if (errno != EACCES )
@@ -424,23 +438,9 @@ int mingw_rmdir(const char *pathname)
424
438
errno = ENOTEMPTY ;
425
439
break ;
426
440
}
427
- /*
428
- * We assume that some other process had the source or
429
- * destination file open at the wrong moment and retry.
430
- * In order to give the other process a higher chance to
431
- * complete its operation, we give up our time slice now.
432
- * If we have to retry again, we do sleep a bit.
433
- */
434
- Sleep (delay [tries ]);
435
- tries ++ ;
436
- }
437
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
438
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
439
- "Should I try again?" , pathname ))
440
- ret = _wrmdir (wpathname );
441
- if (!ret )
442
- invalidate_lstat_cache ();
443
- return ret ;
441
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
442
+ "Should I try again?" , pathname ));
443
+ return -1 ;
444
444
}
445
445
446
446
static inline int needs_hiding (const char * path )
@@ -2650,20 +2650,8 @@ int mingw_rename(const char *pold, const char *pnew)
2650
2650
SetFileAttributesW (wpnew , attrs );
2651
2651
}
2652
2652
}
2653
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2654
- /*
2655
- * We assume that some other process had the source or
2656
- * destination file open at the wrong moment and retry.
2657
- * In order to give the other process a higher chance to
2658
- * complete its operation, we give up our time slice now.
2659
- * If we have to retry again, we do sleep a bit.
2660
- */
2661
- Sleep (delay [tries ]);
2662
- tries ++ ;
2663
- goto repeat ;
2664
- }
2665
2653
if (gle == ERROR_ACCESS_DENIED &&
2666
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2654
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2667
2655
"Should I try again?" , pold , pnew ))
2668
2656
goto repeat ;
2669
2657
0 commit comments