10
10
11
11
#define HCAST (type , handle ) ((type)(intptr_t)handle)
12
12
13
- static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
14
-
15
13
int err_win_to_posix (DWORD winerr )
16
14
{
17
15
int error = ENOSYS ;
@@ -174,15 +172,12 @@ static int read_yes_no_answer(void)
174
172
return -1 ;
175
173
}
176
174
177
- static int ask_yes_no_if_possible (const char * format , ... )
175
+ static int ask_yes_no_if_possible (const char * format , va_list args )
178
176
{
179
177
char question [4096 ];
180
178
const char * retry_hook [] = { NULL , NULL , NULL };
181
- va_list args ;
182
179
183
- va_start (args , format );
184
180
vsnprintf (question , sizeof (question ), format , args );
185
- va_end (args );
186
181
187
182
if ((retry_hook [0 ] = mingw_getenv ("GIT_ASK_YESNO" ))) {
188
183
retry_hook [1 ] = question ;
@@ -204,6 +199,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
204
199
}
205
200
}
206
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
+
207
227
/* Windows only */
208
228
enum hide_dotfiles_type {
209
229
HIDE_DOTFILES_FALSE = 0 ,
@@ -272,31 +292,21 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf)
272
292
273
293
int mingw_unlink (const char * pathname )
274
294
{
275
- int ret , tries = 0 ;
295
+ int tries = 0 ;
276
296
wchar_t wpathname [MAX_LONG_PATH ];
277
297
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
278
298
return -1 ;
279
299
280
- /* read-only files cannot be removed */
281
- _wchmod (wpathname , 0666 );
282
- while ((ret = _wunlink (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
300
+ do {
301
+ /* read-only files cannot be removed */
302
+ _wchmod (wpathname , 0666 );
303
+ if (!_wunlink (wpathname ))
304
+ return 0 ;
283
305
if (!is_file_in_use_error (GetLastError ()))
284
306
break ;
285
- /*
286
- * We assume that some other process had the source or
287
- * destination file open at the wrong moment and retry.
288
- * In order to give the other process a higher chance to
289
- * complete its operation, we give up our time slice now.
290
- * If we have to retry again, we do sleep a bit.
291
- */
292
- Sleep (delay [tries ]);
293
- tries ++ ;
294
- }
295
- while (ret == -1 && is_file_in_use_error (GetLastError ()) &&
296
- ask_yes_no_if_possible ("Unlink of file '%s' failed. "
297
- "Should I try again?" , pathname ))
298
- ret = _wunlink (wpathname );
299
- return ret ;
307
+ } while (retry_ask_yes_no (& tries , "Unlink of file '%s' failed. "
308
+ "Should I try again?" , pathname ));
309
+ return -1 ;
300
310
}
301
311
302
312
static int is_dir_empty (const wchar_t * wpath )
@@ -323,12 +333,14 @@ static int is_dir_empty(const wchar_t *wpath)
323
333
324
334
int mingw_rmdir (const char * pathname )
325
335
{
326
- int ret , tries = 0 ;
336
+ int tries = 0 ;
327
337
wchar_t wpathname [MAX_LONG_PATH ];
328
338
if (xutftowcs_long_path (wpathname , pathname ) < 0 )
329
339
return -1 ;
330
340
331
- while ((ret = _wrmdir (wpathname )) == -1 && tries < ARRAY_SIZE (delay )) {
341
+ do {
342
+ if (!_wrmdir (wpathname ))
343
+ return 0 ;
332
344
if (!is_file_in_use_error (GetLastError ()))
333
345
errno = err_win_to_posix (GetLastError ());
334
346
if (errno != EACCES )
@@ -337,21 +349,9 @@ int mingw_rmdir(const char *pathname)
337
349
errno = ENOTEMPTY ;
338
350
break ;
339
351
}
340
- /*
341
- * We assume that some other process had the source or
342
- * destination file open at the wrong moment and retry.
343
- * In order to give the other process a higher chance to
344
- * complete its operation, we give up our time slice now.
345
- * If we have to retry again, we do sleep a bit.
346
- */
347
- Sleep (delay [tries ]);
348
- tries ++ ;
349
- }
350
- while (ret == -1 && errno == EACCES && is_file_in_use_error (GetLastError ()) &&
351
- ask_yes_no_if_possible ("Deletion of directory '%s' failed. "
352
- "Should I try again?" , pathname ))
353
- ret = _wrmdir (wpathname );
354
- return ret ;
352
+ } while (retry_ask_yes_no (& tries , "Deletion of directory '%s' failed. "
353
+ "Should I try again?" , pathname ));
354
+ return -1 ;
355
355
}
356
356
357
357
static inline int needs_hiding (const char * path )
@@ -2049,20 +2049,8 @@ int mingw_rename(const char *pold, const char *pnew)
2049
2049
SetFileAttributesW (wpnew , attrs );
2050
2050
}
2051
2051
}
2052
- if (tries < ARRAY_SIZE (delay ) && gle == ERROR_ACCESS_DENIED ) {
2053
- /*
2054
- * We assume that some other process had the source or
2055
- * destination file open at the wrong moment and retry.
2056
- * In order to give the other process a higher chance to
2057
- * complete its operation, we give up our time slice now.
2058
- * If we have to retry again, we do sleep a bit.
2059
- */
2060
- Sleep (delay [tries ]);
2061
- tries ++ ;
2062
- goto repeat ;
2063
- }
2064
2052
if (gle == ERROR_ACCESS_DENIED &&
2065
- ask_yes_no_if_possible ( "Rename from '%s' to '%s' failed. "
2053
+ retry_ask_yes_no ( & tries , "Rename from '%s' to '%s' failed. "
2066
2054
"Should I try again?" , pold , pnew ))
2067
2055
goto repeat ;
2068
2056
0 commit comments