1212
1313#define HCAST (type , handle ) ((type)(intptr_t)handle)
1414
15- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
16-
1715void open_in_gdb (void )
1816{
1917 static struct child_process cp = CHILD_PROCESS_INIT ;
@@ -189,15 +187,12 @@ static int read_yes_no_answer(void)
189187 return -1 ;
190188}
191189
192- static int ask_yes_no_if_possible (const char * format , ... )
190+ static int ask_yes_no_if_possible (const char * format , va_list args )
193191{
194192 char question [4096 ];
195193 const char * retry_hook [] = { NULL , NULL , NULL };
196- va_list args ;
197194
198- va_start (args , format );
199195 vsnprintf (question , sizeof (question ), format , args );
200- va_end (args );
201196
202197 if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
203198 retry_hook [1 ] = question ;
@@ -219,6 +214,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
219214 }
220215}
221216
217+ static int retry_ask_yes_no (int * tries , const char * format , ...)
218+ {
219+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
220+ va_list args ;
221+ int result , saved_errno = errno ;
222+
223+ if ((* tries ) < ARRAY_SIZE (delay )) {
224+ /*
225+ * We assume that some other process had the file open at the wrong
226+ * moment and retry. In order to give the other process a higher
227+ * chance to complete its operation, we give up our time slice now.
228+ * If we have to retry again, we do sleep a bit.
229+ */
230+ Sleep (delay [* tries ]);
231+ (* tries )++ ;
232+ return 1 ;
233+ }
234+
235+ va_start (args , format );
236+ result = ask_yes_no_if_possible (format , args );
237+ va_end (args );
238+ errno = saved_errno ;
239+ return result ;
240+ }
241+
222242/* Windows only */
223243enum hide_dotfiles_type {
224244 HIDE_DOTFILES_FALSE = 0 ,
@@ -287,31 +307,21 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
287307
288308int mingw_unlink (const char * pathname )
289309{
290- int ret , tries = 0 ;
310+ int tries = 0 ;
291311 wchar_t wpathname [MAX_LONG_PATH ];
292312 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
293313 return -1 ;
294314
295- /* read-only files cannot be removed */
296- _wchmod (wpathname , 0666 );
297- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
315+ do {
316+ /* read-only files cannot be removed */
317+ _wchmod (wpathname , 0666 );
318+ if (!_wunlink (wpathname ))
319+ return 0 ;
298320 if (!is_file_in_use_error (GetLastError ()))
299321 break ;
300- /*
301- * We assume that some other process had the source or
302- * destination file open at the wrong moment and retry.
303- * In order to give the other process a higher chance to
304- * complete its operation, we give up our time slice now.
305- * If we have to retry again, we do sleep a bit.
306- */
307- Sleep (delay [tries ]);
308- tries ++ ;
309- }
310- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
311- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
312- "Should I try again?" , pathname ))
313- ret = _wunlink (wpathname );
314- return ret ;
322+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
323+ "Should I try again?" , pathname ));
324+ return -1 ;
315325}
316326
317327static int is_dir_empty (const wchar_t * wpath )
@@ -338,12 +348,14 @@ static int is_dir_empty(const wchar_t *wpath)
338348
339349int mingw_rmdir (const char * pathname )
340350{
341- int ret , tries = 0 ;
351+ int tries = 0 ;
342352 wchar_t wpathname [MAX_LONG_PATH ];
343353 if (xutftowcs_long_path (wpathname , pathname ) < 0 )
344354 return -1 ;
345355
346- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
356+ do {
357+ if (!_wrmdir (wpathname ))
358+ return 0 ;
347359 if (!is_file_in_use_error (GetLastError ()))
348360 errno = err_win_to_posix (GetLastError ());
349361 if (errno != EACCES )
@@ -352,21 +364,9 @@ int mingw_rmdir(const char *pathname)
352364 errno = ENOTEMPTY ;
353365 break ;
354366 }
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 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
366- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
367- "Should I try again?" , pathname ))
368- ret = _wrmdir (wpathname );
369- return ret ;
367+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
368+ "Should I try again?" , pathname ));
369+ return -1 ;
370370}
371371
372372static inline int needs_hiding (const char * path )
@@ -1921,20 +1921,8 @@ int mingw_rename(const char *pold, const char *pnew)
19211921 SetFileAttributesW (wpnew , attrs );
19221922 }
19231923 }
1924- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
1925- /*
1926- * We assume that some other process had the source or
1927- * destination file open at the wrong moment and retry.
1928- * In order to give the other process a higher chance to
1929- * complete its operation, we give up our time slice now.
1930- * If we have to retry again, we do sleep a bit.
1931- */
1932- Sleep (delay [tries ]);
1933- tries ++ ;
1934- goto repeat ;
1935- }
19361924 if (gle == ERROR_ACCESS_DENIED &&
1937- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
1925+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
19381926 "Should I try again?" , pold , pnew ))
19391927 goto repeat ;
19401928
0 commit comments