summaryrefslogtreecommitdiff
path: root/compat/mingw.c
AgeCommit message (Collapse)AuthorFilesLines
2018-03-19mingw: abort on invalid strftime formatsLibravatar Johannes Schindelin1-0/+11
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-11-02mingw: optionally redirect stderr/stdout via the same handleLibravatar Johannes Schindelin1-0/+15
The "2>&1" notation in Powershell and in Unix shells implies that stderr is redirected to the same handle into which stdout is already written. Let's use this special value to allow the same trick with GIT_REDIRECT_STDERR and GIT_REDIRECT_STDOUT: if the former's value is `2>&1`, then stderr will simply be written to the same handle as stdout. The functionality was suggested by Jeff Hostetler. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-11-02mingw: add experimental feature to redirect standard handlesLibravatar Johannes Schindelin1-0/+43
Particularly when calling Git from applications, such as Visual Studio's Team Explorer, it is important that stdin/stdout/stderr are closed properly. However, when spawning processes on Windows, those handles must be marked as inheritable if we want to use them, but that flag is a global flag and may very well be used by other spawned processes which then do not know to close those handles. Let's introduce a set of environment variables (GIT_REDIRECT_STDIN and friends) that specify paths to files, or even better, named pipes (which are similar to Unix sockets) and that are used by the spawned Git process. This helps work around above-mentioned issue: those named pipes will be opened in a non-inheritable way upon startup, and no handles are passed around (and therefore no inherited handles need to be closed by any spawned child). This feature shipped with Git for Windows (marked as experimental) since v2.11.0(2), so it has seen some serious testing in the meantime. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-13Merge branch 'nd/fopen-errors'Libravatar Junio C Hamano1-0/+2
We often try to open a file for reading whose existence is optional, and silently ignore errors from open/fopen; report such errors if they are not due to missing files. * nd/fopen-errors: mingw_fopen: report ENOENT for invalid file names mingw: verify that paths are not mistaken for remote nicknames log: fix memory leak in open_next_file() rerere.c: move error_errno() closer to the source system call print errno when reporting a system call error wrapper.c: make warn_on_inaccessible() static wrapper.c: add and use fopen_or_warn() wrapper.c: add and use warn_on_fopen_errors() config.mak.uname: set FREAD_READS_DIRECTORIES for Darwin, too config.mak.uname: set FREAD_READS_DIRECTORIES for Linux and FreeBSD clone: use xfopen() instead of fopen() use xfopen() in more places git_fopen: fix a sparse 'not declared' warning
2017-06-02mingw_fopen: report ENOENT for invalid file namesLibravatar Johannes Sixt1-0/+2
On Windows, certain characters are prohibited in file names, most prominently the colon. When fopen() is called with such an invalid file name, the underlying Windows API actually reports a particular error, but since there is no suitable errno value, this error is translated to EINVAL. Detect the case and report ENOENT instead. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-05-23mingw: simplify PATH handlingLibravatar René Scharfe1-68/+23
On Windows the environment variable PATH contains a semicolon-separated list of directories to search for, in order, when looking for the location of a binary to run. get_path_split() parses it and returns an array of string copies, which is iterated by path_lookup(), which in turn passes each entry to lookup_prog(). Change lookup_prog() to take the directory name as a length-limited string instead of as a NUL-terminated one and parse PATH directly in path_lookup(). This avoids memory allocations, simplifying the code. Helped-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Rene Scharfe <l.s.r@web.de> Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-08-25Merge branch 'js/no-html-bypass-on-windows'Libravatar Junio C Hamano1-42/+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-08-19Revert "display HTML in default browser using Windows' shell API"Libravatar Johannes Schindelin1-42/+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-06-20mingw: let the build succeed with DEVELOPER=1Libravatar Johannes Schindelin1-3/+3
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-0/+74
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-11mingw: introduce the 'core.hideDotFiles' settingLibravatar Johannes Schindelin1-0/+74
On Unix (and Linux), files and directories whose names start with a dot are usually not shown by default. This convention is used by Git: the .git/ directory should be left alone by regular users, and only accessed through Git itself. On Windows, no such convention exists. Instead, there is an explicit flag to mark files or directories as hidden. In the early days, Git for Windows did not mark the .git/ directory (or for that matter, any file or directory whose name starts with a dot) hidden. This lead to quite a bit of confusion, and even loss of data. Consequently, Git for Windows introduced the core.hideDotFiles setting, with three possible values: true, false, and dotGitOnly, defaulting to marking only the .git/ directory as hidden. The rationale: users do not need to access .git/ directly, and indeed (as was demonstrated) should not really see that directory, either. However, not all dot files should be hidden by default, as e.g. Eclipse does not show them (and the user would therefore be unable to see, say, a .gitattributes file). In over five years since the last attempt to bring this patch into core Git, a slightly buggy version of this patch has served Git for Windows' users well: no single report indicated problems with the hidden .git/ directory, and the stream of problems caused by the previously non-hidden .git/ directory simply stopped. The bugs have been fixed during the process of getting this patch upstream. Note that there is a funny quirk we have to pay attention to when creating hidden files: we use Win32's _wopen() function which transmogrifies its arguments and hands off to Win32's CreateFile() function. That latter function errors out with ERROR_ACCESS_DENIED (the equivalent of EACCES) when the equivalent of the O_CREAT flag was passed and the file attributes (including the hidden flag) do not match an existing file's. And _wopen() accepts no parameter that would be transmogrified into said hidden flag. Therefore, we simply try again without O_CREAT. A slightly different method is required for our fopen()/freopen() function as we cannot even *remove* the implicit O_CREAT flag. Therefore, we briefly mark existing files as unhidden when opening them via fopen()/freopen(). The ERROR_ACCESS_DENIED error can also be triggered by opening a file that is marked as a system file (which is unlikely to be tracked in Git), and by trying to create a file that has *just* been deleted and is awaiting the last open handles to be released (which would be handled better by the "Try again?" logic, a story for a different patch series, though). In both cases, it does not matter much if we try again without the O_CREAT flag, read: it does not hurt, either. For details how ERROR_ACCESS_DENIED can be triggered, see https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858 Original-patch-by: Erik Faye-Lund <kusmabite@gmail.com> Initial-Test-By: Pat Thoyts <patthoyts@users.sourceforge.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-04Windows: shorten code by re-using convert_slashes()Libravatar Johannes Sixt1-7/+2
Make a few more spots more readable by using the recently introduced, Windows-specific helper. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-03-04Merge branch 'jk/tighten-alloc'Libravatar Junio C Hamano1-1/+1
* jk/tighten-alloc: compat/mingw: brown paper bag fix for 50a6c8e
2016-02-29compat/mingw: brown paper bag fix for 50a6c8eLibravatar Jeff King1-1/+1
Commit 50a6c8e (use st_add and st_mult for allocation size computation, 2016-02-22) fixed up many xmalloc call-sites including ones in compat/mingw.c. But I screwed up one of them, which was half-converted to ALLOC_ARRAY, using a very early prototype of the function. And I never caught it because I don't build on Windows. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-26Merge branch 'jk/tighten-alloc'Libravatar Junio C Hamano1-5/+5
Update various codepaths to avoid manually-counted malloc(). * jk/tighten-alloc: (22 commits) ewah: convert to REALLOC_ARRAY, etc convert ewah/bitmap code to use xmalloc diff_populate_gitlink: use a strbuf transport_anonymize_url: use xstrfmt git-compat-util: drop mempcpy compat code sequencer: simplify memory allocation of get_message test-path-utils: fix normalize_path_copy output buffer size fetch-pack: simplify add_sought_entry fast-import: simplify allocation in start_packfile write_untracked_extension: use FLEX_ALLOC helper prepare_{git,shell}_cmd: use argv_array use st_add and st_mult for allocation size computation convert trivial cases to FLEX_ARRAY macros use xmallocz to avoid size arithmetic convert trivial cases to ALLOC_ARRAY convert manual allocations to argv_array argv-array: add detach function add helpers for allocating flex-array structs harden REALLOC_ARRAY and xcalloc against size_t overflow tree-diff: catch integer overflow in combine_diff_path allocation ...
2016-02-22use st_add and st_mult for allocation size computationLibravatar Jeff King1-2/+2
If our size computation overflows size_t, we may allocate a much smaller buffer than we expected and overflow it. It's probably impossible to trigger an overflow in most of these sites in practice, but it is easy enough convert their additions and multiplications into overflow-checking variants. This may be fixing real bugs, and it makes auditing the code easier. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-22convert trivial cases to ALLOC_ARRAYLibravatar Jeff King1-3/+3
Each of these cases can be converted to use ALLOC_ARRAY or REALLOC_ARRAY, which has two advantages: 1. It automatically checks the array-size multiplication for overflow. 2. It always uses sizeof(*array) for the element-size, so that it can never go out of sync with the declared type of the array. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-02-17Merge branch 'js/mingw-tests'Libravatar Junio C Hamano1-14/+77
Test scripts have been updated to remove assumptions that are not portable between Git for POSIX and Git for Windows, or to skip ones with expectations that are not satisfiable on Git for Windows. * js/mingw-tests: (21 commits) gitignore: ignore generated test-fake-ssh executable mingw: do not bother to test funny file names mingw: skip a test in t9130 that cannot pass on Windows mingw: handle the missing POSIXPERM prereq in t9124 mingw: avoid illegal filename in t9118 mingw: mark t9100's test cases with appropriate prereqs t0008: avoid absolute path mingw: work around pwd issues in the tests mingw: fix t9700's assumption about directory separators mingw: skip test in t1508 that fails due to path conversion tests: turn off git-daemon tests if FIFOs are not available mingw: disable mkfifo-based tests mingw: accomodate t0060-path-utils for MSYS2 mingw: fix t5601-clone.sh mingw: let lstat() fail with errno == ENOTDIR when appropriate mingw: try to delete target directory before renaming mingw: prepare the TMPDIR environment variable for shell scripts mingw: factor out Windows specific environment setup Git.pm: stop assuming that absolute paths start with a slash mingw: do not trust MSYS2's MinGW gettext.sh ...
2016-02-05Merge branch 'js/dirname-basename' into maintLibravatar Junio C Hamano1-9/+12
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-9/+12
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-26mingw: let lstat() fail with errno == ENOTDIR when appropriateLibravatar Johannes Schindelin1-0/+39
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 <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-26mingw: try to delete target directory before renamingLibravatar 마누엘1-1/+6
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: 마누엘 <nalla@hamal.uberspace.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-26mingw: prepare the TMPDIR environment variable for shell scriptsLibravatar Johannes Schindelin1-4/+19
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 <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-26mingw: factor out Windows specific environment setupLibravatar Karsten Blees1-13/+17
We will add more environment-related code to that new function in the next patch. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-01-25mingw: avoid linking to the C library's isalpha()Libravatar Johannes Sixt1-0/+7
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 warnings when casting HANDLEs to intLibravatar Johannes Schindelin1-3/+6
HANDLE is defined internally as a void *, but in many cases it is actually guaranteed to be a 32-bit integer. In these cases, GCC should not warn about a cast of a pointer to an integer of a different type because we know exactly what we are doing. 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-9/+5
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-22Merge branch 'js/emu-write-epipe-on-windows'Libravatar Junio C Hamano1-0/+17
The write(2) emulation for Windows learned to set errno to EPIPE when necessary. * js/emu-write-epipe-on-windows: mingw: emulate write(2) that fails with a EPIPE
2015-12-21mingw: emulate write(2) that fails with a EPIPELibravatar Johannes Schindelin1-0/+17
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-10-23compat/mingw.c: remove printf format warningLibravatar Johannes Sixt1-1/+1
5096d490 (convert trivial sprintf / strcpy calls to xsnprintf) converted two sprintf calls. Now GCC warns that "format '%u' expects argument of type 'unsigned int', but argument 4 has type 'long unsigned int'". Instead of changing the format string, use a variable of type unsigned in place of the typedef-ed type DWORD, which hides that it is actually an unsigned long. There is no correctness issue with the old code because unsigned long and unsigned are always of the same size on Windows, even in 64-bit builds. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-25convert trivial sprintf / strcpy calls to xsnprintfLibravatar Jeff King1-3/+5
We sometimes sprintf into fixed-size buffers when we know that the buffer is large enough to fit the input (either because it's a constant, or because it's numeric input that is bounded in size). Likewise with strcpy of constant strings. However, these sites make it hard to audit sprintf and strcpy calls for buffer overflows, as a reader has to cross-reference the size of the array with the input. Let's use xsnprintf instead, which communicates to a reader that we don't expect this to overflow (and catches the mistake in case we do). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-28Mingw: verify both ends of the pipe () callLibravatar Jose F. Morales1-1/+1
The code to open and test the second end of the pipe clearly imitates the code for the first end. A little too closely, though... Let's fix the obvious copy-edit bug. Signed-off-by: Jose F. Morales <jfmcjf@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Acked-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/+11
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-11-17Windows: correct detection of EISDIR in mingw_open()Libravatar Johannes Sixt1-1/+1
According to the Linux open(2) man page, open() must return EISDIR if a directory was attempted to be opened for writing. Our emulation in mingw_open() does not get this right: it checks only for O_CREAT. Fix it to check for a write request. This fixes a failure in reflog handling, which opens files with O_APPEND|O_WRONLY, but without O_CREAT, and expects EISDIR when the named file happens to be a directory. 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-127/+164
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 'maint'Libravatar Junio C Hamano1-2/+1
* maint: use xmemdupz() to allocate copies of strings given by start and length use xcalloc() to allocate zero-initialized memory
2014-07-21use xcalloc() to allocate zero-initialized memoryLibravatar René Scharfe1-2/+1
Use xcalloc() instead of xmalloc() followed by memset() to allocate and zero out memory because it's shorter and avoids duplicating the function parameters. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-21Win32: enable color output in Windows cmd.exeLibravatar Karsten Blees1-0/+4
Git requires the TERM environment variable to be set for all color* settings. Simulate the TERM variable if it is not set (default on Windows). 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-07-21Win32: patch Windows environment on startupLibravatar Karsten Blees1-13/+12
Fix Windows specific environment settings on startup rather than checking for special values on every getenv call. As a side effect, this makes the patched environment (i.e. with properly initialized TMPDIR and TERM) available to child processes. 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: keep the environment sortedLibravatar Karsten Blees1-39/+65
The Windows environment is sorted, keep it that way for O(log n) environment access. Change compareenv to compare only the keys, so that it can be used to find an entry irrespective of the value. Change lookupenv to binary seach for an entry. Return one's complement of the insert position if not found (libc's bsearch returns NULL). Replace MSVCRT's getenv with a minimal do_getenv based on the binary search function. Change do_putenv to insert new entries at the correct position. Simplify the function by swapping if conditions and using memmove instead of for loops. Move qsort from make_environment_block to mingw_startup. We still need to sort on startup to make sure that the environment is sorted according to our compareenv function (while Win32 / CreateProcess requires the environment block to be sorted case-insensitively, CreateProcess currently doesn't enforce this, and some applications such as bash just don't care). Note that environment functions are _not_ thread-safe and are not required to be so by POSIX, the application is responsible for synchronizing access to the environment. MSVCRT's getenv and our new getenv implementation are better than that in that they are thread-safe with respect to other getenv calls as long as the environment is not modified. Git's indiscriminate use of getenv in background threads currently requires this property. 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: use low-level memory allocation during initializationLibravatar Karsten Blees1-15/+28
As of d41489a6 "Add more large blob test cases", git's high-level memory allocation functions (xmalloc, xmemdupz etc.) access the environment to simulate limited memory in tests (see 'getenv("GIT_ALLOC_LIMIT")' in memory_limit_check()). These functions should not be used before the environment is fully initialized (particularly not to initialize the environment itself). The current solution ('environ = NULL; ALLOC_GROW(environ...)') only works because MSVCRT's getenv() reinitializes environ when it is NULL (i.e. it leaves us with two sets of unusabe (non-UTF-8) and unfreeable (CRT- allocated) environments). Add our own set of malloc-or-die functions to be used in startup code. Also check the result of __wgetmainargs, which may fail if there's not enough memory for wide-char arguments and environment. This patch is in preparation of the sorted environment feature, which completely replaces MSVCRT's getenv() implementation. 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: reduce environment array reallocationsLibravatar Karsten Blees1-27/+35
Move environment array reallocation from do_putenv to the respective callers. Keep track of the environment size in a global variable. Use ALLOC_GROW in mingw_putenv to reduce reallocations. Allocate a sufficiently sized environment array in make_environment_block to prevent reallocations. 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: don't copy the environment twice when spawning child processesLibravatar Karsten Blees1-50/+26
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: factor out environment block creationLibravatar Karsten Blees1-23/+32
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: unify environment function namesLibravatar Karsten Blees1-7/+7
Environment helper functions use random naming ('env' prefix or suffix or both, with or without '_'). Change to POSIX naming scheme ('env' suffix, no '_'). Env_setenv has more in common with putenv than setenv. Change to do_putenv. 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: unify environment case-sensitivityLibravatar Karsten Blees1-2/+1
The environment on Windows is case-insensitive. Some environment functions (such as unsetenv and make_augmented_environ) have always used case- sensitive comparisons instead, while others (getenv, putenv, sorting in spawn*) were case-insensitive. Prevent potential inconsistencies by using case-insensitive comparison in lookup_env (used by putenv, unsetenv and make_augmented_environ). 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-4/+6
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/+15
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-21Win32: Unicode environment (outgoing)Libravatar Karsten Blees1-11/+14
Convert environment from UTF-8 to UTF-16 when creating other processes. 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-17Revert "Windows: teach getenv to do a case-sensitive search"Libravatar Karsten Blees1-20/+3
This reverts commit df599e9612788b728ce43a03159b85f1fe624d6a. As of 5e9637c6 "i18n: add infrastructure for translating Git with gettext", eval_gettext uses MinGW envsubst.exe instead of git-sh-i18n--envsubst.exe for variable substitution. This breaks git-submodule.sh messages and tests, as envsubst.exe doesn't support case-sensitive environment lookup (the same is true for almost everything on Windows, including MSys and Cygwin tools). 30a615ac "Windows/i18n: rename $path to prevent clashes with $PATH" renames the conflicting variable in git-submodule.sh, so that it works on Windows (i.e. with case-insensitive environment, regardless of the toolset). Revert to the documented behaviour of case-insensitive environment on Windows. 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>