Since baaf233 (connect: improve check for plink to reduce false
positives, 2015-04-26), t5601 writes out a `plink.exe` for testing that
is actually a shell script. So the assumption that the `.exe` extension
implies that the file is *not* a shell script is now wrong.
The original idea to special-case `.exe` files was probably to
help performance, but since we are in a code path that involves spawning
a new process (which in and of itself is pretty slow on Windows anyway),
we pursue a better idea to improve performance elsewhere: we try to
convert scripts into builtins and to reduce the number of spawned
processes by adding more internal API calls.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Accessing the Windows console through the special CONIN$ / CONOUT$ devices
doesn't work properly for non-ASCII usernames an passwords.
It also doesn't work for terminal emulators that hide the native console
window (such as mintty), and 'TERM=xterm*' is not necessarily a reliable
indicator for such terminals.
The new shell_prompt() function, on the other hand, works fine for both
MSys1 and MSys2, in native console windows as well as mintty, and properly
supports Unicode. It just needs bash on the path (for 'read -s', which is
bash-specific).
On Windows, try to use the shell to read from the terminal. If that fails
with ENOENT (i.e. bash was not found), use CONIN/OUT as fallback.
Note: To test this, create a UTF-8 credential file with non-ASCII chars,
e.g. in git-bash: 'echo url=http://täst.com > cred.txt'. Then in git-cmd,
'git credential fill <cred.txt' works (shell version), while calling git
without the git-wrapper (i.e. 'mingw64\bin\git credential fill <cred.txt')
mangles non-ASCII chars in both console output and input.
Signed-off-by: Karsten Blees <blees@dcon.de>
The `git_terminal_prompt()` function expects the terminal window to be
attached to a Win32 Console. However, this is not the case with terminal
windows other than `cmd.exe`'s, e.g. with MSys2's own `mintty`.
Non-cmd terminals such as `mintty` still have to have a Win32 Console
to be proper console programs, but have to hide the Win32 Console to
be able to provide more flexibility (such as being resizeable not only
vertically but also horizontally). By writing to that Win32 Console,
`git_terminal_prompt()` manages only to send the prompt to nowhere and
to wait for input from a Console to which the user has no access.
This commit introduces a function specifically to support `mintty` -- or
other terminals that are compatible with MSys2's `/dev/tty` emulation. We
use the `TERM` environment variable as an indicator for that: if the value
starts with "xterm" (such as `mintty`'s "xterm_256color"), we prefer to
let `xterm_prompt()` handle the user interaction.
The most prominent user of `git_terminal_prompt()` is certainly
`git-remote-https.exe`. It is an interesting use case because both
`stdin` and `stdout` are redirected when Git calls said executable, yet
it still wants to access the terminal.
When running inside a `mintty`, the terminal is not accessible to the
`git-remote-https.exe` program, though, because it is a MinGW program
and the `mintty` terminal is not backed by a Win32 console.
To solve that problem, we simply call out to the shell -- which is an
*MSys2* program and can therefore access `/dev/tty`.
Helped-by: nalla <nalla@hamal.uberspace.de>
Signed-off-by: Karsten Blees <blees@dcon.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
For performance reasons `stdout` is not unbuffered by default. That leads
to problems if after printing to `stdout` a read on `stdin` is performed.
For that reason interactive commands like `git clean -i` do not function
properly anymore if the `stdout` is not flushed by `fflush(stdout)` before
trying to read from `stdin`.
In the case of `git clean -i` all reads on `stdin` were preceded by a
`fflush(stdout)` call.
Signed-off-by: nalla <nalla@hamal.uberspace.de>
HOME initialization was historically duplicated in many different places,
including /etc/profile, launch scripts such as git-bash.vbs and gitk.cmd,
and (although slightly broken) in the git-wrapper.
Even unrelated projects such as GitExtensions and TortoiseGit need to
implement the same logic to be able to call git directly.
Initialize HOME in git's own startup code so that we can eventually retire
all the duplicate initialization code.
Signed-off-by: Karsten Blees <blees@dcon.de>
Lets keep the environment initialization and conversion section as lean as
possible and move recently added tweaks to setup_windows_environment().
This fixes the following potential problems:
* Prevent duplicate TZ variables if both TZ and MSYS2_TZ are set.
* Some of the higher level x* APIs from wrapper.c require a working
getenv(), using e.g. xstrdup() during initialization is dangerous.
* Slashifying the Windows TMP variable may break native Windows programs,
use POSIX TMPDIR instead.
* Properly slashify TMPDIR even if it is already set, and also if we only
have TEMP, but not TMP.
* Reduce complexity from O(n) to O(log n).
Signed-off-by: Karsten Blees <blees@dcon.de>
This developer should really, really have known better. The fact that we
are changing the environment in ways for which the MSVCRT is not
prepared for is bad enough. But then this developer followed the request
to re-enable nedmalloc -- despite the prediction that it would cause an
access violation, predicting it in the same message as the request to
re-enable nedmalloc, no less!
To paper over the issue until the time when this developer finds the
time to re-design the Unicode environment handling from scratch, let's
hope that cURL is the only library we are using that *may* set an
environment variable using MSVCRT's putenv() after we fscked the
environment up.
Note: this commit can serve as no source of pride to anyone, certainly
not yours truly. It is necessary as a quick and pragmatic stop gap,
though, to prevent worse problems.
Note: cURL manages to set the variable CHARSET when nedmalloc is *not*
enabled, without causing an access violation. In that case, it sets it
successfully to the value "cp" + GetACP() (hence it is our choice, too,
cURL may need it, Git does not):
https://github.com/bagder/curl/blob/aa5808b5/lib/easy.c#L157-L162
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git on native Windows exclusively uses UTF-8 for console output (both with
mintty and native console windows). Gettext uses setlocale() to determine
the output encoding for translated text, however, MSVCRT's setlocale()
doesn't support UTF-8. As a result, translated text is encoded in system
encoding (GetAPC()), and non-ASCII chars are mangled in console output.
Use gettext's bind_textdomain_codeset() to force the encoding to UTF-8 on
native Windows.
In this developers' setup, HAVE_LIBCHARSET_H is apparently defined, but
we *really* want to override the locale_charset() here.
Signed-off-by: Karsten Blees <blees@dcon.de>
A '+' is not a valid part of a filename with Windows file systems (it is
reserved because the '+' operator meant file concatenation back in the
DOS days).
Let's just not use it.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When Git for Windows was still based on MSys1, we had no gettext, ergo
no msgfmt, either. Therefore, we introduced a small and simple Tcl
script to perform the same task.
However, with MSys2, we no longer need that because we have a proper
msgfmt executable. Plus, the po2msg.sh script somehow manages to hang
when run in parallel.
Two reasons to use real msgfmt.exe instead.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This happens to shut up t7602 on Windows which would otherwise take
the different line endings for a sign that the merge failed.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Along the lines of 05d0e3b and f33946d, use cat instead of echo to avoid
line ending mismatches in the test result of "am empty-file does not
infloop" which make the test fail.
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
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>
When the result of a (a, 0) expression is not used, GCC now finds it
necessary to complain with a warning:
right-hand operand of comma expression has no effect
Let's just pretend to use the 0 value and have a peaceful and quiet life
again.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The environment is modified in most surprising circumstances, and not
all of them are under Git's control. For example, calling
curl_global_init() on Windows will ensure that the CHARSET variable is
set, adding one if necessary.
While the previous commit worked around crashes triggered by such
outside changes of the environment by relaxing the requirement that the
environment be terminated by a NULL pointer, the other assumption made
by `mingw_getenv()` and `mingw_putenv()` is that the environment is
sorted, for efficient lookup via binary search.
Let's make real sure that our environment is intact before querying or
modifying it, and reinitialize our idea of the environment if necessary.
With this commit, before working on the environment we look briefly for
indicators that the environment was modified outside of our control, and
to ensure that it is terminated with a NULL pointer and sorted again in
that case.
Note: the indicators are maybe not sufficient. For example, when a
variable is removed, it will not be noticed. It might also be a problem
if outside changes to the environment result in a modified `environ`
pointer: it is unclear whether such a modification could result in a
problem when `mingw_putenv()` needs to `realloc()` the environment
buffer.
For the moment, however, the current fix works well enough, so let's
only face the potential problems when (and if!) they occur.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Outside of our Windows-specific code, the end of the environment can be
marked also by a pointer to a NUL character, not only by a NULL pointer
as our code assumed so far.
That led to a buffer overrun in `make_environment_block()` when running
`git-remote-https` in `mintty` (because `curl_global_init()` added the
`CHARSET` environment variable *outside* of `mingw_putenv()`, ending the
environment in a pointer to an empty string).
Side note for future debugging on Windows: when running programs in
`mintty`, the standard input/output/error is not connected to a Win32
Console, but instead is pipe()d. That means that even stderr may not be
written completely before a crash, but has to be fflush()ed explicitly.
For example, when debugging crashes, the developer should insert an
`fflush(stderr);` at the end of the `error()` function defined in
usage.c.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
It is unlikely that we have an empty environment, ever, but *if* we do,
when `environ_size - 1` is passed to `bsearchenv()` it is misinterpreted
as a real large integer.
To make the code truly defensive, refuse to do anything at all if the
size is negative (which should not happen, of course).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
As suggested privately to Brendan Forster by some unnamed person
(suggestion for the future: use the public mailing list, or even the
public GitHub issue tracker, that is a much better place to offer such
suggestions), we should make use of gcc's stack smashing protector that
helps detect stack buffer overruns early.
Rather than using -fstack-protector, we use -fstack-protector-strong
because it strikes a better balance between how much code is affected
and the performance impact.
In a local test (time git log --grep=is -p), best of 5 timings went from
23.009s to 22.997s (i.e. the performance impact was *well* lost in the
noise).
This fixes https://github.com/git-for-windows/git/issues/501
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
MSys2 emulates pseudo terminals via named pipes, and isatty() returns 0
for such file descriptors. Therefore, some interactive functionality (such
as launching a pager, asking if a failed unlink should be repeated etc.)
doesn't work when run in a terminal emulator that uses MSys ptys (such as
mintty).
However, MSys uses special names for its pty pipes ('msys-*-pty*'), which
allows us to distinguish them from normal piped input / output.
On startup, check if stdin / stdout / stderr are connected to such pipes
using the NtQueryObject API from NTDll.dll. If the names match, adjust the
flags in MSVCRT's ioinfo structure accordingly.
Signed-off-by: Karsten Blees <blees@dcon.de>
On Windows >= Vista, not having an application manifest with a
requestedExecutionLevel can cause several kinds of confusing behavior.
The first and more obvious behavior is "Installer Detection", where
Windows sometimes decides (by looking at things like the file name and
even sequences of bytes within the executable) that an executable is an
installer and should run elevated (causing the well-known popup dialog
to appear). In Git's context, subcommands such as "git patch-id" or "git
update-index" fall prey to this behavior.
The second and more confusing behavior is "File Virtualization". It
means that when files are written without having write permission, it
does not fail (as expected), but they are instead redirected to
somewhere else. When the files are read, the original contents are
returned, though, not the ones that were just written somewhere else.
Even more confusing, not all write accesses are redirected; Trying to
write to write-protected .exe files, for example, will fail instead of
redirecting.
In addition to being unwanted behavior, File Virtualization causes
dramatic slowdowns in Git (see for instance
http://code.google.com/p/msysgit/issues/detail?id=320).
There are two ways to prevent those two behaviors: Either you embed an
application manifest within all your executables, or you add an external
manifest (a file with the same name followed by .manifest) to all your
executables. Since Git's builtins are hardlinked (or copied), it is
simpler and more robust to embed a manifest.
A recent enough MSVC compiler should already embed a working internal
manifest, but for MinGW you have to do so by hand.
Very lightly tested on Wine, where like on Windows XP it should not make
any difference.
References:
- New UAC Technologies for Windows Vista
http://msdn.microsoft.com/en-us/library/bb756960.aspx
- Create and Embed an Application Manifest (UAC)
http://msdn.microsoft.com/en-us/library/bb756929.aspx
[js: simplified the embedding dramatically by reusing Git for Windows'
existing Windows resource file, removed the optional (and dubious)
processorArchitecture attribute of the manifest's assemblyIdentity
section.]
Signed-off-by: Cesar Eduardo Barros <cesarb@cesarb.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
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.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: 마누엘 <nalla@users.noreply.github.com>
With MSys2, the sigset_t type is defined in sys/types.h, therefore we
need to #include said file.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This test assumed that there are no two equivalent directory separators.
However, on Windows, the back slash and the forward slash *are*
equivalent. Let's paper over this issue by converting the backward
slashes to forward ones in the test that fails with MSys2 otherwise.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When shell scripts access a $TMP variable containing backslashes, they
will be mistaken for escape characters. Let's not let that happen by
converting them to forward slashes.
This fixes t7800 with MSys2.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
There is a really useful debugging technique developed by Sverre
Rabbelier that inserts "bash &&" somewhere in the test scripts, letting
the developer interact at given points with the current state.
Another debugging technique, used a lot by this here coder, is to run
certain executables via gdb by guarding a "gdb -args" call in
bin-wrappers/git.
Both techniques were disabled by 781f76b1(test-lib: redirect stdin of
tests).
Let's reinstate the ability to run an interactive shell by making the
redirection optional: setting the TEST_NO_REDIRECT environment variable
will skip the redirection.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This test is susceptible to MSys2's posix-to-windows path mangling; Let's
just use POSIX paths throughout and let the tests pass.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
With MSys2, there is actually an implementation of mkfifo available. The
only problem is that it is only emulating named pipes through the MSys2
runtime; The Win32 API has no idea about named pipes, hence the Git
executable cannot access those pipes either.
The symptom is that Git fails with a '<name>: No such file or directory'
because MSys2 emulates named pipes through special-crafted '.lnk' files.
The solution is to tell the test suite explicitly that we cannot use
named pipes when we want to test a MinGW Git.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
MSys2 actually allows to create files or directories whose names contain
tabs, newlines or colors, even if plain Win32 API cannot access them.
As we are using an MSys2 bash to run the tests, such files or
directories are created successfully, but Git has no chance to work with
them because it is a regular Windows program, hence limited by the Win32
API.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
With MSys2, the "TZ" environment variable gets filtered out when calling
non-MSys2 executables. The reason is that Windows' time zone handling is
substantially different from the POSIX one.
However, we just taught Git for Windows' fork of the MSys2 runtime to
pass on the timezone in a different environment variable, MSYS2_TZ for
the sole purpose of Git being able to reinterpret it correctly.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The unsetenv code has no idea to update our environ_size, therefore
causing segmentation faults when environment variables are removed
without compat/mingw.c's knowing (MinGW's optimized lookup would try
to strcmp() against NULL in such a case).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
It does not quite work because it produces DOS line endings which the
shell does not like at all.
This lets t3406, t3903, t4254, t7400, t7401, t7406 and t7407 pass.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This just makes things compile, the test suite needs extra tender loving
care in addition to this change. We will address these issues in later
commits.
While at it, also allow building MSys2 Git (i.e. a Git that uses MSys2's
POSIX emulation layer).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git for Windows lags a little bit behind with the 2.x releases because
the Git for Windows developers wanted to let that big jump coincide with
a well-needed overhaul of the context within which Git for Windows is
developed.
To understand why this is such a big issue, it needs to be noted that
many parts of Git are not written in portable C, but instead relies on a
POSIX shell and Perl to be available. Even in the portable C part, there
is the ingrained notion that we can work with UTF-8 encoded strings.
To support the scripts, Git for Windows has to ship a minimal POSIX
emulation layer with Bash and Perl thrown in, and when the Git for
Windows effort started originally, in August 2007, we settled on using
MSys, a stripped down version of Cygwin. Consequently, the original name
of the project was "msysGit" (which, sadly, caused a *lot* of confusion
because few Windows users know about MSys, and even less care).
To compile the C code of Git for Windows, we used MSys, too: it sports
an additional version of the GNU C Compiler that targets the plain
Win32 API (with a few convenience functions thrown in) instead of the
POSIX emulation layer that would require the MSys runtime to run the
compiled programs. That way, Git for Windows' executable(s) are really
just Win32 programs. To discern executables requiring the POSIX
emulation layer from the ones that do not, the latter are called MinGW
(Minimal GNU for Windows) when the former are called MSys executables.
This reliance on MSys incurred challenges, too, though: some of our
changes to the MSys runtime -- necessary to support Git for Windows
better -- were not accepted upstream, the MSys runtime was not developed
further to support e.g. UTF-8 or 64-bit, and apart from not having a
package management system until much later (when mingw-get was
introduced), many packages provided by the MSys/MinGW project lag behind
the respective source code versions, in particular Bash and OpenSSL. For
a while, the Git for Windows project tried to remedy the situation by
trying to build newer versions of those packages, but the situation
quickly became untenable, especially with problems like the Heartbleed
bug requiring swift action and Git for Windows contributors being scarce
-- despite millions of downloads suggesting that there are many users.
After a brief push in the direction of mingw-get, thanks to the
long-time contributor and co-maintainer Sebastian Schuberth, it became
clear that we need to look for alternatives.
Happily, in the meantime the MSys2 project (https://msys2.github.io/)
emerged, and was chosen to be the base of the Git for Windows 2.x. MSys2
is a rewrite of the spirit of MSys: it is again a stripped down version
of Cygwin, but it is actively kept up-to-date with Cygwin's source code.
Thereby, it already supports Unicode internally, and it also offers the
64-bit support that we yearned for since the beginning of the Git for
Windows project.
MSys2 also ported the Pacman package management system from Arch Linux
and uses it heavily. This brings the same convenience to which Linux
users are used to from `yum` or `apt-get`, and to which MacOSX users are
used to from Homebrew or MacPorts, or BSD users from the Ports system,
to MSys2: a simple `pacman -Syu` will update all installed packages to
the newest versions currently available.
MSys2 is also *very* active, typically providing package updates
multiple times per week.
It still required a two-month effort to bring everything to a state
where Git's test suite passes, and a couple of patches await their
submission to the respective upstream projects. Yet without MSys2, the
modernization of Git for Windows would simply not have happened.
This commit lays the ground work to supporting MSys2-based Git builds.
Assisted-by: Waldek Maleska <weakcamel@users.github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
squash! config.mak.uname: support MSys2
Make sure that the nedmalloc patch is applied before.
With MSys2's GCC, `ReadWriteBarrier` is already defined, and FORCEINLINE
unfortunately gets defined incorrectly.
Let's work around both problems, using the MSys2-specific
__MINGW64_VERSION_MAJOR constant to guard them.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
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).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
MSys2's strace facility is very useful for debugging... With this patch,
the bash will be executed through strace if the environment variable
GIT_STRACE_COMMANDS is set, which comes in real handy when investigating
issues in the test suite.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This way the libraries get properly installed into the "site_perl"
directory and we just have to move them out of the "mingw" directory.
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
This is a companion patch to bf9acba (http: treat config options
sslCAPath and sslCAInfo as paths, 2015-11-23).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>