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 ,
@@ -331,34 +351,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
331
351
332
352
int mingw_unlink (const char * pathname )
333
353
{
334
- int ret , tries = 0 ;
354
+ int tries = 0 ;
335
355
wchar_t wpathname [MAX_LONG_PATH ];
336
356
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
337
357
return -1 ;
338
358
339
359
if (DeleteFileW (wpathname ))
340
360
return 0 ;
341
361
342
- /* read-only files cannot be removed */
343
- _wchmod (wpathname , 0666 );
344
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
362
+ do {
363
+ /* read-only files cannot be removed */
364
+ _wchmod (wpathname , 0666 );
365
+ if (!_wunlink (wpathname ))
366
+ return 0 ;
345
367
if (!is_file_in_use_error (GetLastError ()))
346
368
break ;
347
- /*
348
- * We assume that some other process had the source or
349
- * destination file open at the wrong moment and retry.
350
- * In order to give the other process a higher chance to
351
- * complete its operation, we give up our time slice now.
352
- * If we have to retry again, we do sleep a bit.
353
- */
354
- Sleep (delay [tries ]);
355
- tries ++ ;
356
- }
357
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
358
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
359
- "Should I try again?" , pathname ))
360
- ret = _wunlink (wpathname );
361
- return ret ;
369
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
370
+ "Should I try again?" , pathname ));
371
+ return -1 ;
362
372
}
363
373
364
374
static int is_dir_empty (const wchar_t * wpath )
@@ -385,7 +395,7 @@ static int is_dir_empty(const wchar_t *wpath)
385
395
386
396
int mingw_rmdir (const char * pathname )
387
397
{
388
- int ret , tries = 0 ;
398
+ int tries = 0 ;
389
399
wchar_t wpathname [MAX_LONG_PATH ];
390
400
struct stat st ;
391
401
@@ -411,7 +421,11 @@ int mingw_rmdir(const char *pathname)
411
421
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
412
422
return -1 ;
413
423
414
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
424
+ do {
425
+ if (!_wrmdir (wpathname )) {
426
+ invalidate_lstat_cache ();
427
+ return 0 ;
428
+ }
415
429
if (!is_file_in_use_error (GetLastError ()))
416
430
errno = err_win_to_posix (GetLastError ());
417
431
if (errno != EACCES )
@@ -420,23 +434,9 @@ int mingw_rmdir(const char *pathname)
420
434
errno = ENOTEMPTY ;
421
435
break ;
422
436
}
423
- /*
424
- * We assume that some other process had the source or
425
- * destination file open at the wrong moment and retry.
426
- * In order to give the other process a higher chance to
427
- * complete its operation, we give up our time slice now.
428
- * If we have to retry again, we do sleep a bit.
429
- */
430
- Sleep (delay [tries ]);
431
- tries ++ ;
432
- }
433
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
434
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
435
- "Should I try again?" , pathname ))
436
- ret = _wrmdir (wpathname );
437
- if (!ret )
438
- invalidate_lstat_cache ();
439
- return ret ;
437
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
438
+ "Should I try again?" , pathname ));
439
+ return -1 ;
440
440
}
441
441
442
442
static inline int needs_hiding (const char * path )
@@ -2440,20 +2440,8 @@ int mingw_rename(const char *pold, const char *pnew)
2440
2440
SetFileAttributesW (wpnew , attrs );
2441
2441
}
2442
2442
}
2443
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2444
- /*
2445
- * We assume that some other process had the source or
2446
- * destination file open at the wrong moment and retry.
2447
- * In order to give the other process a higher chance to
2448
- * complete its operation, we give up our time slice now.
2449
- * If we have to retry again, we do sleep a bit.
2450
- */
2451
- Sleep (delay [tries ]);
2452
- tries ++ ;
2453
- goto repeat ;
2454
- }
2455
2443
if (gle == ERROR_ACCESS_DENIED &&
2456
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2444
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2457
2445
"Should I try again?" , pold , pnew ))
2458
2446
goto repeat ;
2459
2447
0 commit comments