1111
1212#define HCAST (type , handle ) ((type)(intptr_t)handle)
1313
14- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
15-
1614void open_in_gdb (void )
1715{
1816 static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -188,15 +186,12 @@ static int read_yes_no_answer(void)
188186 return -1 ;
189187}
190188
191- static int ask_yes_no_if_possible (const char * format , ... )
189+ static int ask_yes_no_if_possible (const char * format , va_list args )
192190{
193191 char question [4096 ];
194192 const char * retry_hook [] = { NULL , NULL , NULL };
195- va_list args ;
196193
197- va_start (args , format );
198194 vsnprintf (question , sizeof (question ), format , args );
199- va_end (args );
200195
201196 if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
202197 retry_hook [1 ] = question ;
@@ -218,6 +213,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
218213 }
219214}
220215
216+ static int retry_ask_yes_no (int * tries , const char * format , ...)
217+ {
218+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
219+ va_list args ;
220+ int result , saved_errno = errno ;
221+
222+ if ((* tries ) < ARRAY_SIZE (delay )) {
223+ /*
224+ * We assume that some other process had the file open at the wrong
225+ * moment and retry. In order to give the other process a higher
226+ * chance to complete its operation, we give up our time slice now.
227+ * If we have to retry again, we do sleep a bit.
228+ */
229+ Sleep (delay [* tries ]);
230+ (* tries )++ ;
231+ return 1 ;
232+ }
233+
234+ va_start (args , format );
235+ result = ask_yes_no_if_possible (format , args );
236+ va_end (args );
237+ errno = saved_errno ;
238+ return result ;
239+ }
240+
221241/* Windows only */
222242enum hide_dotfiles_type {
223243 HIDE_DOTFILES_FALSE = 0 ,
@@ -286,31 +306,21 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
286306
287307int mingw_unlink (const char * pathname )
288308{
289- int ret , tries = 0 ;
309+ int tries = 0 ;
290310 wchar_t wpathname [MAX_LONG_PATH ];
291311 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
292312 return -1 ;
293313
294- /* read-only files cannot be removed */
295- _wchmod (wpathname , 0666 );
296- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
314+ do {
315+ /* read-only files cannot be removed */
316+ _wchmod (wpathname , 0666 );
317+ if (!_wunlink (wpathname ))
318+ return 0 ;
297319 if (!is_file_in_use_error (GetLastError ()))
298320 break ;
299- /*
300- * We assume that some other process had the source or
301- * destination file open at the wrong moment and retry.
302- * In order to give the other process a higher chance to
303- * complete its operation, we give up our time slice now.
304- * If we have to retry again, we do sleep a bit.
305- */
306- Sleep (delay [tries ]);
307- tries ++ ;
308- }
309- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
310- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
311- "Should I try again?" , pathname ))
312- ret = _wunlink (wpathname );
313- return ret ;
321+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
322+ "Should I try again?" , pathname ));
323+ return -1 ;
314324}
315325
316326static int is_dir_empty (const wchar_t * wpath )
@@ -337,12 +347,14 @@ static int is_dir_empty(const wchar_t *wpath)
337347
338348int mingw_rmdir (const char * pathname )
339349{
340- int ret , tries = 0 ;
350+ int tries = 0 ;
341351 wchar_t wpathname [MAX_LONG_PATH ];
342352 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
343353 return -1 ;
344354
345- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
355+ do {
356+ if (!_wrmdir (wpathname ))
357+ return 0 ;
346358 if (!is_file_in_use_error (GetLastError ()))
347359 errno = err_win_to_posix (GetLastError ());
348360 if (errno != EACCES )
@@ -351,21 +363,9 @@ int mingw_rmdir(const char *pathname)
351363 errno = ENOTEMPTY ;
352364 break ;
353365 }
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 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
365- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
366- "Should I try again?" , pathname ))
367- ret = _wrmdir (wpathname );
368- return ret ;
366+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
367+ "Should I try again?" , pathname ));
368+ return -1 ;
369369}
370370
371371static inline int needs_hiding (const char * path )
@@ -1913,20 +1913,8 @@ int mingw_rename(const char *pold, const char *pnew)
19131913 SetFileAttributesW (wpnew , attrs );
19141914 }
19151915 }
1916- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
1917- /*
1918- * We assume that some other process had the source or
1919- * destination file open at the wrong moment and retry.
1920- * In order to give the other process a higher chance to
1921- * complete its operation, we give up our time slice now.
1922- * If we have to retry again, we do sleep a bit.
1923- */
1924- Sleep (delay [tries ]);
1925- tries ++ ;
1926- goto repeat ;
1927- }
19281916 if (gle == ERROR_ACCESS_DENIED &&
1929- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
1917+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
19301918 "Should I try again?" , pold , pnew ))
19311919 goto repeat ;
19321920
0 commit comments