2727
2828#define HCAST (type , handle ) ((type)(intptr_t)handle)
2929
30- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
31-
3230void open_in_gdb (void )
3331{
3432 static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -204,15 +202,12 @@ static int read_yes_no_answer(void)
204202 return -1 ;
205203}
206204
207- static int ask_yes_no_if_possible (const char * format , ... )
205+ static int ask_yes_no_if_possible (const char * format , va_list args )
208206{
209207 char question [4096 ];
210208 const char * retry_hook ;
211- va_list args ;
212209
213- va_start (args , format );
214210 vsnprintf (question , sizeof (question ), format , args );
215- va_end (args );
216211
217212 retry_hook = mingw_getenv ("GIT_ASK_YESNO" );
218213 if (retry_hook ) {
@@ -237,6 +232,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
237232 }
238233}
239234
235+ static int retry_ask_yes_no (int * tries , const char * format , ...)
236+ {
237+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
238+ va_list args ;
239+ int result , saved_errno = errno ;
240+
241+ if ((* tries ) < ARRAY_SIZE (delay )) {
242+ /*
243+ * We assume that some other process had the file open at the wrong
244+ * moment and retry. In order to give the other process a higher
245+ * chance to complete its operation, we give up our time slice now.
246+ * If we have to retry again, we do sleep a bit.
247+ */
248+ Sleep (delay [* tries ]);
249+ (* tries )++ ;
250+ return 1 ;
251+ }
252+
253+ va_start (args , format );
254+ result = ask_yes_no_if_possible (format , args );
255+ va_end (args );
256+ errno = saved_errno ;
257+ return result ;
258+ }
259+
240260/* Windows only */
241261enum hide_dotfiles_type {
242262 HIDE_DOTFILES_FALSE = 0 ,
@@ -339,34 +359,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
339359
340360int mingw_unlink (const char * pathname )
341361{
342- int ret , tries = 0 ;
362+ int tries = 0 ;
343363 wchar_t wpathname [MAX_LONG_PATH ];
344364 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
345365 return -1 ;
346366
347367 if (DeleteFileW (wpathname ))
348368 return 0 ;
349369
350- /* read-only files cannot be removed */
351- _wchmod (wpathname , 0666 );
352- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
370+ do {
371+ /* read-only files cannot be removed */
372+ _wchmod (wpathname , 0666 );
373+ if (!_wunlink (wpathname ))
374+ return 0 ;
353375 if (!is_file_in_use_error (GetLastError ()))
354376 break ;
355- /*
356- * We assume that some other process had the source or
357- * destination file open at the wrong moment and retry.
358- * In order to give the other process a higher chance to
359- * complete its operation, we give up our time slice now.
360- * If we have to retry again, we do sleep a bit.
361- */
362- Sleep (delay [tries ]);
363- tries ++ ;
364- }
365- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
366- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
367- "Should I try again?" , pathname ))
368- ret = _wunlink (wpathname );
369- return ret ;
377+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
378+ "Should I try again?" , pathname ));
379+ return -1 ;
370380}
371381
372382static int is_dir_empty (const wchar_t * wpath )
@@ -393,7 +403,7 @@ static int is_dir_empty(const wchar_t *wpath)
393403
394404int mingw_rmdir (const char * pathname )
395405{
396- int ret , tries = 0 ;
406+ int tries = 0 ;
397407 wchar_t wpathname [MAX_LONG_PATH ];
398408 struct stat st ;
399409
@@ -419,7 +429,11 @@ int mingw_rmdir(const char *pathname)
419429 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
420430 return -1 ;
421431
422- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
432+ do {
433+ if (!_wrmdir (wpathname )) {
434+ invalidate_lstat_cache ();
435+ return 0 ;
436+ }
423437 if (!is_file_in_use_error (GetLastError ()))
424438 errno = err_win_to_posix (GetLastError ());
425439 if (errno != EACCES )
@@ -428,23 +442,9 @@ int mingw_rmdir(const char *pathname)
428442 errno = ENOTEMPTY ;
429443 break ;
430444 }
431- /*
432- * We assume that some other process had the source or
433- * destination file open at the wrong moment and retry.
434- * In order to give the other process a higher chance to
435- * complete its operation, we give up our time slice now.
436- * If we have to retry again, we do sleep a bit.
437- */
438- Sleep (delay [tries ]);
439- tries ++ ;
440- }
441- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
442- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
443- "Should I try again?" , pathname ))
444- ret = _wrmdir (wpathname );
445- if (!ret )
446- invalidate_lstat_cache ();
447- return ret ;
445+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
446+ "Should I try again?" , pathname ));
447+ return -1 ;
448448}
449449
450450static inline int needs_hiding (const char * path )
@@ -2596,20 +2596,8 @@ int mingw_rename(const char *pold, const char *pnew)
25962596 SetFileAttributesW (wpnew , attrs );
25972597 }
25982598 }
2599- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2600- /*
2601- * We assume that some other process had the source or
2602- * destination file open at the wrong moment and retry.
2603- * In order to give the other process a higher chance to
2604- * complete its operation, we give up our time slice now.
2605- * If we have to retry again, we do sleep a bit.
2606- */
2607- Sleep (delay [tries ]);
2608- tries ++ ;
2609- goto repeat ;
2610- }
26112599 if (gle == ERROR_ACCESS_DENIED &&
2612- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2600+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
26132601 "Should I try again?" , pold , pnew ))
26142602 goto repeat ;
26152603
0 commit comments