28
29
#define HCAST(type, handle) ((type)(intptr_t)handle)
30
31
-static const int delay[] = { 0, 1, 10, 20, 40 };
32
-
31
void open_in_gdb(void)
32
{
33
static struct child_process cp = CHILD_PROCESS_INIT;
203
return -1;
204
}
205
208
-static int ask_yes_no_if_possible(const char *format, ...)
206
+static int ask_yes_no_if_possible(const char *format, va_list args)
207
{
208
char question[4096];
209
const char *retry_hook;
212
- va_list args;
210
214
- va_start(args, format);
211
vsnprintf(question, sizeof(question), format, args);
216
- va_end(args);
212
213
retry_hook = mingw_getenv("GIT_ASK_YESNO");
214
if (retry_hook) {
233
}
234
}
235
236
+static int retry_ask_yes_no(int *tries, const char *format, ...)
237
+{
238
+ static const int delay[] = { 0, 1, 10, 20, 40 };
239
+ va_list args;
240
+ int result, saved_errno = errno;
241
+
242
+ if ((*tries) < ARRAY_SIZE(delay)) {
243
+ /*
244
+ * We assume that some other process had the file open at the wrong
245
+ * moment and retry. In order to give the other process a higher
246
+ * chance to complete its operation, we give up our time slice now.
247
+ * If we have to retry again, we do sleep a bit.
248
+ */
249
+ Sleep(delay[*tries]);
250
+ (*tries)++;
251
+ return 1;
252
+ }
253
+
254
+ va_start(args, format);
255
+ result = ask_yes_no_if_possible(format, args);
256
+ va_end(args);
257
+ errno = saved_errno;
258
+ return result;
259
+}
260
+
261
/* Windows only */
262
enum hide_dotfiles_type {
263
HIDE_DOTFILES_FALSE = 0,
318
319
int mingw_unlink(const char *pathname, int handle_in_use_error)
320
{
301
- int ret, tries = 0;
321
+ int tries = 0;
322
wchar_t wpathname[MAX_PATH];
323
if (xutftowcs_path(wpathname, pathname) < 0)
324
return -1;
326
if (DeleteFileW(wpathname))
327
return 0;
328
309
- /* read-only files cannot be removed */
310
- _wchmod(wpathname, 0666);
311
- while ((ret = _wunlink(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
329
+ do {
330
+ /* read-only files cannot be removed */
331
+ _wchmod(wpathname, 0666);
332
+ if (!_wunlink(wpathname))
333
+ return 0;
334
if (!is_file_in_use_error(GetLastError()))
335
break;
336
if (!handle_in_use_error)
315
- return ret;
337
+ return -1;
338
317
- /*
318
- * We assume that some other process had the source or
319
- * destination file open at the wrong moment and retry.
320
- * In order to give the other process a higher chance to
321
- * complete its operation, we give up our time slice now.
322
- * If we have to retry again, we do sleep a bit.
323
- */
324
- Sleep(delay[tries]);
325
- tries++;
326
- }
327
- while (ret == -1 && is_file_in_use_error(GetLastError()) &&
328
- ask_yes_no_if_possible("Unlink of file '%s' failed. "
329
- "Should I try again?", pathname))
330
- ret = _wunlink(wpathname);
331
- return ret;
339
+ } while (retry_ask_yes_no(&tries, "Unlink of file '%s' failed. "
340
+ "Should I try again?", pathname));
341
+ return -1;
342
}
343
344
static int is_dir_empty(const wchar_t *wpath)
365
366
int mingw_rmdir(const char *pathname)
367
{
358
- int ret, tries = 0;
368
+ int tries = 0;
369
wchar_t wpathname[MAX_PATH];
370
struct stat st;
371
391
if (xutftowcs_path(wpathname, pathname) < 0)
392
return -1;
393
384
- while ((ret = _wrmdir(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
394
+ do {
395
+ if (!_wrmdir(wpathname)) {
396
+ invalidate_lstat_cache();
397
+ return 0;
398
+ }
399
if (!is_file_in_use_error(GetLastError()))
400
errno = err_win_to_posix(GetLastError());
401
if (errno != EACCES)
404
errno = ENOTEMPTY;
405
break;
406
}
393
- /*
394
- * We assume that some other process had the source or
395
- * destination file open at the wrong moment and retry.
396
- * In order to give the other process a higher chance to
397
- * complete its operation, we give up our time slice now.
398
- * If we have to retry again, we do sleep a bit.
399
- */
400
- Sleep(delay[tries]);
401
- tries++;
402
- }
403
- while (ret == -1 && errno == EACCES && is_file_in_use_error(GetLastError()) &&
404
- ask_yes_no_if_possible("Deletion of directory '%s' failed. "
405
- "Should I try again?", pathname))
406
- ret = _wrmdir(wpathname);
407
- if (!ret)
408
- invalidate_lstat_cache();
409
- return ret;
407
+ } while (retry_ask_yes_no(&tries, "Deletion of directory '%s' failed. "
408
+ "Should I try again?", pathname));
409
+ return -1;
410
}
411
412
static inline int needs_hiding(const char *path)
2384
SetFileAttributesW(wpnew, attrs);
2385
}
2386
}
2387
- if (tries < ARRAY_SIZE(delay) && gle == ERROR_ACCESS_DENIED) {
2388
- /*
2389
- * We assume that some other process had the source or
2390
- * destination file open at the wrong moment and retry.
2391
- * In order to give the other process a higher chance to
2392
- * complete its operation, we give up our time slice now.
2393
- * If we have to retry again, we do sleep a bit.
2394
- */
2395
- Sleep(delay[tries]);
2396
- tries++;
2397
- goto repeat;
2398
- }
2387
if (gle == ERROR_ACCESS_DENIED &&
2400
- ask_yes_no_if_possible("Rename from '%s' to '%s' failed. "
2388
+ retry_ask_yes_no(&tries, "Rename from '%s' to '%s' failed. "
2389
"Should I try again?", pold, pnew))
2390
goto repeat;
2391