From 02e6edc082969c3f52ea954e71b391410632dfba Mon Sep 17 00:00:00 2001 From: Karsten Blees Date: Tue, 26 Jan 2016 15:34:38 +0100 Subject: mingw: factor out Windows specific environment setup We will add more environment-related code to that new function in the next patch. Signed-off-by: Karsten Blees Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index 7115e4e09e..b592000f58 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2044,6 +2044,22 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen) return -1; } +static void setup_windows_environment() +{ + /* on Windows it is TMP and TEMP */ + if (!getenv("TMPDIR")) { + const char *tmp = getenv("TMP"); + if (!tmp) + tmp = getenv("TEMP"); + if (tmp) + setenv("TMPDIR", tmp, 1); + } + + /* 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). @@ -2122,19 +2138,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); -- cgit v1.2.3 From 1fc7bf79e5f907b85aa0213c0ad4969506cf8f2b Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 26 Jan 2016 15:34:43 +0100 Subject: mingw: prepare the TMPDIR environment variable for shell scripts When shell scripts access a $TMPDIR variable containing backslashes, they will be mistaken for escape characters. Let's not let that happen by converting them to forward slashes. This partially fixes t7800 with MSYS2. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index b592000f58..717931e359 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2046,13 +2046,28 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen) static void setup_windows_environment() { + char *tmp = getenv("TMPDIR"); + /* on Windows it is TMP and TEMP */ - if (!getenv("TMPDIR")) { - const char *tmp = getenv("TMP"); - if (!tmp) + if (!tmp) { + if (!(tmp = getenv("TMP"))) tmp = getenv("TEMP"); - if (tmp) + 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) */ -- cgit v1.2.3 From 4426fb51421cdbf6f8d4c8dfb8bffd7adb51e034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A7=88=EB=88=84=EC=97=98?= Date: Tue, 26 Jan 2016 15:34:47 +0100 Subject: mingw: try to delete target directory before renaming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the rename() function tries to move a directory it fails if the target directory exists. It should check if it can delete the (possibly empty) target directory and then try again to move the directory. This partially fixes t9100-git-svn-basic.sh. Signed-off-by: 마누엘 Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index 717931e359..9e64f76bde 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1603,7 +1603,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) && -- cgit v1.2.3 From 4b0abd5c695c87bf600e57b6a5c7d6844707d34c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 26 Jan 2016 15:34:52 +0100 Subject: mingw: let lstat() fail with errno == ENOTDIR when appropriate POSIX semantics requires lstat() to fail with ENOTDIR when "[a] component of the path prefix names an existing file that is neither a directory nor a symbolic link to a directory". See http://pubs.opengroup.org/onlinepubs/9699919799/functions/lstat.html This behavior is expected by t1404-update-ref-df-conflicts now. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- compat/mingw.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index 9e64f76bde..545e952a58 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -454,6 +454,39 @@ static inline time_t filetime_to_time_t(const FILETIME *ft) 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. @@ -514,6 +547,12 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf) 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; -- cgit v1.2.3