diff --git a/compat/mingw.c b/compat/mingw.c index 25479604fa..78ad8f76fb 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -3,6 +3,7 @@ #include #include "../strbuf.h" #include "../cache.h" +#include "../run-command.h" unsigned int _CRT_fmode = _O_BINARY; static const int delay[] = { 0, 1, 10, 20, 40 }; @@ -156,6 +157,54 @@ int mingw_mkdir(const char *path, int mode) return ret; } +static int ask_user_yes_no(const char *format, ...) +{ + char answer[5]; + char question[4096]; + const char *retry_hook[] = { NULL, NULL, NULL }; + va_list args; + + if ((retry_hook[0] = getenv("GIT_ASK_YESNO"))) { + + va_start(args, format); + vsnprintf(question, sizeof(question), format, args); + va_end(args); + + retry_hook[1] = question; + return !run_command_v_opt(retry_hook, 0); + } + + if (!isatty(_fileno(stdin))) + return 0; + + while (1) { + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, " (y/n)? "); + + if (fgets(answer, sizeof(answer), stdin)) { + /* remove the newline */ + if (answer[strlen(answer)-2] == '\r') + answer[strlen(answer)-2] = '\0'; + if (answer[strlen(answer)-1] == '\n') + answer[strlen(answer)-1] = '\0'; + } else + return 0; + + if (answer[0] == 'y' && strlen(answer) == 1) + return 1; + if (!strncasecmp(answer, "yes", sizeof(answer))) + return 1; + if (answer[0] == 'n' && strlen(answer) == 1) + return 0; + if (!strncasecmp(answer, "no", sizeof(answer))) + return 0; + fprintf(stderr, "I did not understand your answer: '%s'\n", + answer); + } +} + #undef unlink int mingw_unlink(const char *pathname) { @@ -176,6 +225,10 @@ int mingw_unlink(const char *pathname) Sleep(delay[tries]); tries++; } + while (ret == -1 && errno == EACCES && + ask_user_yes_no("Unlink of file '%s' failed. " + "Should I try again?", pathname)) + ret = unlink(pathname); return ret; } @@ -1281,6 +1334,11 @@ repeat: tries++; goto repeat; } + if (gle == ERROR_ACCESS_DENIED && + ask_user_yes_no("Rename from '%s' to '%s' failed. " + "Should I try again?", pold, pnew)) + goto repeat; + errno = EACCES; return -1; }