2626
2727#define HCAST (type , handle ) ((type)(intptr_t)handle)
2828
29- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
30-
3129void open_in_gdb (void )
3230{
3331 static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -203,15 +201,12 @@ static int read_yes_no_answer(void)
203201 return -1 ;
204202}
205203
206- static int ask_yes_no_if_possible (const char * format , ... )
204+ static int ask_yes_no_if_possible (const char * format , va_list args )
207205{
208206 char question [4096 ];
209207 const char * retry_hook ;
210- va_list args ;
211208
212- va_start (args , format );
213209 vsnprintf (question , sizeof (question ), format , args );
214- va_end (args );
215210
216211 retry_hook = mingw_getenv ("GIT_ASK_YESNO" );
217212 if (retry_hook ) {
@@ -236,6 +231,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
236231 }
237232}
238233
234+ static int retry_ask_yes_no (int * tries , const char * format , ...)
235+ {
236+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
237+ va_list args ;
238+ int result , saved_errno = errno ;
239+
240+ if ((* tries ) < ARRAY_SIZE (delay )) {
241+ /*
242+ * We assume that some other process had the file open at the wrong
243+ * moment and retry. In order to give the other process a higher
244+ * chance to complete its operation, we give up our time slice now.
245+ * If we have to retry again, we do sleep a bit.
246+ */
247+ Sleep (delay [* tries ]);
248+ (* tries )++ ;
249+ return 1 ;
250+ }
251+
252+ va_start (args , format );
253+ result = ask_yes_no_if_possible (format , args );
254+ va_end (args );
255+ errno = saved_errno ;
256+ return result ;
257+ }
258+
239259/* Windows only */
240260enum hide_dotfiles_type {
241261 HIDE_DOTFILES_FALSE = 0 ,
@@ -338,34 +358,24 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
338358
339359int mingw_unlink (const char * pathname )
340360{
341- int ret , tries = 0 ;
361+ int tries = 0 ;
342362 wchar_t wpathname [MAX_LONG_PATH ];
343363 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
344364 return -1 ;
345365
346366 if (DeleteFileW (wpathname ))
347367 return 0 ;
348368
349- /* read-only files cannot be removed */
350- _wchmod (wpathname , 0666 );
351- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
369+ do {
370+ /* read-only files cannot be removed */
371+ _wchmod (wpathname , 0666 );
372+ if (!_wunlink (wpathname ))
373+ return 0 ;
352374 if (!is_file_in_use_error (GetLastError ()))
353375 break ;
354- /*
355- * We assume that some other process had the source or
356- * destination file open at the wrong moment and retry.
357- * In order to give the other process a higher chance to
358- * complete its operation, we give up our time slice now.
359- * If we have to retry again, we do sleep a bit.
360- */
361- Sleep (delay [tries ]);
362- tries ++ ;
363- }
364- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
365- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
366- "Should I try again?" , pathname ))
367- ret = _wunlink (wpathname );
368- return ret ;
376+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
377+ "Should I try again?" , pathname ));
378+ return -1 ;
369379}
370380
371381static int is_dir_empty (const wchar_t * wpath )
@@ -392,7 +402,7 @@ static int is_dir_empty(const wchar_t *wpath)
392402
393403int mingw_rmdir (const char * pathname )
394404{
395- int ret , tries = 0 ;
405+ int tries = 0 ;
396406 wchar_t wpathname [MAX_LONG_PATH ];
397407 struct stat st ;
398408
@@ -418,7 +428,11 @@ int mingw_rmdir(const char *pathname)
418428 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
419429 return -1 ;
420430
421- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
431+ do {
432+ if (!_wrmdir (wpathname )) {
433+ invalidate_lstat_cache ();
434+ return 0 ;
435+ }
422436 if (!is_file_in_use_error (GetLastError ()))
423437 errno = err_win_to_posix (GetLastError ());
424438 if (errno != EACCES )
@@ -427,23 +441,9 @@ int mingw_rmdir(const char *pathname)
427441 errno = ENOTEMPTY ;
428442 break ;
429443 }
430- /*
431- * We assume that some other process had the source or
432- * destination file open at the wrong moment and retry.
433- * In order to give the other process a higher chance to
434- * complete its operation, we give up our time slice now.
435- * If we have to retry again, we do sleep a bit.
436- */
437- Sleep (delay [tries ]);
438- tries ++ ;
439- }
440- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
441- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
442- "Should I try again?" , pathname ))
443- ret = _wrmdir (wpathname );
444- if (!ret )
445- invalidate_lstat_cache ();
446- return ret ;
444+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
445+ "Should I try again?" , pathname ));
446+ return -1 ;
447447}
448448
449449static inline int needs_hiding (const char * path )
@@ -2595,20 +2595,8 @@ int mingw_rename(const char *pold, const char *pnew)
25952595 SetFileAttributesW (wpnew , attrs );
25962596 }
25972597 }
2598- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2599- /*
2600- * We assume that some other process had the source or
2601- * destination file open at the wrong moment and retry.
2602- * In order to give the other process a higher chance to
2603- * complete its operation, we give up our time slice now.
2604- * If we have to retry again, we do sleep a bit.
2605- */
2606- Sleep (delay [tries ]);
2607- tries ++ ;
2608- goto repeat ;
2609- }
26102598 if (gle == ERROR_ACCESS_DENIED &&
2611- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2599+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
26122600 "Should I try again?" , pold , pnew ))
26132601 goto repeat ;
26142602
0 commit comments