1616
1717#define HCAST (type , handle ) ((type)(intptr_t)handle)
1818
19- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
20-
2119void open_in_gdb (void )
2220{
2321 static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -194,15 +192,12 @@ static int read_yes_no_answer(void)
194192 return -1 ;
195193}
196194
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 )
198196{
199197 char question [4096 ];
200198 const char * retry_hook ;
201- va_list args ;
202199
203- va_start (args , format );
204200 vsnprintf (question , sizeof (question ), format , args );
205- va_end (args );
206201
207202 retry_hook = mingw_getenv ("GIT_ASK_YESNO" );
208203 if (retry_hook ) {
@@ -227,6 +222,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
227222 }
228223}
229224
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+
230250/* Windows only */
231251enum hide_dotfiles_type {
232252 HIDE_DOTFILES_FALSE = 0 ,
@@ -320,34 +340,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
320340
321341int mingw_unlink (const char * pathname )
322342{
323- int ret , tries = 0 ;
343+ int tries = 0 ;
324344 wchar_t wpathname [MAX_LONG_PATH ];
325345 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
326346 return -1 ;
327347
328348 if (DeleteFileW (wpathname ))
329349 return 0 ;
330350
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 ;
334356 if (!is_file_in_use_error (GetLastError ()))
335357 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 ;
351361}
352362
353363static int is_dir_empty (const wchar_t * wpath )
@@ -374,7 +384,7 @@ static int is_dir_empty(const wchar_t *wpath)
374384
375385int mingw_rmdir (const char * pathname )
376386{
377- int ret , tries = 0 ;
387+ int tries = 0 ;
378388 wchar_t wpathname [MAX_LONG_PATH ];
379389 struct stat st ;
380390
@@ -400,7 +410,11 @@ int mingw_rmdir(const char *pathname)
400410 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
401411 return -1 ;
402412
403- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
413+ do {
414+ if (!_wrmdir (wpathname )) {
415+ invalidate_lstat_cache ();
416+ return 0 ;
417+ }
404418 if (!is_file_in_use_error (GetLastError ()))
405419 errno = err_win_to_posix (GetLastError ());
406420 if (errno != EACCES )
@@ -409,23 +423,9 @@ int mingw_rmdir(const char *pathname)
409423 errno = ENOTEMPTY ;
410424 break ;
411425 }
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 ;
429429}
430430
431431static inline int needs_hiding (const char * path )
@@ -2412,20 +2412,8 @@ int mingw_rename(const char *pold, const char *pnew)
24122412 SetFileAttributesW (wpnew , attrs );
24132413 }
24142414 }
2415- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2416- /*
2417- * We assume that some other process had the source or
2418- * destination file open at the wrong moment and retry.
2419- * In order to give the other process a higher chance to
2420- * complete its operation, we give up our time slice now.
2421- * If we have to retry again, we do sleep a bit.
2422- */
2423- Sleep (delay [tries ]);
2424- tries ++ ;
2425- goto repeat ;
2426- }
24272415 if (gle == ERROR_ACCESS_DENIED &&
2428- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2416+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
24292417 "Should I try again?" , pold , pnew ))
24302418 goto repeat ;
24312419
0 commit comments