14
14
15
15
#define HCAST (type , handle ) ((type)(intptr_t)handle)
16
16
17
- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
18
-
19
17
void open_in_gdb (void )
20
18
{
21
19
static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -192,15 +190,12 @@ static int read_yes_no_answer(void)
192
190
return -1 ;
193
191
}
194
192
195
- static int ask_yes_no_if_possible (const char * format , ... )
193
+ static int ask_yes_no_if_possible (const char * format , va_list args )
196
194
{
197
195
char question [4096 ];
198
196
const char * retry_hook [] = { NULL , NULL , NULL };
199
- va_list args ;
200
197
201
- va_start (args , format );
202
198
vsnprintf (question , sizeof (question ), format , args );
203
- va_end (args );
204
199
205
200
if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
206
201
retry_hook [1 ] = question ;
@@ -222,6 +217,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
222
217
}
223
218
}
224
219
220
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
221
+ {
222
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
223
+ va_list args ;
224
+ int result , saved_errno = errno ;
225
+
226
+ if ((* tries ) < ARRAY_SIZE (delay )) {
227
+ /*
228
+ * We assume that some other process had the file open at the wrong
229
+ * moment and retry. In order to give the other process a higher
230
+ * chance to complete its operation, we give up our time slice now.
231
+ * If we have to retry again, we do sleep a bit.
232
+ */
233
+ Sleep (delay [* tries ]);
234
+ (* tries )++ ;
235
+ return 1 ;
236
+ }
237
+
238
+ va_start (args , format );
239
+ result = ask_yes_no_if_possible (format , args );
240
+ va_end (args );
241
+ errno = saved_errno ;
242
+ return result ;
243
+ }
244
+
225
245
/* Windows only */
226
246
enum hide_dotfiles_type {
227
247
HIDE_DOTFILES_FALSE = 0 ,
@@ -300,34 +320,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
300
320
301
321
int mingw_unlink (const char * pathname )
302
322
{
303
- int ret , tries = 0 ;
323
+ int tries = 0 ;
304
324
wchar_t wpathname [MAX_LONG_PATH ];
305
325
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
306
326
return -1 ;
307
327
308
328
if (DeleteFileW (wpathname ))
309
329
return 0 ;
310
330
311
- /* read-only files cannot be removed */
312
- _wchmod (wpathname , 0666 );
313
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
331
+ do {
332
+ /* read-only files cannot be removed */
333
+ _wchmod (wpathname , 0666 );
334
+ if (!_wunlink (wpathname ))
335
+ return 0 ;
314
336
if (!is_file_in_use_error (GetLastError ()))
315
337
break ;
316
- /*
317
- * We assume that some other process had the source or
318
- * destination file open at the wrong moment and retry.
319
- * In order to give the other process a higher chance to
320
- * complete its operation, we give up our time slice now.
321
- * If we have to retry again, we do sleep a bit.
322
- */
323
- Sleep (delay [tries ]);
324
- tries ++ ;
325
- }
326
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
327
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
328
- "Should I try again?" , pathname ))
329
- ret = _wunlink (wpathname );
330
- return ret ;
338
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
339
+ "Should I try again?" , pathname ));
340
+ return -1 ;
331
341
}
332
342
333
343
static int is_dir_empty (const wchar_t * wpath )
@@ -354,7 +364,7 @@ static int is_dir_empty(const wchar_t *wpath)
354
364
355
365
int mingw_rmdir (const char * pathname )
356
366
{
357
- int ret , tries = 0 ;
367
+ int tries = 0 ;
358
368
wchar_t wpathname [MAX_LONG_PATH ];
359
369
struct stat st ;
360
370
@@ -380,7 +390,11 @@ int mingw_rmdir(const char *pathname)
380
390
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
381
391
return -1 ;
382
392
383
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
393
+ do {
394
+ if (!_wrmdir (wpathname )) {
395
+ invalidate_lstat_cache ();
396
+ return 0 ;
397
+ }
384
398
if (!is_file_in_use_error (GetLastError ()))
385
399
errno = err_win_to_posix (GetLastError ());
386
400
if (errno != EACCES )
@@ -389,23 +403,9 @@ int mingw_rmdir(const char *pathname)
389
403
errno = ENOTEMPTY ;
390
404
break ;
391
405
}
392
- /*
393
- * We assume that some other process had the source or
394
- * destination file open at the wrong moment and retry.
395
- * In order to give the other process a higher chance to
396
- * complete its operation, we give up our time slice now.
397
- * If we have to retry again, we do sleep a bit.
398
- */
399
- Sleep (delay [tries ]);
400
- tries ++ ;
401
- }
402
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
403
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
404
- "Should I try again?" , pathname ))
405
- ret = _wrmdir (wpathname );
406
- if (!ret )
407
- invalidate_lstat_cache ();
408
- return ret ;
406
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
407
+ "Should I try again?" , pathname ));
408
+ return -1 ;
409
409
}
410
410
411
411
static inline int needs_hiding (const char * path )
@@ -2358,20 +2358,8 @@ int mingw_rename(const char *pold, const char *pnew)
2358
2358
SetFileAttributesW (wpnew , attrs );
2359
2359
}
2360
2360
}
2361
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2362
- /*
2363
- * We assume that some other process had the source or
2364
- * destination file open at the wrong moment and retry.
2365
- * In order to give the other process a higher chance to
2366
- * complete its operation, we give up our time slice now.
2367
- * If we have to retry again, we do sleep a bit.
2368
- */
2369
- Sleep (delay [tries ]);
2370
- tries ++ ;
2371
- goto repeat ;
2372
- }
2373
2361
if (gle == ERROR_ACCESS_DENIED &&
2374
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2362
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2375
2363
"Should I try again?" , pold , pnew ))
2376
2364
goto repeat ;
2377
2365
0 commit comments