16
16
17
17
#define HCAST (type , handle ) ((type)(intptr_t)handle)
18
18
19
- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
20
-
21
19
void open_in_gdb (void )
22
20
{
23
21
static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -194,15 +192,12 @@ static int read_yes_no_answer(void)
194
192
return -1 ;
195
193
}
196
194
197
- static int ask_yes_no_if_possible (const char * format , ... )
195
+ static int ask_yes_no_if_possible (const char * format , va_list args )
198
196
{
199
197
char question [4096 ];
200
198
const char * retry_hook ;
201
- va_list args ;
202
199
203
- va_start (args , format );
204
200
vsnprintf (question , sizeof (question ), format , args );
205
- va_end (args );
206
201
207
202
retry_hook = mingw_getenv ("GIT_ASK_YESNO" );
208
203
if (retry_hook ) {
@@ -227,6 +222,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
227
222
}
228
223
}
229
224
225
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
226
+ {
227
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
228
+ va_list args ;
229
+ int result , saved_errno = errno ;
230
+
231
+ if ((* tries ) < ARRAY_SIZE (delay )) {
232
+ /*
233
+ * We assume that some other process had the file open at the wrong
234
+ * moment and retry. In order to give the other process a higher
235
+ * chance to complete its operation, we give up our time slice now.
236
+ * If we have to retry again, we do sleep a bit.
237
+ */
238
+ Sleep (delay [* tries ]);
239
+ (* tries )++ ;
240
+ return 1 ;
241
+ }
242
+
243
+ va_start (args , format );
244
+ result = ask_yes_no_if_possible (format , args );
245
+ va_end (args );
246
+ errno = saved_errno ;
247
+ return result ;
248
+ }
249
+
230
250
/* Windows only */
231
251
enum hide_dotfiles_type {
232
252
HIDE_DOTFILES_FALSE = 0 ,
@@ -320,34 +340,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
320
340
321
341
int mingw_unlink (const char * pathname )
322
342
{
323
- int ret , tries = 0 ;
343
+ int tries = 0 ;
324
344
wchar_t wpathname [MAX_LONG_PATH ];
325
345
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
326
346
return -1 ;
327
347
328
348
if (DeleteFileW (wpathname ))
329
349
return 0 ;
330
350
331
- /* read-only files cannot be removed */
332
- _wchmod (wpathname , 0666 );
333
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
351
+ do {
352
+ /* read-only files cannot be removed */
353
+ _wchmod (wpathname , 0666 );
354
+ if (!_wunlink (wpathname ))
355
+ return 0 ;
334
356
if (!is_file_in_use_error (GetLastError ()))
335
357
break ;
336
- /*
337
- * We assume that some other process had the source or
338
- * destination file open at the wrong moment and retry.
339
- * In order to give the other process a higher chance to
340
- * complete its operation, we give up our time slice now.
341
- * If we have to retry again, we do sleep a bit.
342
- */
343
- Sleep (delay [tries ]);
344
- tries ++ ;
345
- }
346
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
347
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
348
- "Should I try again?" , pathname ))
349
- ret = _wunlink (wpathname );
350
- return ret ;
358
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
359
+ "Should I try again?" , pathname ));
360
+ return -1 ;
351
361
}
352
362
353
363
static int is_dir_empty (const wchar_t * wpath )
@@ -374,7 +384,7 @@ static int is_dir_empty(const wchar_t *wpath)
374
384
375
385
int mingw_rmdir (const char * pathname )
376
386
{
377
- int ret , tries = 0 ;
387
+ int tries = 0 ;
378
388
wchar_t wpathname [MAX_LONG_PATH ];
379
389
struct stat st ;
380
390
@@ -400,7 +410,11 @@ int mingw_rmdir(const char *pathname)
400
410
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
401
411
return -1 ;
402
412
403
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
413
+ do {
414
+ if (!_wrmdir (wpathname )) {
415
+ invalidate_lstat_cache ();
416
+ return 0 ;
417
+ }
404
418
if (!is_file_in_use_error (GetLastError ()))
405
419
errno = err_win_to_posix (GetLastError ());
406
420
if (errno != EACCES )
@@ -409,23 +423,9 @@ int mingw_rmdir(const char *pathname)
409
423
errno = ENOTEMPTY ;
410
424
break ;
411
425
}
412
- /*
413
- * We assume that some other process had the source or
414
- * destination file open at the wrong moment and retry.
415
- * In order to give the other process a higher chance to
416
- * complete its operation, we give up our time slice now.
417
- * If we have to retry again, we do sleep a bit.
418
- */
419
- Sleep (delay [tries ]);
420
- tries ++ ;
421
- }
422
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
423
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
424
- "Should I try again?" , pathname ))
425
- ret = _wrmdir (wpathname );
426
- if (!ret )
427
- invalidate_lstat_cache ();
428
- return ret ;
426
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
427
+ "Should I try again?" , pathname ));
428
+ return -1 ;
429
429
}
430
430
431
431
static inline int needs_hiding (const char * path )
@@ -2403,20 +2403,8 @@ int mingw_rename(const char *pold, const char *pnew)
2403
2403
SetFileAttributesW (wpnew , attrs );
2404
2404
}
2405
2405
}
2406
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2407
- /*
2408
- * We assume that some other process had the source or
2409
- * destination file open at the wrong moment and retry.
2410
- * In order to give the other process a higher chance to
2411
- * complete its operation, we give up our time slice now.
2412
- * If we have to retry again, we do sleep a bit.
2413
- */
2414
- Sleep (delay [tries ]);
2415
- tries ++ ;
2416
- goto repeat ;
2417
- }
2418
2406
if (gle == ERROR_ACCESS_DENIED &&
2419
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2407
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2420
2408
"Should I try again?" , pold , pnew ))
2421
2409
goto repeat ;
2422
2410
0 commit comments