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