@@ -172,15 +172,12 @@ static int read_yes_no_answer(void)
172
172
return -1 ;
173
173
}
174
174
175
- static int ask_yes_no_if_possible (const char * format , ... )
175
+ static int ask_yes_no_if_possible (const char * format , va_list args )
176
176
{
177
177
char question [4096 ];
178
178
const char * retry_hook [] = { NULL , NULL , NULL };
179
- va_list args ;
180
179
181
- va_start (args , format );
182
180
vsnprintf (question , sizeof (question ), format , args );
183
- va_end (args );
184
181
185
182
if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
186
183
retry_hook [1 ] = question ;
@@ -202,33 +199,48 @@ static int ask_yes_no_if_possible(const char *format, ...)
202
199
}
203
200
}
204
201
202
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
203
+ {
204
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
205
+ va_list args ;
206
+ int result , saved_errno = errno ;
207
+
208
+ if ((* tries ) < ARRAY_SIZE (delay )) {
209
+ /*
210
+ * We assume that some other process had the file open at the wrong
211
+ * moment and retry. In order to give the other process a higher
212
+ * chance to complete its operation, we give up our time slice now.
213
+ * If we have to retry again, we do sleep a bit.
214
+ */
215
+ Sleep (delay [* tries ]);
216
+ (* tries )++ ;
217
+ return 1 ;
218
+ }
219
+
220
+ va_start (args , format );
221
+ result = ask_yes_no_if_possible (format , args );
222
+ va_end (args );
223
+ errno = saved_errno ;
224
+ return result ;
225
+ }
226
+
205
227
int mingw_unlink (const char * pathname )
206
228
{
207
- int ret , tries = 0 ;
229
+ int tries = 0 ;
208
230
wchar_t wpathname [MAX_LONG_PATH ];
209
231
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
210
232
return -1 ;
211
233
212
- /* read-only files cannot be removed */
213
- _wchmod (wpathname , 0666 );
214
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
234
+ do {
235
+ /* read-only files cannot be removed */
236
+ _wchmod (wpathname , 0666 );
237
+ if (!_wunlink (wpathname ))
238
+ return 0 ;
215
239
if (!is_file_in_use_error (GetLastError ()))
216
240
break ;
217
- /*
218
- * We assume that some other process had the source or
219
- * destination file open at the wrong moment and retry.
220
- * In order to give the other process a higher chance to
221
- * complete its operation, we give up our time slice now.
222
- * If we have to retry again, we do sleep a bit.
223
- */
224
- Sleep (delay [tries ]);
225
- tries ++ ;
226
- }
227
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
228
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
229
- "Should I try again?" , pathname ))
230
- ret = _wunlink (wpathname );
231
- return ret ;
241
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
242
+ "Should I try again?" , pathname ));
243
+ return -1 ;
232
244
}
233
245
234
246
static int is_dir_empty (const wchar_t * wpath )
@@ -255,12 +267,14 @@ static int is_dir_empty(const wchar_t *wpath)
255
267
256
268
int mingw_rmdir (const char * pathname )
257
269
{
258
- int ret , tries = 0 ;
270
+ int tries = 0 ;
259
271
wchar_t wpathname [MAX_LONG_PATH ];
260
272
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
261
273
return -1 ;
262
274
263
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
275
+ do {
276
+ if (!_wrmdir (wpathname ))
277
+ return 0 ;
264
278
if (!is_file_in_use_error (GetLastError ()))
265
279
errno = err_win_to_posix (GetLastError ());
266
280
if (errno != EACCES )
@@ -269,21 +283,9 @@ int mingw_rmdir(const char *pathname)
269
283
errno = ENOTEMPTY ;
270
284
break ;
271
285
}
272
- /*
273
- * We assume that some other process had the source or
274
- * destination file open at the wrong moment and retry.
275
- * In order to give the other process a higher chance to
276
- * complete its operation, we give up our time slice now.
277
- * If we have to retry again, we do sleep a bit.
278
- */
279
- Sleep (delay [tries ]);
280
- tries ++ ;
281
- }
282
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
283
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
284
- "Should I try again?" , pathname ))
285
- ret = _wrmdir (wpathname );
286
- return ret ;
286
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
287
+ "Should I try again?" , pathname ));
288
+ return -1 ;
287
289
}
288
290
289
291
static inline int needs_hiding (const char * path )
@@ -1798,20 +1800,8 @@ int mingw_rename(const char *pold, const char *pnew)
1798
1800
SetFileAttributesW (wpnew , attrs );
1799
1801
}
1800
1802
}
1801
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
1802
- /*
1803
- * We assume that some other process had the source or
1804
- * destination file open at the wrong moment and retry.
1805
- * In order to give the other process a higher chance to
1806
- * complete its operation, we give up our time slice now.
1807
- * If we have to retry again, we do sleep a bit.
1808
- */
1809
- Sleep (delay [tries ]);
1810
- tries ++ ;
1811
- goto repeat ;
1812
- }
1813
1803
if (gle == ERROR_ACCESS_DENIED &&
1814
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
1804
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
1815
1805
"Should I try again?" , pold , pnew ))
1816
1806
goto repeat ;
1817
1807
0 commit comments