diff options
Diffstat (limited to 'compat/mingw.c')
-rw-r--r-- | compat/mingw.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index b5230149db..8ee0b6408e 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -460,8 +460,21 @@ static int mingw_open_append(wchar_t const *wfilename, int oflags, ...) handle = CreateFileW(wfilename, FILE_APPEND_DATA, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); - if (handle == INVALID_HANDLE_VALUE) - return errno = err_win_to_posix(GetLastError()), -1; + if (handle == INVALID_HANDLE_VALUE) { + DWORD err = GetLastError(); + + /* + * Some network storage solutions (e.g. Isilon) might return + * ERROR_INVALID_PARAMETER instead of expected error + * ERROR_PATH_NOT_FOUND, which results in an unknown error. If + * so, let's turn the error to ERROR_PATH_NOT_FOUND instead. + */ + if (err == ERROR_INVALID_PARAMETER) + err = ERROR_PATH_NOT_FOUND; + + errno = err_win_to_posix(err); + return -1; + } /* * No O_APPEND here, because the CRT uses it only to reset the @@ -964,7 +977,16 @@ revert_attrs: size_t mingw_strftime(char *s, size_t max, const char *format, const struct tm *tm) { - size_t ret = strftime(s, max, format, tm); + /* a pointer to the original strftime in case we can't find the UCRT version */ + static size_t (*fallback)(char *, size_t, const char *, const struct tm *) = strftime; + size_t ret; + DECLARE_PROC_ADDR(ucrtbase.dll, size_t, strftime, char *, size_t, + const char *, const struct tm *); + + if (INIT_PROC_ADDR(strftime)) + ret = strftime(s, max, format, tm); + else + ret = fallback(s, max, format, tm); if (!ret && errno == EINVAL) die("invalid strftime format: '%s'", format); @@ -1245,7 +1267,7 @@ static char *path_lookup(const char *cmd, int exe_only) int len = strlen(cmd); int isexe = len >= 4 && !strcasecmp(cmd+len-4, ".exe"); - if (strchr(cmd, '/') || strchr(cmd, '\\')) + if (strpbrk(cmd, "/\\")) return xstrdup(cmd); path = mingw_getenv("PATH"); @@ -1479,6 +1501,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen const char *(*quote_arg)(const char *arg) = is_msys2_sh(cmd ? cmd : *argv) ? quote_arg_msys2 : quote_arg_msvc; + const char *strace_env; /* Make sure to override previous errors, if any */ errno = 0; @@ -1562,6 +1585,31 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen free(quoted); } + strace_env = getenv("GIT_STRACE_COMMANDS"); + if (strace_env) { + char *p = path_lookup("strace.exe", 1); + if (!p) + return error("strace not found!"); + if (xutftowcs_path(wcmd, p) < 0) { + free(p); + return -1; + } + free(p); + if (!strcmp("1", strace_env) || + !strcasecmp("yes", strace_env) || + !strcasecmp("true", strace_env)) + strbuf_insert(&args, 0, "strace ", 7); + else { + const char *quoted = quote_arg(strace_env); + struct strbuf buf = STRBUF_INIT; + strbuf_addf(&buf, "strace -o %s ", quoted); + if (quoted != strace_env) + free((char *)quoted); + strbuf_insert(&args, 0, buf.buf, buf.len); + strbuf_release(&buf); + } + } + ALLOC_ARRAY(wargs, st_add(st_mult(2, args.len), 1)); xutftowcs(wargs, args.buf, 2 * args.len + 1); strbuf_release(&args); @@ -2581,12 +2629,14 @@ not_a_reserved_name: continue; } break; - case 'c': case 'C': /* COM<N>, CON, CONIN$, CONOUT$ */ + case 'c': case 'C': + /* COM1 ... COM9, CON, CONIN$, CONOUT$ */ if ((c = path[++i]) != 'o' && c != 'O') goto not_a_reserved_name; c = path[++i]; - if (c == 'm' || c == 'M') { /* COM<N> */ - if (!isdigit(path[++i])) + if (c == 'm' || c == 'M') { /* COM1 ... COM9 */ + c = path[++i]; + if (c < '1' || c > '9') goto not_a_reserved_name; } else if (c == 'n' || c == 'N') { /* CON */ c = path[i + 1]; |