Merge branch 'jk/tighten-alloc'
authorJunio C Hamano <gitster@pobox.com>
Fri, 4 Mar 2016 21:46:25 +0000 (13:46 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 4 Mar 2016 21:46:25 +0000 (13:46 -0800)
* jk/tighten-alloc:
compat/mingw: brown paper bag fix for 50a6c8e

1  2 
compat/mingw.c
diff --combined compat/mingw.c
index cfedcf9656549050c1d97ab69000d4279d1b0b5e,af56c1fe6116a448a0699ef3360e24e0ecbe419f..54c82ecf201dde2c317efe6862173c1b40f2552d
@@@ -6,8 -6,6 +6,8 @@@
  #include "../run-command.h"
  #include "../cache.h"
  
 +#define HCAST(type, handle) ((type)(intptr_t)handle)
 +
  static const int delay[] = { 0, 1, 10, 20, 40 };
  
  int err_win_to_posix(DWORD winerr)
@@@ -454,39 -452,6 +454,39 @@@ static inline time_t filetime_to_time_t
        return (time_t)(filetime_to_hnsec(ft) / 10000000);
  }
  
 +/**
 + * Verifies that safe_create_leading_directories() would succeed.
 + */
 +static int has_valid_directory_prefix(wchar_t *wfilename)
 +{
 +      int n = wcslen(wfilename);
 +
 +      while (n > 0) {
 +              wchar_t c = wfilename[--n];
 +              DWORD attributes;
 +
 +              if (!is_dir_sep(c))
 +                      continue;
 +
 +              wfilename[n] = L'\0';
 +              attributes = GetFileAttributesW(wfilename);
 +              wfilename[n] = c;
 +              if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
 +                              attributes == FILE_ATTRIBUTE_DEVICE)
 +                      return 1;
 +              if (attributes == INVALID_FILE_ATTRIBUTES)
 +                      switch (GetLastError()) {
 +                      case ERROR_PATH_NOT_FOUND:
 +                              continue;
 +                      case ERROR_FILE_NOT_FOUND:
 +                              /* This implies parent directory exists. */
 +                              return 1;
 +                      }
 +              return 0;
 +      }
 +      return 1;
 +}
 +
  /* We keep the do_lstat code in a separate function to avoid recursion.
   * When a path ends with a slash, the stat will fail with ENOENT. In
   * this case, we strip the trailing slashes and stat again.
@@@ -547,12 -512,6 +547,12 @@@ static int do_lstat(int follow, const c
        case ERROR_NOT_ENOUGH_MEMORY:
                errno = ENOMEM;
                break;
 +      case ERROR_PATH_NOT_FOUND:
 +              if (!has_valid_directory_prefix(wfilename)) {
 +                      errno = ENOTDIR;
 +                      break;
 +              }
 +              /* fallthru */
        default:
                errno = ENOENT;
                break;
@@@ -732,13 -691,13 +732,13 @@@ int pipe(int filedes[2]
                errno = err_win_to_posix(GetLastError());
                return -1;
        }
 -      filedes[0] = _open_osfhandle((int)h[0], O_NOINHERIT);
 +      filedes[0] = _open_osfhandle(HCAST(int, h[0]), O_NOINHERIT);
        if (filedes[0] < 0) {
                CloseHandle(h[0]);
                CloseHandle(h[1]);
                return -1;
        }
 -      filedes[1] = _open_osfhandle((int)h[1], O_NOINHERIT);
 +      filedes[1] = _open_osfhandle(HCAST(int, h[1]), O_NOINHERIT);
        if (filedes[1] < 0) {
                close(filedes[0]);
                CloseHandle(h[1]);
@@@ -1069,7 -1028,7 +1069,7 @@@ static pid_t mingw_spawnve_fd(const cha
                        free(quoted);
        }
  
-       wargs = xmalloc_array(st_add(st_mult(2, args.len), 1), sizeof(wchar_t));
+       ALLOC_ARRAY(wargs, st_add(st_mult(2, args.len), 1));
        xutftowcs(wargs, args.buf, 2 * args.len + 1);
        strbuf_release(&args);
  
@@@ -1642,12 -1601,7 +1642,12 @@@ repeat
        if (gle == ERROR_ACCESS_DENIED &&
            (attrs = GetFileAttributesW(wpnew)) != INVALID_FILE_ATTRIBUTES) {
                if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
 -                      errno = EISDIR;
 +                      DWORD attrsold = GetFileAttributesW(wpold);
 +                      if (attrsold == INVALID_FILE_ATTRIBUTES ||
 +                          !(attrsold & FILE_ATTRIBUTE_DIRECTORY))
 +                              errno = EISDIR;
 +                      else if (!_wrmdir(wpnew))
 +                              goto repeat;
                        return -1;
                }
                if ((attrs & FILE_ATTRIBUTE_READONLY) &&
@@@ -1892,8 -1846,7 +1892,8 @@@ void mingw_open_html(const char *unixpa
                die("cannot run browser");
  
        printf("Launching default browser to display HTML ...\n");
 -      r = (int)ShellExecute(NULL, "open", htmlpath, NULL, "\\", SW_SHOWNORMAL);
 +      r = HCAST(int, ShellExecute(NULL, "open", htmlpath,
 +                              NULL, "\\", SW_SHOWNORMAL));
        FreeLibrary(shell32);
        /* see the MSDN documentation referring to the result codes here */
        if (r <= 32) {
@@@ -2091,37 -2044,6 +2091,37 @@@ int xwcstoutf(char *utf, const wchar_t 
        return -1;
  }
  
 +static void setup_windows_environment()
 +{
 +      char *tmp = getenv("TMPDIR");
 +
 +      /* on Windows it is TMP and TEMP */
 +      if (!tmp) {
 +              if (!(tmp = getenv("TMP")))
 +                      tmp = getenv("TEMP");
 +              if (tmp) {
 +                      setenv("TMPDIR", tmp, 1);
 +                      tmp = getenv("TMPDIR");
 +              }
 +      }
 +
 +      if (tmp) {
 +              /*
 +               * Convert all dir separators to forward slashes,
 +               * to help shell commands called from the Git
 +               * executable (by not mistaking the dir separators
 +               * for escape characters).
 +               */
 +              for (; *tmp; tmp++)
 +                      if (*tmp == '\\')
 +                              *tmp = '/';
 +      }
 +
 +      /* simulate TERM to enable auto-color (see color.c) */
 +      if (!getenv("TERM"))
 +              setenv("TERM", "cygwin", 1);
 +}
 +
  /*
   * Disable MSVCRT command line wildcard expansion (__getmainargs called from
   * mingw startup code, see init.c in mingw runtime).
@@@ -2200,7 -2122,19 +2200,7 @@@ void mingw_startup(
        qsort(environ, i, sizeof(char*), compareenv);
  
        /* fix Windows specific environment settings */
 -
 -      /* on Windows it is TMP and TEMP */
 -      if (!mingw_getenv("TMPDIR")) {
 -              const char *tmp = mingw_getenv("TMP");
 -              if (!tmp)
 -                      tmp = mingw_getenv("TEMP");
 -              if (tmp)
 -                      setenv("TMPDIR", tmp, 1);
 -      }
 -
 -      /* simulate TERM to enable auto-color (see color.c) */
 -      if (!getenv("TERM"))
 -              setenv("TERM", "cygwin", 1);
 +      setup_windows_environment();
  
        /* initialize critical section for waitpid pinfo_t list */
        InitializeCriticalSection(&pinfo_cs);