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