9
9
10
10
#define HCAST (type , handle ) ((type)(intptr_t)handle)
11
11
12
- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
13
-
14
12
int err_win_to_posix (DWORD winerr )
15
13
{
16
14
int error = ENOSYS ;
@@ -173,15 +171,12 @@ static int read_yes_no_answer(void)
173
171
return -1 ;
174
172
}
175
173
176
- static int ask_yes_no_if_possible (const char * format , ... )
174
+ static int ask_yes_no_if_possible (const char * format , va_list args )
177
175
{
178
176
char question [4096 ];
179
177
const char * retry_hook [] = { NULL , NULL , NULL };
180
- va_list args ;
181
178
182
- va_start (args , format );
183
179
vsnprintf (question , sizeof (question ), format , args );
184
- va_end (args );
185
180
186
181
if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
187
182
retry_hook [1 ] = question ;
@@ -203,6 +198,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
203
198
}
204
199
}
205
200
201
+ static int retry_ask_yes_no (int * tries , const char * format , ...)
202
+ {
203
+ static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
204
+ va_list args ;
205
+ int result , saved_errno = errno ;
206
+
207
+ if ((* tries ) < ARRAY_SIZE (delay )) {
208
+ /*
209
+ * We assume that some other process had the file open at the wrong
210
+ * moment and retry. In order to give the other process a higher
211
+ * chance to complete its operation, we give up our time slice now.
212
+ * If we have to retry again, we do sleep a bit.
213
+ */
214
+ Sleep (delay [* tries ]);
215
+ (* tries )++ ;
216
+ return 1 ;
217
+ }
218
+
219
+ va_start (args , format );
220
+ result = ask_yes_no_if_possible (format , args );
221
+ va_end (args );
222
+ errno = saved_errno ;
223
+ return result ;
224
+ }
225
+
206
226
/* Windows only */
207
227
enum hide_dotfiles_type {
208
228
HIDE_DOTFILES_FALSE = 0 ,
@@ -271,31 +291,21 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
271
291
272
292
int mingw_unlink (const char * pathname )
273
293
{
274
- int ret , tries = 0 ;
294
+ int tries = 0 ;
275
295
wchar_t wpathname [MAX_LONG_PATH ];
276
296
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
277
297
return -1 ;
278
298
279
- /* read-only files cannot be removed */
280
- _wchmod (wpathname , 0666 );
281
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
299
+ do {
300
+ /* read-only files cannot be removed */
301
+ _wchmod (wpathname , 0666 );
302
+ if (!_wunlink (wpathname ))
303
+ return 0 ;
282
304
if (!is_file_in_use_error (GetLastError ()))
283
305
break ;
284
- /*
285
- * We assume that some other process had the source or
286
- * destination file open at the wrong moment and retry.
287
- * In order to give the other process a higher chance to
288
- * complete its operation, we give up our time slice now.
289
- * If we have to retry again, we do sleep a bit.
290
- */
291
- Sleep (delay [tries ]);
292
- tries ++ ;
293
- }
294
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
295
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
296
- "Should I try again?" , pathname ))
297
- ret = _wunlink (wpathname );
298
- return ret ;
306
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
307
+ "Should I try again?" , pathname ));
308
+ return -1 ;
299
309
}
300
310
301
311
static int is_dir_empty (const wchar_t * wpath )
@@ -322,12 +332,14 @@ static int is_dir_empty(const wchar_t *wpath)
322
332
323
333
int mingw_rmdir (const char * pathname )
324
334
{
325
- int ret , tries = 0 ;
335
+ int tries = 0 ;
326
336
wchar_t wpathname [MAX_LONG_PATH ];
327
337
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
328
338
return -1 ;
329
339
330
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
340
+ do {
341
+ if (!_wrmdir (wpathname ))
342
+ return 0 ;
331
343
if (!is_file_in_use_error (GetLastError ()))
332
344
errno = err_win_to_posix (GetLastError ());
333
345
if (errno != EACCES )
@@ -336,21 +348,9 @@ int mingw_rmdir(const char *pathname)
336
348
errno = ENOTEMPTY ;
337
349
break ;
338
350
}
339
- /*
340
- * We assume that some other process had the source or
341
- * destination file open at the wrong moment and retry.
342
- * In order to give the other process a higher chance to
343
- * complete its operation, we give up our time slice now.
344
- * If we have to retry again, we do sleep a bit.
345
- */
346
- Sleep (delay [tries ]);
347
- tries ++ ;
348
- }
349
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
350
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
351
- "Should I try again?" , pathname ))
352
- ret = _wrmdir (wpathname );
353
- return ret ;
351
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
352
+ "Should I try again?" , pathname ));
353
+ return -1 ;
354
354
}
355
355
356
356
static inline int needs_hiding (const char * path )
@@ -2010,20 +2010,8 @@ int mingw_rename(const char *pold, const char *pnew)
2010
2010
SetFileAttributesW (wpnew , attrs );
2011
2011
}
2012
2012
}
2013
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2014
- /*
2015
- * We assume that some other process had the source or
2016
- * destination file open at the wrong moment and retry.
2017
- * In order to give the other process a higher chance to
2018
- * complete its operation, we give up our time slice now.
2019
- * If we have to retry again, we do sleep a bit.
2020
- */
2021
- Sleep (delay [tries ]);
2022
- tries ++ ;
2023
- goto repeat ;
2024
- }
2025
2013
if (gle == ERROR_ACCESS_DENIED &&
2026
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2014
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2027
2015
"Should I try again?" , pold , pnew ))
2028
2016
goto repeat ;
2029
2017
0 commit comments