summaryrefslogtreecommitdiff
path: root/compat/mingw.h
AgeCommit message (Collapse)AuthorFilesLines
2019-12-06Sync with 2.16.6Libravatar Johannes Schindelin1-2/+16
* maint-2.16: (31 commits) Git 2.16.6 test-drop-caches: use `has_dos_drive_prefix()` Git 2.15.4 Git 2.14.6 mingw: handle `subst`-ed "DOS drives" mingw: refuse to access paths with trailing spaces or periods mingw: refuse to access paths with illegal characters unpack-trees: let merged_entry() pass through do_add_entry()'s errors quote-stress-test: offer to test quoting arguments for MSYS2 sh t6130/t9350: prepare for stringent Win32 path validation quote-stress-test: allow skipping some trials quote-stress-test: accept arguments to test via the command-line tests: add a helper to stress test argument quoting mingw: fix quoting of arguments Disallow dubiously-nested submodule git directories protect_ntfs: turn on NTFS protection by default path: also guard `.gitmodules` against NTFS Alternate Data Streams is_ntfs_dotgit(): speed it up mingw: disallow backslash characters in tree objects' file names path: safeguard `.git` against NTFS Alternate Streams Accesses ...
2019-12-05mingw: handle `subst`-ed "DOS drives"Libravatar Johannes Schindelin1-2/+2
Over a decade ago, in 25fe217b86c (Windows: Treat Windows style path names., 2008-03-05), Git was taught to handle absolute Windows paths, i.e. paths that start with a drive letter and a colon. Unbeknownst to us, while drive letters of physical drives are limited to letters of the English alphabet, there is a way to assign virtual drive letters to arbitrary directories, via the `subst` command, which is _not_ limited to English letters. It is therefore possible to have absolute Windows paths of the form `1:\what\the\hex.txt`. Even "better": pretty much arbitrary Unicode letters can also be used, e.g. `ä:\tschibät.sch`. While it can be sensibly argued that users who set up such funny drive letters really seek adverse consequences, the Windows Operating System is known to be a platform where many users are at the mercy of administrators who have their very own idea of what constitutes a reasonable setup. Therefore, let's just make sure that such funny paths are still considered absolute paths by Git, on Windows. In addition to Unicode characters, pretty much any character is a valid drive letter, as far as `subst` is concerned, even `:` and `"` or even a space character. While it is probably the opposite of smart to use them, let's safeguard `is_dos_drive_prefix()` against all of them. Note: `[::1]:repo` is a valid URL, but not a valid path on Windows. As `[` is now considered a valid drive letter, we need to be very careful to avoid misinterpreting such a string as valid local path in `url_is_local_not_ssh()`. To do that, we use the just-introduced function `is_valid_path()` (which will label the string as invalid file name because of the colon characters). This fixes CVE-2019-1351. Reported-by: Nicolas Joly <Nicolas.Joly@microsoft.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-12-05mingw: refuse to access paths with illegal charactersLibravatar Johannes Schindelin1-2/+5
Certain characters are not admissible in file names on Windows, even if Cygwin/MSYS2 (and therefore, Git for Windows' Bash) pretend that they are, e.g. `:`, `<`, `>`, etc Let's disallow those characters explicitly in Windows builds of Git. Note: just like trailing spaces or periods, it _is_ possible on Windows to create commits adding files with such illegal characters, as long as the operation leaves the worktree untouched. To allow for that, we continue to guard `is_valid_win32_path()` behind the config setting `core.protectNTFS`, so that users _can_ continue to do that, as long as they turn the protections off via that config setting. Among other problems, this prevents Git from trying to write to an "NTFS Alternate Data Stream" (which refers to metadata stored alongside a file, under a special name: "<filename>:<stream-name>"). This fix therefore also prevents an attack vector that was exploited in demonstrations of a number of recently-fixed security bugs. Further reading on illegal characters in Win32 filenames: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2019-12-05mingw: refuse to access paths with trailing spaces or periodsLibravatar Johannes Schindelin1-0/+11
When creating a directory on Windows whose path ends in a space or a period (or chains thereof), the Win32 API "helpfully" trims those. For example, `mkdir("abc ");` will return success, but actually create a directory called `abc` instead. This stems back to the DOS days, when all file names had exactly 8 characters plus exactly 3 characters for the file extension, and the only way to have shorter names was by padding with spaces. Sadly, this "helpful" behavior is a bit inconsistent: after a successful `mkdir("abc ");`, a `mkdir("abc /def")` will actually _fail_ (because the directory `abc ` does not actually exist). Even if it would work, we now have a serious problem because a Git repository could contain directories `abc` and `abc `, and on Windows, they would be "merged" unintentionally. As these paths are illegal on Windows, anyway, let's disallow any accesses to such paths on that Operating System. For practical reasons, this behavior is still guarded by the config setting `core.protectNTFS`: it is possible (and at least two regression tests make use of it) to create commits without involving the worktree. In such a scenario, it is of course possible -- even on Windows -- to create such file names. Among other consequences, this patch disallows submodules' paths to end in spaces on Windows (which would formerly have confused Git enough to try to write into incorrect paths, anyway). While this patch does not fix a vulnerability on its own, it prevents an attack vector that was exploited in demonstrations of a number of recently-fixed security bugs. The regression test added to `t/t7417-submodule-path-url.sh` reflects that attack vector. Note that we have to adjust the test case "prevent git~1 squatting on Windows" in `t/t7415-submodule-names.sh` because of a very subtle issue. It tries to clone two submodules whose names differ only in a trailing period character, and as a consequence their git directories differ in the same way. Previously, when Git tried to clone the second submodule, it thought that the git directory already existed (because on Windows, when you create a directory with the name `b.` it actually creates `b`), but with this patch, the first submodule's clone will fail because of the illegal name of the git directory. Therefore, when cloning the second submodule, Git will take a different code path: a fresh clone (without an existing git directory). Both code paths fail to clone the second submodule, both because the the corresponding worktree directory exists and is not empty, but the error messages are worded differently. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2018-03-19mingw: abort on invalid strftime formatsLibravatar Johannes Schindelin1-0/+3
On Windows, strftime() does not silently ignore invalid formats, but warns about them and then returns 0 and sets errno to EINVAL. Unfortunately, Git does not expect such a behavior, as it disagrees with strftime()'s semantics on Linux. As a consequence, Git misinterprets the return value 0 as "I need more space" and grows the buffer. As the larger buffer does not fix the format, the buffer grows and grows and grows until we are out of memory and abort. Ideally, we would switch off the parameter validation just for strftime(), but we cannot even override the invalid parameter handler via _set_thread_local_invalid_parameter_handler() using MINGW because that function is not declared. Even _set_invalid_parameter_handler(), which *is* declared, does not help, as it simply does... nothing. So let's just bite the bullet and override strftime() for MINGW and abort on an invalid format string. While this does not provide the best user experience, it is the best we can do. See https://msdn.microsoft.com/en-us/library/fe06s4ak.aspx for more details. This fixes https://github.com/git-for-windows/git/issues/863 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-02Merge branch 'js/bs-is-a-dir-sep-on-windows'Libravatar Junio C Hamano1-1/+5
"foo\bar\baz" in "git fetch foo\bar\baz", even though there is no slashes in it, cannot be a nickname for a remote on Windows, as that is likely to be a pathname on a local filesystem. * js/bs-is-a-dir-sep-on-windows: Windows: do not treat a path with backslashes as a remote's nick name mingw.h: permit arguments with side effects for is_dir_sep
2017-05-23mingw.h: permit arguments with side effects for is_dir_sepLibravatar Johannes Sixt1-1/+5
Taking git-compat-util.h's cue (which uses an inline function to back is_dir_sep()), let's use an inline function to back also the Windows version of is_dir_sep(). This avoids problems when calling the function with arguments that do more than just provide a single character, e.g. incrementing a pointer. Example: is_dir_sep(*p++) Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-12-11mingw: intercept isatty() to handle /dev/null as Git expects itLibravatar Johannes Schindelin1-0/+3
When Git's source code calls isatty(), it really asks whether the respective file descriptor is connected to an interactive terminal. Windows' _isatty() function, however, determines whether the file descriptor is associated with a character device. And NUL, Windows' equivalent of /dev/null, is a character device. Which means that for years, Git mistakenly detected an associated interactive terminal when being run through the test suite, which almost always redirects stdin, stdout and stderr to /dev/null. This bug only became obvious, and painfully so, when the new bisect--helper entered the `pu` branch and made the automatic build & test time out because t6030 was waiting for an answer. For details, see https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-09-08Merge branch 'bw/mingw-avoid-inheriting-fd-to-lockfile' into maintLibravatar Junio C Hamano1-0/+4
The tempfile (hence its user lockfile) API lets the caller to open a file descriptor to a temporary file, write into it and then finalize it by first closing the filehandle and then either removing or renaming the temporary file. When the process spawns a subprocess after obtaining the file descriptor, and if the subprocess has not exited when the attempt to remove or rename is made, the last step fails on Windows, because the subprocess has the file descriptor still open. Open tempfile with O_CLOEXEC flag to avoid this (on Windows, this is mapped to O_NOINHERIT). * bw/mingw-avoid-inheriting-fd-to-lockfile: mingw: ensure temporary file handles are not inherited by child processes t6026-merge-attr: child processes must not inherit index.lock handles
2016-09-08Merge branch 'js/no-html-bypass-on-windows' into maintLibravatar Junio C Hamano1-3/+0
On Windows, help.browser configuration variable used to be ignored, which has been corrected. * js/no-html-bypass-on-windows: Revert "display HTML in default browser using Windows' shell API"
2016-09-08Merge branch 'jk/common-main' into maintLibravatar Junio C Hamano1-1/+1
There are certain house-keeping tasks that need to be performed at the very beginning of any Git program, and programs that are not built-in commands had to do them exactly the same way as "git" potty does. It was easy to make mistakes in one-off standalone programs (like test helpers). A common "main()" function that calls cmd_main() of individual program has been introduced to make it harder to make mistakes. * jk/common-main: mingw: declare main()'s argv as const common-main: call git_setup_gettext() common-main: call restore_sigpipe_to_default() common-main: call sanitize_stdfds() common-main: call git_extract_argv0_path() add an extra level of indirection to main()
2016-08-23mingw: ensure temporary file handles are not inherited by child processesLibravatar Ben Wijen1-0/+4
When the index is locked and child processes inherit the handle to said lock and the parent process wants to remove the lock before the child process exits, on Windows there is a problem: it won't work because files cannot be deleted if a process holds a handle on them. The symptom: Rename from 'xxx/.git/index.lock' to 'xxx/.git/index' failed. Should I try again? (y/n) Spawning child processes with bInheritHandles==FALSE would not work because no file handles would be inherited, not even the hStdXxx handles in STARTUPINFO (stdin/stdout/stderr). Opening every file with O_NOINHERIT does not work, either, as e.g. git-upload-pack expects inherited file handles. This leaves us with the only way out: creating temp files with the O_NOINHERIT flag. This flag is Windows-specific, however. For our purposes, it is equivalent to O_CLOEXEC (which does not exist on Windows), so let's just open temporary files with the O_CLOEXEC flag and map that flag to O_NOINHERIT on Windows. As Eric Wong pointed out, we need to be careful to handle the case where the Linux headers used to compile Git support O_CLOEXEC but the Linux kernel used to run Git does not: it returns an EINVAL. This fixes the test that we just introduced to demonstrate the problem. Signed-off-by: Ben Wijen <ben@wijen.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-08-19Revert "display HTML in default browser using Windows' shell API"Libravatar Johannes Schindelin1-3/+0
Since 4804aab (help (Windows): Display HTML in default browser using Windows' shell API, 2008-07-13), Git for Windows used to call `ShellExecute()` to launch the default Windows handler for `.html` files. The idea was to avoid going through a shell script, for performance reasons. However, this change ignores the `help.browser` config setting. Together with browsing help not being a performance-critical operation, let's just revert that patch. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-08-08Merge branch 'ew/daemon-socket-keepalive' into maintLibravatar Junio C Hamano1-0/+3
Recent update to "git daemon" tries to enable the socket-level KEEPALIVE, but when it is spawned via inetd, the standard input file descriptor may not necessarily be connected to a socket. Suppress an ENOTSOCK error from setsockopt(). * ew/daemon-socket-keepalive: Windows: add missing definition of ENOTSOCK daemon: ignore ENOTSOCK from setsockopt
2016-07-22Windows: add missing definition of ENOTSOCKLibravatar Johannes Sixt1-0/+3
The previous commit introduced the first use of ENOTSOCK. This macro is not available on Windows. Define it as WSAENOTSOCK because that is the corresponding error value reported by the Windows versions of socket functions. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-06mingw: declare main()'s argv as constLibravatar Johannes Schindelin1-1/+1
In 84d32bf (sparse: Fix mingw_main() argument number/type errors, 2013-04-27), we addressed problems identified by the 'sparse' tool where argv was declared inconsistently. The way we addressed it was by casting from the non-const version to the const-version. This patch is long overdue, fixing compat/mingw.h's declaration to make the "argv" parameter const. This also allows us to lose the "const" trickery introduced earlier to common-main.c:main(). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-06-20mingw: let the build succeed with DEVELOPER=1Libravatar Johannes Schindelin1-2/+2
The recently introduced developer flags identified a couple of old-style function declarations in the Windows-specific code where the parameter list was left empty instead of specifying "void" explicitly. Let's just fix them. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-05-26Merge branch 'js/windows-dotgit' into maintLibravatar Junio C Hamano1-3/+0
On Windows, .git and optionally any files whose name starts with a dot are now marked as hidden, with a core.hideDotFiles knob to customize this behaviour. * js/windows-dotgit: mingw: remove unnecessary definition mingw: introduce the 'core.hideDotFiles' setting
2016-05-18Merge branch 'jk/push-client-deadlock-fix' into HEADLibravatar Junio C Hamano1-0/+1
Some Windows SDK lacks pthread_sigmask() implementation and fails to compile the recently updated "git push" codepath that uses it. * jk/push-client-deadlock-fix: Windows: only add a no-op pthread_sigmask() when needed Windows: add pthread_sigmask() that does nothing t5504: drop sigpipe=ok from push tests fetch-pack: isolate sigpipe in demuxer thread send-pack: isolate sigpipe in demuxer thread run-command: teach async threads to ignore SIGPIPE send-pack: close demux pipe before finishing async process
2016-05-11mingw: remove unnecessary definitionLibravatar Johannes Schindelin1-3/+0
For some reason, the definition of the MINGW version of `mark_as_git_dir()` slipped into this developer's patch series to support building Git for Windows. As the `mark_as_git_dir()` function is not needed at all anymore (it was used originally to support the core.hideDotFiles = gitDirOnly setting, but we now use a different method to support that case), let's just remove it. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-05-02Windows: add pthread_sigmask() that does nothingLibravatar Johannes Sixt1-0/+1
A previous change introduced a call to pthread_sigmask() in order to block SIGPIPE in a thread. Since there are no signal facilities on Windows that are similar to POSIX signals, just ignore the request to block the signal. In the particular case, the effect of blocking SIGPIPE on POSIX is that write() calls return EPIPE when the reader closes the pipe. This is how write() behaves on Windows. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-03-30MSVC: use shipped headers instead of fallback definitionsLibravatar Sven Strickroth1-1/+1
VS2010 comes with stdint.h [1] VS2013 comes with inttypes.h [2] [1] https://stackoverflow.com/a/2628014/3906760 [2] https://blogs.msdn.microsoft.com/vcblog/2013/07/19/c99-library-support-in-visual-studio-2013/ Signed-off-by: Sven Strickroth <sven@cs-ware.de> Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Acked-by: Sebastian Schuberth <sschuberth@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-03-23config --show-origin: report paths with forward slashesLibravatar Johannes Schindelin1-0/+6
On Windows, the backslash is the native directory separator, but all supported Windows versions also accept the forward slash in most circumstances. Our tests expect forward slashes. Relative paths are generated by Git using forward slashes. So let's try to be consistent and use forward slashes in the $HOME part of the paths reported by `git config --show-origin`, too. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-05Merge branch 'js/dirname-basename' into maintLibravatar Junio C Hamano1-1/+4
dirname() emulation has been added, as Msys2 lacks it. * js/dirname-basename: mingw: avoid linking to the C library's isalpha() t0060: loosen overly strict expectations t0060: verify that basename() and dirname() work as expected compat/basename.c: provide a dirname() compatibility function compat/basename: make basename() conform to POSIX Refactor skipping DOS drive prefixes
2016-02-03Merge branch 'js/dirname-basename'Libravatar Junio C Hamano1-1/+4
dirname() emulation has been added, as Msys2 lacks it. * js/dirname-basename: mingw: avoid linking to the C library's isalpha() t0060: loosen overly strict expectations t0060: verify that basename() and dirname() work as expected compat/basename.c: provide a dirname() compatibility function compat/basename: make basename() conform to POSIX Refactor skipping DOS drive prefixes
2016-01-25mingw: avoid linking to the C library's isalpha()Libravatar Johannes Sixt1-6/+1
The implementation of mingw_skip_dos_drive_prefix() calls isalpha() via has_dos_drive_prefix(). Since the definition occurs long before isalpha() is defined in git-compat-util.h, my build environment reports: CC alloc.o In file included from git-compat-util.h:186, from cache.h:4, from alloc.c:12: compat/mingw.h: In function 'mingw_skip_dos_drive_prefix': compat/mingw.h:365: warning: implicit declaration of function 'isalpha' Dscho does not see a similar warning in his build and suspects that ctype.h is included somehow behind the scenes. This implies that his build links to the C library's isalpha() and does not use git's isalpha(). To fix both the warning in my build and the inconsistency in Dscho's build, move the function definition to mingw.c. Then it picks up git's isalpha() because git-compat-util.h is included at the top of the file. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-15mingw: avoid redefining S_* constantsLibravatar Johannes Schindelin1-0/+4
When compiling with MSys2's compiler, these constants are already defined. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-14compat/mingw: support MSys2-based MinGW buildLibravatar Johannes Schindelin1-1/+23
The excellent MSys2 project brings a substantially updated MinGW environment including newer GCC versions and new headers. To support compiling Git, let's special-case the new MinGW (tell-tale: the _MINGW64_VERSION_MAJOR constant is defined). Note: this commit only addresses compile failures, not compile warnings (that task is left for a future patch). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-12Refactor skipping DOS drive prefixesLibravatar Johannes Schindelin1-1/+9
Junio noticed that there is an implicit assumption in pretty much all the code calling has_dos_drive_prefix(): it forces all of its callsites to hardcode the knowledge that the DOS drive prefix is always two bytes long. While this assumption is pretty safe, we can still make the code more readable and less error-prone by introducing a function that skips the DOS drive prefix safely. While at it, we change the has_dos_drive_prefix() return value: it now returns the number of bytes to be skipped if there is a DOS drive prefix. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-12-21mingw: emulate write(2) that fails with a EPIPELibravatar Johannes Schindelin1-0/+3
On Windows, when writing to a pipe fails, errno is always EINVAL. However, Git expects it to be EPIPE. According to the documentation, there are two cases in which write() triggers EINVAL: the buffer is NULL, or the length is odd but the mode is 16-bit Unicode (the broken pipe is not mentioned as possible cause). Git never sets the file mode to anything but binary, therefore we know that errno should actually be EPIPE if it is EINVAL and the buffer is not NULL. See https://msdn.microsoft.com/en-us/library/1570wh78.aspx for more details. This works around t5571.11 failing with v2.6.4 on Windows. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Acked-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-26Merge branch 'nd/untracked-cache'Libravatar Junio C Hamano1-0/+9
Teach the index to optionally remember already seen untracked files to speed up "git status" in a working tree with tons of cruft. * nd/untracked-cache: (24 commits) git-status.txt: advertisement for untracked cache untracked cache: guard and disable on system changes mingw32: add uname() t7063: tests for untracked cache update-index: test the system before enabling untracked cache update-index: manually enable or disable untracked cache status: enable untracked cache untracked-cache: temporarily disable with $GIT_DISABLE_UNTRACKED_CACHE untracked cache: mark index dirty if untracked cache is updated untracked cache: print stats with $GIT_TRACE_UNTRACKED_STATS untracked cache: avoid racy timestamps read-cache.c: split racy stat test to a separate function untracked cache: invalidate at index addition or removal untracked cache: load from UNTR index extension untracked cache: save to an index extension ewah: add convenient wrapper ewah_serialize_strbuf() untracked cache: don't open non-existent .gitignore untracked cache: mark what dirs should be recursed/saved untracked cache: record/validate dir mtime and reuse cached output untracked cache: make a wrapper around {open,read,close}dir() ...
2015-04-15compat/mingw: stubs for getpgid() and tcgetpgrp()Libravatar Johannes Sixt1-2/+6
Windows does not have process groups. It is, therefore, the simplest to pretend that each process is in its own process group. While here, move the getppid() stub from its old location (between two sync related functions) next to the two new functions. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-12mingw32: add uname()Libravatar Nguyễn Thái Ngọc Duy1-0/+9
Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-09-22mingw.h: add dummy functions for sigset_t operationsLibravatar Johannes Sixt1-1/+6
Windows does not have POSIX-like signals, and so we ignore all operations on the non-existent signal mask machinery. Do not turn sigemptyset into a function, but leave it a macro that erases the code in the argument because it is used to set sa_mask of a struct sigaction, but our dummy in mingw.h does not have that member. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-30Merge branch 'sk/mingw-uni-fix-more'Libravatar Junio C Hamano1-6/+5
Most of these are battle-tested in msysgit and are needed to complete what has been merged to 'master' already. * sk/mingw-uni-fix-more: Win32: enable color output in Windows cmd.exe Win32: patch Windows environment on startup Win32: keep the environment sorted Win32: use low-level memory allocation during initialization Win32: reduce environment array reallocations Win32: don't copy the environment twice when spawning child processes Win32: factor out environment block creation Win32: unify environment function names Win32: unify environment case-sensitivity Win32: fix environment memory leaks Win32: Unicode environment (incoming) Win32: Unicode environment (outgoing) Revert "Windows: teach getenv to do a case-sensitive search" tests: do not pass iso8859-1 encoded parameter
2014-07-21Merge branch 'sk/mingw-uni-fix'Libravatar Junio C Hamano1-4/+14
* sk/mingw-uni-fix: Win32: Unicode file name support (dirent) Win32: Unicode file name support (except dirent)
2014-07-21Win32: don't copy the environment twice when spawning child processesLibravatar Karsten Blees1-6/+2
When spawning child processes via start_command(), the environment and all environment entries are copied twice. First by make_augmented_environ / copy_environ to merge with child_process.env. Then a second time by make_environment_block to create a sorted environment block string as required by CreateProcess. Move the merge logic to make_environment_block so that we only need to copy the environment once. This changes semantics of the env parameter: it now expects a delta (such as child_process.env) rather than a full environment. This is not a problem as the parameter is only used by start_command() (all other callers previously passed char **environ, and now pass NULL). The merge logic no longer xstrdup()s the environment strings, so do_putenv must not free them. Add a parameter to distinguish this from normal putenv. Remove the now unused make_augmented_environ / free_environ API. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-21Win32: fix environment memory leaksLibravatar Karsten Blees1-0/+1
All functions that modify the environment have memory leaks. Disable gitunsetenv in the Makefile and use env_setenv (via mingw_putenv) instead (this frees removed environment entries). Move xstrdup from env_setenv to make_augmented_environ, so that mingw_putenv no longer copies the environment entries (according to POSIX [1], "the string [...] shall become part of the environment"). This also fixes the memory leak in gitsetenv, which expects a POSIX compliant putenv. [1] http://pubs.opengroup.org/onlinepubs/009695399/functions/putenv.html Note: This patch depends on taking control of char **environ and having our own mingw_putenv (both introduced in "Win32: Unicode environment (incoming)"). Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-21Win32: Unicode environment (incoming)Libravatar Karsten Blees1-0/+2
Convert environment from UTF-16 to UTF-8 on startup. No changes to getenv() are necessary, as the MSVCRT version is implemented on top of char **environ. However, putenv / _wputenv from MSVCRT no longer work, for two reasons: 1. they try to keep environ, _wenviron and the Win32 process environment in sync, using the default system encoding instead of UTF-8 to convert between charsets 2. msysgit and MSVCRT use different allocators, memory allocated in git cannot be freed by the CRT and vice versa Implement mingw_putenv using the env_setenv helper function from the environment merge code. Note that in case of memory allocation failure, putenv now dies with error message (due to xrealloc) instead of failing with ENOMEM. As git assumes setenv / putenv to always succeed, this prevents it from continuing with incorrect settings. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-16MinGW: fix compile error due to missing ELOOPLibravatar Karsten Blees1-0/+3
MinGW and MSVC before 2010 don't define ELOOP, use EMLINK (aka "Too many links") instead. Signed-off-by: Karsten Blees <blees@dcon.de> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-15Win32: Unicode file name support (except dirent)Libravatar Karsten Blees1-4/+14
Replaces Windows "ANSI" APIs dealing with file- or path names with their Unicode equivalent, adding UTF-8/UTF-16LE conversion as necessary. The dirent API (opendir/readdir/closedir) is updated in a separate commit. Adds trivial wrappers for access, chmod and chdir. Adds wrapper for mktemp (needed for both mkstemp and mkdtemp). The simplest way to convert a repository with legacy-encoded (e.g. Cp1252) file names to UTF-8 ist to checkout with an old msysgit version and "git add --all & git commit" with the new version. Includes a fix for bug reported by John Chen: On Windows XP (not Win7), directories cannot be deleted while a find handle is open, causing "Deletion of directory '...' failed. Should I try again?" prompts. Prior to this commit, these failures were silently ignored due to strbuf_free in is_dir_empty resetting GetLastError to ERROR_SUCCESS. Close the find handle in is_dir_empty so that git doesn't block deletion of the directory even after all other applications have released it. Reported-by: John Chen <john0312@gmail.com> Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10Win32: fix broken pipe detectionLibravatar Karsten Blees1-2/+0
As of "Win32: Thread-safe windows console output", git-log no longer terminates when the pager process dies. This is due to disabling buffering for the replaced stdout / stderr streams. Git-log will periodically fflush stdout (see write_or_die.c/mayble_flush_or_die()), but with no buffering, this is a NOP that always succeeds (so we never detect the EPIPE error). Exchange the original console handles with our console thread pipe handles by accessing the internal MSVCRT data structures directly (which are exposed via __pioinfo for some reason). Implement this with minimal assumptions about the actual data structure to make it work with different (hopefully even future) MSVCRT versions. While messing with internal data structures is ugly, this patch solves the problem at the source instead of adding more workarounds. We no longer need the special winansi_isatty override, and the limitations documented in "Win32: Thread-safe windows console output" are gone (i.e. fdopen(1/2) returns unbuffered streams now, and isatty() for duped console file descriptors works as expected). Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10Win32: Thread-safe windows console outputLibravatar Karsten Blees1-8/+4
Winansi.c has many static variables that are accessed and modified from the [v][f]printf / fputs functions overridden in the file. This may cause multi threaded git commands that print to the console to produce corrupted output or even crash. Additionally, winansi.c doesn't override all functions that can be used to print to the console (e.g. fwrite, write, fputc are missing), so that ANSI escapes don't work properly for some git commands (e.g. git-grep). Instead of doing ANSI emulation in just a few wrapped functions on top of the IO API, let's plug into the IO system and take advantage of the thread safety inherent to the IO system. Redirect stdout and stderr to a pipe if they point to the console. A background thread reads from the pipe, handles ANSI escape sequences and UTF-8 to UTF-16 conversion, then writes to the console. The pipe-based stdout and stderr replacements must be set to unbuffered, as MSVCRT doesn't support line buffering and fully buffered streams are inappropriate for console output. Due to the byte-oriented pipe, ANSI escape sequences and multi-byte UTF-8 sequences can no longer be expected to arrive in one piece. Replace the string-based ansi_emulate() with a simple stateful parser (this also fixes colored diff hunk headers, which were broken as of commit 2efcc977). Override isatty to return true for the pipes redirecting to the console. Exec/spawn obtain the original console handle to pass to the next process via winansi_get_osfhandle(). All other overrides are gone, the default stdio implementations work as expected with the piped stdout/stderr descriptors. Global variables are either initialized on startup (single threaded) or exclusively modified by the background thread. Threads communicate through the pipe, no further synchronization is necessary. The background thread is terminated by disonnecting the pipe after flushing the stdio and pipe buffers. This doesn't work for anonymous pipes (created via CreatePipe), as DisconnectNamedPipe only works on the read end, which discards remaining data. Thus we have to setup the pipe manually, with the write end beeing the server (opened with CreateNamedPipe) and the read end the client (opened with CreateFile). Limitations: doesn't track reopened or duped file descriptors, i.e.: - fdopen(1/2) returns fully buffered streams - dup(1/2), dup2(1/2) returns normal pipe descriptors (i.e. isatty() = false, winansi_get_osfhandle won't return the original console handle) Currently, only the git-format-patch command uses xfdopen(xdup(1)) (see "realstdout" in builtin/log.c), but works well with these limitations. Many thanks to Atsushi Nakagawa <atnak@chejz.com> for suggesting and reviewing the thread-exit-mechanism. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10Win32: add Unicode conversion functionsLibravatar Karsten Blees1-0/+104
Add Unicode conversion functions to convert between Windows native UTF-16LE encoding to UTF-8 and back. To support repositories with legacy-encoded file names, the UTF-8 to UTF-16 conversion function tries to create valid, unique file names even for invalid UTF-8 byte sequences, so that these repositories can be checked out without error. The current implementation leaves invalid UTF-8 bytes in range 0xa0 - 0xff as is (producing printable Unicode chars \u00a0 - \u00ff, equivalent to ISO-8859-1), and converts 0x80 - 0x9f to hex-code (\u0080 - \u009f are control chars). The Windows MultiByteToWideChar API was not used as it either drops invalid UTF-8 sequences (on Win2k/XP; producing non-unique or even empty file names) or converts them to the replacement char \ufffd (Vista/7; causing ERROR_INVALID_NAME in subsequent calls to file system APIs). Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10Win32: support Unicode console outputLibravatar Karsten Blees1-0/+2
WriteConsoleW seems to be the only way to reliably print unicode to the console (without weird code page conversions). Also redirects vfprintf to the winansi.c version. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10mingw: avoid const warningLibravatar Stepan Kasal1-1/+1
Fix const warnings in http-fetch.c and remote-curl.c main() where is argv declared as const. The fix should work for all future declarations of main, no matter whether the second parameter's type is "char**", "const char**", or "char *[]". Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10Win32: move main macro to a functionLibravatar Karsten Blees1-10/+4
The code in the MinGW main macro is getting more and more complex, move to a separate initialization function for readabiliy and extensibility. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10Windows: allow using UNC path for git repositoryLibravatar Cezary Zawadka1-0/+2
[efl: moved MinGW-specific part to compat/] [jes: fixed compilation on non-Windows] Eric Sunshine fixed mingw_offset_1st_component() to return consistently "foo" for UNC "//machine/share/foo", cf http://groups.google.com/group/msysgit/browse_thread/thread/c0af578549b5dda0 Author: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Cezary Zawadka <czawadka@gmail.com> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-17mingw: remove mingw_writeLibravatar Erik Faye-Lund1-3/+0
Since 0b6806b9 ("xread, xwrite: limit size of IO to 8MB"), this wrapper is no longer needed, as read and write are already split into small chunks. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-09-24Merge branch 'kb/msvc-compile'Libravatar Jonathan Nieder1-4/+26
* kb/msvc-compile: Windows: do not redefine _WIN32_WINNT MinGW: Fix stat definitions to work with MinGW runtime version 4.0 MSVC: fix stat definition hell MSVC: fix compile errors due to macro redefinitions MSVC: fix compile errors due to missing libintl.h