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