Merge branch 'ef/mingw-rmdir'
authorJunio C Hamano <gitster@pobox.com>
Tue, 11 Dec 2012 23:51:14 +0000 (15:51 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 11 Dec 2012 23:51:14 +0000 (15:51 -0800)
MinGW has a workaround when rmdir unnecessarily fails to retry with
a prompt, but the logic was kicking in when the rmdir failed with
ENOTEMPTY, i.e. was expected to fail and there is no point retrying.

* ef/mingw-rmdir:
mingw_rmdir: do not prompt for retry when non-empty

1  2 
compat/mingw.c
diff --combined compat/mingw.c
index 34724c27815803c4440f7223a1bd84c1c2ba041a,28527abe22309d2c1380ee349caae90a3f5c638a..b67362558046f354b167fe185369b3d2b98879c1
@@@ -256,6 -256,8 +256,8 @@@ int mingw_rmdir(const char *pathname
  
        while ((ret = rmdir(pathname)) == -1 && tries < ARRAY_SIZE(delay)) {
                if (!is_file_in_use_error(GetLastError()))
+                       errno = err_win_to_posix(GetLastError());
+               if (errno != EACCES)
                        break;
                if (!is_dir_empty(pathname)) {
                        errno = ENOTEMPTY;
                Sleep(delay[tries]);
                tries++;
        }
-       while (ret == -1 && is_file_in_use_error(GetLastError()) &&
+       while (ret == -1 && errno == EACCES && is_file_in_use_error(GetLastError()) &&
               ask_yes_no_if_possible("Deletion of directory '%s' failed. "
                        "Should I try again?", pathname))
               ret = rmdir(pathname);
@@@ -319,31 -321,6 +321,31 @@@ ssize_t mingw_write(int fd, const void 
        return write(fd, buf, min(count, 31 * 1024 * 1024));
  }
  
 +static BOOL WINAPI ctrl_ignore(DWORD type)
 +{
 +      return TRUE;
 +}
 +
 +#undef fgetc
 +int mingw_fgetc(FILE *stream)
 +{
 +      int ch;
 +      if (!isatty(_fileno(stream)))
 +              return fgetc(stream);
 +
 +      SetConsoleCtrlHandler(ctrl_ignore, TRUE);
 +      while (1) {
 +              ch = fgetc(stream);
 +              if (ch != EOF || GetLastError() != ERROR_OPERATION_ABORTED)
 +                      break;
 +
 +              /* Ctrl+C was pressed, simulate SIGINT and retry */
 +              mingw_raise(SIGINT);
 +      }
 +      SetConsoleCtrlHandler(ctrl_ignore, FALSE);
 +      return ch;
 +}
 +
  #undef fopen
  FILE *mingw_fopen (const char *filename, const char *otype)
  {
@@@ -1571,7 -1548,7 +1573,7 @@@ static HANDLE timer_event
  static HANDLE timer_thread;
  static int timer_interval;
  static int one_shot;
 -static sig_handler_t timer_fn = SIG_DFL;
 +static sig_handler_t timer_fn = SIG_DFL, sigint_fn = SIG_DFL;
  
  /* The timer works like this:
   * The thread, ticktack(), is a trivial routine that most of the time
  static unsigned __stdcall ticktack(void *dummy)
  {
        while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) {
 -              if (timer_fn == SIG_DFL)
 -                      die("Alarm");
 -              if (timer_fn != SIG_IGN)
 -                      timer_fn(SIGALRM);
 +              mingw_raise(SIGALRM);
                if (one_shot)
                        break;
        }
@@@ -1676,49 -1656,12 +1678,49 @@@ int sigaction(int sig, struct sigactio
  sig_handler_t mingw_signal(int sig, sig_handler_t handler)
  {
        sig_handler_t old = timer_fn;
 -      if (sig != SIGALRM)
 +
 +      switch (sig) {
 +      case SIGALRM:
 +              timer_fn = handler;
 +              break;
 +
 +      case SIGINT:
 +              sigint_fn = handler;
 +              break;
 +
 +      default:
                return signal(sig, handler);
 -      timer_fn = handler;
 +      }
 +
        return old;
  }
  
 +#undef raise
 +int mingw_raise(int sig)
 +{
 +      switch (sig) {
 +      case SIGALRM:
 +              if (timer_fn == SIG_DFL) {
 +                      if (isatty(STDERR_FILENO))
 +                              fputs("Alarm clock\n", stderr);
 +                      exit(128 + SIGALRM);
 +              } else if (timer_fn != SIG_IGN)
 +                      timer_fn(SIGALRM);
 +              return 0;
 +
 +      case SIGINT:
 +              if (sigint_fn == SIG_DFL)
 +                      exit(128 + SIGINT);
 +              else if (sigint_fn != SIG_IGN)
 +                      sigint_fn(SIGINT);
 +              return 0;
 +
 +      default:
 +              return raise(sig);
 +      }
 +}
 +
 +
  static const char *make_backslash_path(const char *path)
  {
        static char buf[PATH_MAX + 1];
@@@ -1780,6 -1723,21 +1782,6 @@@ int link(const char *oldpath, const cha
        return 0;
  }
  
 -char *getpass(const char *prompt)
 -{
 -      struct strbuf buf = STRBUF_INIT;
 -
 -      fputs(prompt, stderr);
 -      for (;;) {
 -              char c = _getch();
 -              if (c == '\r' || c == '\n')
 -                      break;
 -              strbuf_addch(&buf, c);
 -      }
 -      fputs("\n", stderr);
 -      return strbuf_detach(&buf, NULL);
 -}
 -
  pid_t waitpid(pid_t pid, int *status, int options)
  {
        HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,