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 [] = { NULL , NULL , NULL };
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
if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
208
203
retry_hook [1 ] = question ;
@@ -224,6 +219,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
224
219
}
225
220
}
226
221
222
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
223
+ {
224
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
225
+ va_list args ;
226
+ int result , saved_errno = errno ;
227
+
228
+ if ((* tries ) < ARRAY_SIZE (delay )) {
229
+ /*
230
+ * We assume that some other process had the file open at the wrong
231
+ * moment and retry. In order to give the other process a higher
232
+ * chance to complete its operation, we give up our time slice now.
233
+ * If we have to retry again, we do sleep a bit.
234
+ */
235
+ Sleep (delay [* tries ]);
236
+ (* tries )++ ;
237
+ return 1 ;
238
+ }
239
+
240
+ va_start (args , format );
241
+ result = ask_yes_no_if_possible (format , args );
242
+ va_end (args );
243
+ errno = saved_errno ;
244
+ return result ;
245
+ }
246
+
227
247
/* Windows only */
228
248
enum hide_dotfiles_type {
229
249
HIDE_DOTFILES_FALSE = 0 ,
@@ -302,34 +322,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
302
322
303
323
int mingw_unlink (const char * pathname )
304
324
{
305
- int ret , tries = 0 ;
325
+ int tries = 0 ;
306
326
wchar_t wpathname [MAX_LONG_PATH ];
307
327
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
308
328
return -1 ;
309
329
310
330
if (DeleteFileW (wpathname ))
311
331
return 0 ;
312
332
313
- /* read-only files cannot be removed */
314
- _wchmod (wpathname , 0666 );
315
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
333
+ do {
334
+ /* read-only files cannot be removed */
335
+ _wchmod (wpathname , 0666 );
336
+ if (!_wunlink (wpathname ))
337
+ return 0 ;
316
338
if (!is_file_in_use_error (GetLastError ()))
317
339
break ;
318
- /*
319
- * We assume that some other process had the source or
320
- * destination file open at the wrong moment and retry.
321
- * In order to give the other process a higher chance to
322
- * complete its operation, we give up our time slice now.
323
- * If we have to retry again, we do sleep a bit.
324
- */
325
- Sleep (delay [tries ]);
326
- tries ++ ;
327
- }
328
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
329
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
330
- "Should I try again?" , pathname ))
331
- ret = _wunlink (wpathname );
332
- return ret ;
340
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
341
+ "Should I try again?" , pathname ));
342
+ return -1 ;
333
343
}
334
344
335
345
static int is_dir_empty (const wchar_t * wpath )
@@ -356,7 +366,7 @@ static int is_dir_empty(const wchar_t *wpath)
356
366
357
367
int mingw_rmdir (const char * pathname )
358
368
{
359
- int ret , tries = 0 ;
369
+ int tries = 0 ;
360
370
wchar_t wpathname [MAX_LONG_PATH ];
361
371
struct stat st ;
362
372
@@ -382,7 +392,11 @@ int mingw_rmdir(const char *pathname)
382
392
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
383
393
return -1 ;
384
394
385
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
395
+ do {
396
+ if (!_wrmdir (wpathname )) {
397
+ invalidate_lstat_cache ();
398
+ return 0 ;
399
+ }
386
400
if (!is_file_in_use_error (GetLastError ()))
387
401
errno = err_win_to_posix (GetLastError ());
388
402
if (errno != EACCES )
@@ -391,23 +405,9 @@ int mingw_rmdir(const char *pathname)
391
405
errno = ENOTEMPTY ;
392
406
break ;
393
407
}
394
- /*
395
- * We assume that some other process had the source or
396
- * destination file open at the wrong moment and retry.
397
- * In order to give the other process a higher chance to
398
- * complete its operation, we give up our time slice now.
399
- * If we have to retry again, we do sleep a bit.
400
- */
401
- Sleep (delay [tries ]);
402
- tries ++ ;
403
- }
404
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
405
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
406
- "Should I try again?" , pathname ))
407
- ret = _wrmdir (wpathname );
408
- if (!ret )
409
- invalidate_lstat_cache ();
410
- return ret ;
408
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
409
+ "Should I try again?" , pathname ));
410
+ return -1 ;
411
411
}
412
412
413
413
static inline int needs_hiding (const char * path )
@@ -2360,20 +2360,8 @@ int mingw_rename(const char *pold, const char *pnew)
2360
2360
SetFileAttributesW (wpnew , attrs );
2361
2361
}
2362
2362
}
2363
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2364
- /*
2365
- * We assume that some other process had the source or
2366
- * destination file open at the wrong moment and retry.
2367
- * In order to give the other process a higher chance to
2368
- * complete its operation, we give up our time slice now.
2369
- * If we have to retry again, we do sleep a bit.
2370
- */
2371
- Sleep (delay [tries ]);
2372
- tries ++ ;
2373
- goto repeat ;
2374
- }
2375
2363
if (gle == ERROR_ACCESS_DENIED &&
2376
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2364
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2377
2365
"Should I try again?" , pold , pnew ))
2378
2366
goto repeat ;
2379
2367
0 commit comments