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