1414
1515#define HCAST (type , handle ) ((type)(intptr_t)handle)
1616
17- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
18-
1917void open_in_gdb (void )
2018{
2119 static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -192,15 +190,12 @@ static int read_yes_no_answer(void)
192190 return -1 ;
193191}
194192
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 )
196194{
197195 char question [4096 ];
198196 const char * retry_hook [] = { NULL , NULL , NULL };
199- va_list args ;
200197
201- va_start (args , format );
202198 vsnprintf (question , sizeof (question ), format , args );
203- va_end (args );
204199
205200 if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
206201 retry_hook [1 ] = question ;
@@ -222,6 +217,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
222217 }
223218}
224219
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+
225245/* Windows only */
226246enum hide_dotfiles_type {
227247 HIDE_DOTFILES_FALSE = 0 ,
@@ -300,34 +320,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
300320
301321int mingw_unlink (const char * pathname )
302322{
303- int ret , tries = 0 ;
323+ int tries = 0 ;
304324 wchar_t wpathname [MAX_LONG_PATH ];
305325 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
306326 return -1 ;
307327
308328 if (DeleteFileW (wpathname ))
309329 return 0 ;
310330
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 ;
314336 if (!is_file_in_use_error (GetLastError ()))
315337 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 ;
331341}
332342
333343static int is_dir_empty (const wchar_t * wpath )
@@ -354,7 +364,7 @@ static int is_dir_empty(const wchar_t *wpath)
354364
355365int mingw_rmdir (const char * pathname )
356366{
357- int ret , tries = 0 ;
367+ int tries = 0 ;
358368 wchar_t wpathname [MAX_LONG_PATH ];
359369 struct stat st ;
360370
@@ -380,7 +390,11 @@ int mingw_rmdir(const char *pathname)
380390 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
381391 return -1 ;
382392
383- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
393+ do {
394+ if (!_wrmdir (wpathname )) {
395+ invalidate_lstat_cache ();
396+ return 0 ;
397+ }
384398 if (!is_file_in_use_error (GetLastError ()))
385399 errno = err_win_to_posix (GetLastError ());
386400 if (errno != EACCES )
@@ -389,23 +403,9 @@ int mingw_rmdir(const char *pathname)
389403 errno = ENOTEMPTY ;
390404 break ;
391405 }
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 ;
409409}
410410
411411static inline int needs_hiding (const char * path )
@@ -2358,20 +2358,8 @@ int mingw_rename(const char *pold, const char *pnew)
23582358 SetFileAttributesW (wpnew , attrs );
23592359 }
23602360 }
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- }
23732361 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. "
23752363 "Should I try again?" , pold , pnew ))
23762364 goto repeat ;
23772365
0 commit comments