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 [] = { NULL , NULL , NULL };
201- va_list args ;
202199
203- va_start (args , format );
204200 vsnprintf (question , sizeof (question ), format , args );
205- va_end (args );
206201
207202 if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
208203 retry_hook [1 ] = question ;
@@ -224,6 +219,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
224219 }
225220}
226221
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+
227247/* Windows only */
228248enum hide_dotfiles_type {
229249 HIDE_DOTFILES_FALSE = 0 ,
@@ -302,34 +322,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
302322
303323int mingw_unlink (const char * pathname )
304324{
305- int ret , tries = 0 ;
325+ int tries = 0 ;
306326 wchar_t wpathname [MAX_LONG_PATH ];
307327 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
308328 return -1 ;
309329
310330 if (DeleteFileW (wpathname ))
311331 return 0 ;
312332
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 ;
316338 if (!is_file_in_use_error (GetLastError ()))
317339 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 ;
333343}
334344
335345static int is_dir_empty (const wchar_t * wpath )
@@ -356,7 +366,7 @@ static int is_dir_empty(const wchar_t *wpath)
356366
357367int mingw_rmdir (const char * pathname )
358368{
359- int ret , tries = 0 ;
369+ int tries = 0 ;
360370 wchar_t wpathname [MAX_LONG_PATH ];
361371 struct stat st ;
362372
@@ -382,7 +392,11 @@ int mingw_rmdir(const char *pathname)
382392 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
383393 return -1 ;
384394
385- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
395+ do {
396+ if (!_wrmdir (wpathname )) {
397+ invalidate_lstat_cache ();
398+ return 0 ;
399+ }
386400 if (!is_file_in_use_error (GetLastError ()))
387401 errno = err_win_to_posix (GetLastError ());
388402 if (errno != EACCES )
@@ -391,23 +405,9 @@ int mingw_rmdir(const char *pathname)
391405 errno = ENOTEMPTY ;
392406 break ;
393407 }
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 ;
411411}
412412
413413static inline int needs_hiding (const char * path )
@@ -2360,20 +2360,8 @@ int mingw_rename(const char *pold, const char *pnew)
23602360 SetFileAttributesW (wpnew , attrs );
23612361 }
23622362 }
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- }
23752363 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. "
23772365 "Should I try again?" , pold , pnew ))
23782366 goto repeat ;
23792367
0 commit comments