This is in the great tradition of POSIX. Original fix by Olivier Refalo.
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>
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>
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>
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>
[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>
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>
This may happen when `git gc --auto` is run automatically, then the
user, to avoid wait time, switches to a new terminal, keeps working
and `git gc --auto` is started again because the first gc instance has
not clean up the repository.
This patch tries to avoid multiple gc running, especially in --auto
mode. In the worst case, gc may be delayed 12 hours if a daemon reuses
the pid stored in gc.pid.
kill(pid, 0) support is added to MinGW port so it should work on
Windows too.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Returning the SIGALRM handler for SIGINT is not very useful.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Sparse issues the following warnings:
SP compat/mingw.c
compat/mingw.c:795:3: warning: symbol 'pinfo_t' was not declared. \
Should it be static?
compat/mingw.c:796:16: warning: symbol 'pinfo' was not declared. \
Should it be static?
compat/mingw.c:797:18: warning: symbol 'pinfo_cs' was not declared. \
Should it be static?
compat/mingw.c:1207:23: warning: Using plain integer as NULL pointer
In 'pinfo_t' variable, defined on line 795, seems to have been a
mistake (a missing typedef keyword?), so we simply remove it.
The 'pinfo' variable does not require more than file scope, so we
simply add the static modifier to the declaration.
The 'pinfo_cs' variable, in contrast, requires initialisation in the
mingw replacement main() function, so we add an extern declaration to
the compat/mingw.h header file.
The remaining warning is suppressed by replacing the rhs of the
pointer assignment with the NULL pointer literal.
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
MinGW has a workaround when rmdir unnecessarily fails to retry with
a prompt, but the logic was kicking in when the rmdir failed with
ENOTEMPTY, i.e. was expected to fail and there is no point retrying.
* ef/mingw-rmdir:
mingw_rmdir: do not prompt for retry when non-empty
in ab1a11be ("mingw_rmdir: set errno=ENOTEMPTY when appropriate"),
a check was added to prevent us from retrying to delete a directory
that is both in use and non-empty.
However, this logic was slightly flawed; since we didn't return
immediately, we end up falling out of the retry-loop, but right into
the prompting-loop.
Fix this by setting errno, and guarding the prompting-loop with an
errno-check.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
There's no remaining call-sites, and as pointed out in the
previous commit message, it's not quite ideal. So let's just
lose it.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Set a control-handler to prevent the process from terminating, and
simulate SIGINT so it can be handled by a signal-handler as usual.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Make sure SIG_DFL for SIGALRM exits with 128 + SIGALRM so other
processes can diagnose why it exits.
While we're at it, make sure we only write to stderr if it's a
terminal, and change the output to match that of Linux.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
check to compat
Commit b2f5e268 (Windows: Work around an oddity when a pipe with no reader
is written to) introduced a check for EINVAL after fflush() to fight
spurious "Invalid argument" errors on Windows when a pipe was broken. But
this check may hide real errors on systems that do not have the this odd
behavior. Introduce an fflush wrapper in compat/mingw.* so that the treatment
is only applied on Windows.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The POSIX standard specifies a return type of int for all six exec
functions. In addition, all exec functions return -1 on error, and
simply do not return on success. However, the current emulation of
the exec functions on mingw are declared with a void return type.
This would cause a problem should any code attempt to call the
exec function in a non-void context. In particular, if an exec
function were used in a conditional it would fail to compile.
In order to improve the fidelity of the emulation, we change the
return type of the mingw_execv[p] functions to int and return -1
on error.
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
POSIX says that last parameter to waitpid should be 'int',
so let's make it so.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* pt/mingw-misc-fixes:
t9901: fix line-ending dependency on windows
mingw: ensure sockets are initialized before calling gethostname
mergetools: use the correct tool for Beyond Compare 3 on Windows
t9300: do not run --cat-blob-fd related tests on MinGW
git-svn: On MSYS, escape and quote SVN_SSH also if set by the user
t9001: do not fail only due to CR/LF issues
t1020: disable the pwd test on MinGW
If the Windows sockets subsystem has not been initialized yet then an
attempt to get the hostname returns an error and prints a warning to the
console. This solves this issue for msysGit as seen with 'git fetch'.
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The "x"-prefixed versions of strdup, malloc, etc. will check whether the
allocation was successful and terminate the process otherwise.
A few uses of malloc were left alone since they already implemented a
graceful path of failure or were in a quasi external library like xdiff.
Additionally, the call to malloc in compat/win32/syslog.c was not modified
since the syslog() implemented there is a die handler and a call to the
x-wrappers within a die handler could result in recursion should memory
allocation fail. This will have to be addressed separately.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* js/i18n-windows:
Windows: teach getenv to do a case-sensitive search
mingw.c: move definition of mingw_getenv down
sh-i18n--envsubst: do not crash when no arguments are given
getenv() on Windows looks up environment variables in a case-insensitive
manner. Even though all documentations claim that the environment is
case-insensitive, it is possible for applications to pass an environment
to child processes that has variables that differ only in case. Bash on
Windows does this, for example, and sh-i18n--envsubst depends on this
behavior.
With this patch environment variables are first looked up in a
case-sensitive manner; only if this finds nothing, the system's getenv() is
used as a fallback.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We want to use static lookup_env() in a subsequent change.
At first sight, this change looks innocent. But it is not due to the
#undef getenv. There is one caller of getenv between the old location and
the new location whose behavior could change. But as can be seen from the
defintion of mingw_getenv, the behavior for this caller does not change
substantially.
To ensure consistent behavior in the future, change all getenv callers
in mingw.c to use mingw_getenv.
With this patch, this is not a big deal, yet, but with the subsequent
change, where we teach getenv to do a case-sensitive lookup, the behavior
of all call sites is changed.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Even though Windows's socket functions look like their POSIX counter parts,
they do not operate on file descriptors, but on "socket objects". To bring
the functions in line with POSIX, we have proxy functions that wrap and
unwrap the socket objects in file descriptors using open_osfhandle and
get_osfhandle. But shutdown() was not proxied, yet. Fix this.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
I found that some doubled words had snuck back into projects from which
I'd already removed them, so now there's a "syntax-check" makefile rule in
gnulib to help prevent recurrence.
Running the command below spotted a few in git, too:
git ls-files | xargs perl -0777 -n \
-e 'while (/\b(then?|[iao]n|i[fst]|but|f?or|at|and|[dt])\s+\1\b/gims)' \
-e '{$n=($` =~ tr/\n/\n/ + 1); ($v=$&)=~s/\n/\\n/g;' \
-e 'print "$ARGV:$n:$v\n"}'
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
On Windows, EACCES overrules ENOTEMPTY when calling rmdir(). But if the
directory is busy, we only want to retry deleting the directory if it
is empty, so test specifically for that case and set ENOTEMPTY rather
than EACCES.
Noticed by Greg Hazel.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The same logic as for unlink and rename also applies to rmdir. For
example in case you have a shell open in a git controlled folder. This
will easily fail. So lets be nice for such cases as well.
Signed-off-by: Heiko Voigt <heiko.voigt@mahr.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
On Windows in case a program is accessing a file unlink or
move operations may fail. To give the user a chance to correct
this we simply wait until the user asks us to retry or fail.
This is useful because of the following use case which seem
to happen rarely but when it does it is a mess:
After making some changes the user realizes that he was on the
incorrect branch. When trying to change the branch some file
is still in use by some other process and git stops in the
middle of changing branches. Now the user has lots of files
with changes mixed with his own. This is especially confusing
on repositories that contain lots of files.
Although the recent implementation of automatic retry makes
this scenario much more unlikely lets provide a fallback as
a last resort.
Thanks to Albert Dvornik for disabling the question if users can't see it.
If the stdout of the command is connected to a terminal but the stderr
has been redirected, the odds are good that the user can't see any
question we print out to stderr. This will result in a "mysterious
hang" while the app is waiting for user input.
It seems better to be conservative, and avoid asking for input
whenever the stderr is not a terminal, just like we do for stdin.
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Albert Dvornik <dvornik+git@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
If a file is opened by another process (e.g. indexing of an IDE) for
reading it is not allowed to be deleted. So in case unlink fails retry
after waiting for some time. This extends the workaround from 6ac6f878.
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The next patch implements a workaround in case unlink fails on Windows.
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* maint:
imap-send: link against libcrypto for HMAC and others
git-send-email.perl: Deduplicate "to:" and "cc:" entries with names
mingw: do not set errno to 0 on success
Currently do_lstat always sets errno to 0 on success. This incorrectly
overwrites previous errors.
Fetch the error-code into a temporary variable instead, and assign that
to errno on failure.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The mingw-runtime implemenation of opendir, readdir and closedir
sets errno to 0 on success, something that POSIX explicitly
forbids. 3ba7a06 ("A loose object is not corrupt if it cannot be
read due to EMFILE") introduce a dependency on this behaviour,
leading to a broken "git clone" on Windows.
compat/mingw.c contains an implementation of readdir, and
compat/msvc.c contains implementations of opendir and closedir.
Move these to compat/win32/dirent.[ch], and change to our own DIR
structure at the same time.
This provides a generic Win32-implementation of opendir, readdir
and closedir which works on both MinGW and MSVC and does not reset
errno, and as a result git clone is working again on Windows.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Previously all error conditions were ignored. Be nice, and set errno
when we should.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Allow the node parameter to be null, which is used for getting
the default bind address.
Also allow the hints parameter to be null, to improve standard
conformance of the stub implementation a little.
Signed-off-by: Martin Storsjo <martin@martin.st>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This is a quite limited kill-emulation; it can only handle
SIGTERM on positive pids. However, it's enough for git-daemon.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The Windows port have so far been using process handles in place
of PID. However, this is not work consistent with what getpid
returns.
PIDs are system-global identifiers, but process handles are local
to a process. Using PIDs instead of process handles allows, for
instance, a user to kill a hung process with the Task Manager,
something that would have been impossible with process handles.
Change the code to use the real PID, and use OpenProcess to get a
process-handle. Store the PID and the process handle in a linked
list protected by a critical section, so we can safely close the
process handle later.
Linked list code written by Pat Thoyts.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-daemon requires some socket-functionality that is not yet
supported in the Windows-port. This patch adds said functionality,
and makes sure WSAStartup gets called by socket(), since it is the
first network-call in git-daemon.
Signed-off-by: Mike Pape <dotzenlabs@gmail.com>
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
As of 2dbc887e, shell.c employs execv(), so provide a MinGW-specific
mingw_execv() override, complementing existing mingw_execvp() and
cousins.
As a bonus, this also resolves a compilation warning due to an
execv() prototype mismatch between Linux and MinGW. Linux expects
the second argument to be (char *const *), whereas MinGW expects
(const char *const *).
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
fetch_and_setup_pack_index() apparently pass a NULL-pointer to
parse_pack_index(), which in turn pass it to check_packed_git_idx(),
which again pass it to open(). Since open() already sets errno
correctly for the NULL-case, let's just avoid the problematic strcmp.
[PT: squashed in fix for fopen which was missed first time round]
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
The mingw function to launch the system html browser is silent if the
target file does not exist leaving the user confused. Make it display
something.
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Reviewed-by: Erik Faye-Lund <kusmabite@gmail.com>
In msysGit the stat() function has been implemented using mingw_lstat
which sets the st_mode member to S_IFLNK when a symbolic links is found.
This causes the is_executable function to return when git attempts to
build a list of available commands in the help code and we end up missing
most git commands. (msysGit issue #445)
This patch modifies the implementation so that lstat() will return the link
flag but if we are called as stat() we read the size of the target and set
the mode to that of a regular file.
Includes squashed fix st_mode for symlink dirs
Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
POSIX sayeth:
"If times is a null pointer, the access and modification
times of the file shall be set to the current time."
Let's do so.
Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Bigger writes to network drives on Windows XP fail. Cap them at 31MB to
allow them to succeed. Callers need to be prepared for write() calls
that do less work than requested anyway.
On local drives, write() calls are translated to WriteFile() calls with
a cap of 64KB on Windows XP and 256KB on Vista. Thus a cap of 31MB won't
affect the number of WriteFile() calls which do the actual work. There's
still room for some other version of Windows to use a chunk size of 1MB
without increasing the number of system calls.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
A caller of start_command can set the member 'dir' to a directory to
request that the child process starts with that directory as CWD. The first
user of this feature was added recently in eee49b6 (Teach diff --submodule
and status to handle .git files in submodules).
On Windows, we have been lazy and had not implemented support for this
feature, yet. This fixes the shortcoming.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Starting with 5256b00 (Use git_mkstemp_mode instead of plain mkstemp to
create object files, 2010-02-22) utime() is invoked on read-only files.
This is not allowed on Windows and results in many warnings of the form
failed utime() on .git/objects/23/tmp_obj_VlgHlc: Permission denied
during a repack. Fix it by making the file temporarily writable.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
On Windows, the equivalent of "/dev/null" is "nul". This implements
compatibility wrappers around fopen() and freopen() that check for this
particular file name.
The new tests exercise code paths where this is relevant.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
To implement gettimeofday(), a broken-down UTC time was requested from the
system using GetSystemTime(), then tm_to_time_t() was used to convert it
to a time_t because it does not look at the current timezone, which
mktime() would do.
Use GetSystemTimeAsFileTime() and a different conversion path to avoid this
back-reference from the compatibility layer to the generic code.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This patch implements native to Windows subset of pthreads API used by Git.
It allows to remove Pthreads for Win32 dependency for MSVC, msysgit and
Cygwin.
[J6t: If the MinGW build was built as part of the msysgit build
environment, then threading was already enabled because the
pthreads-win32 package is available in msysgit. With this patch, we can now
enable threaded code unconditionally.]
Signed-off-by: Andrzej K. Haczewski <ahaczewski@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When stdin, stdout, or stderr must be redirected for a child process that
on Windows is spawned using one of the spawn() functions of Microsoft's
C runtime, then there is no choice other than to
1. make a backup copy of fd 0,1,2 with dup
2. dup2 the redirection source fd into 0,1,2
3. spawn
4. dup2 the backup back into 0,1,2
5. close the backup copy and the redirection source
We used this idiom as well -- but we are not using the spawn() functions
anymore!
Instead, we have our own implementation. We had hardcoded that stdin,
stdout, and stderr of the child process were inherited from the parent's
fds 0, 1, and 2. But we can actually specify any fd.
With this patch, the fds to inherit are passed from start_command()'s
WIN32 section to our spawn implementation. This way, we can avoid the
backup copies of the fds.
The backup copies were a bug waiting to surface: The OS handles underlying
the dup()ed fds were inherited by the child process (but were not
associated with a file descriptor in the child). Consequently, the file or
pipe represented by the OS handle remained open even after the backup copy
was closed in the parent process until the child exited.
Since our implementation of pipe() creates non-inheritable OS handles, we
still dup() file descriptors in start_command() because dup() happens to
create inheritable duplicates. (A nice side effect is that the fd cleanup
in start_command is the same for Windows and Unix and remains unchanged.)
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Our implementation of pipe() must create non-inheritable handles for the
reason that when a child process is started, there is no opportunity to
close the unneeded pipe ends in the child (on POSIX this is done between
fork() and exec()).
Previously, we used the _pipe() function provided by Microsoft's C runtime
(which creates inheritable handles) and then turned the handles into
non-inheritable handles using the DuplicateHandle() API.
Simplify the procedure by using the CreatePipe() API, which can create
non-inheritable handles right from the beginning.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This DLL is only needed to invoke the browser in a "git help" call. By
looking up the only function that we need at runtime, we can avoid the
startup costs of this DLL.
DLL usage can be profiled with Microsoft's Dependency Walker. For example,
a call to "git diff-files" loaded
before: 19 DLLs
after: 9 DLLs
As a result, the runtime of 'make -j2 test' went down from 16:00min
to 12:40min on one of my boxes.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The IPv6 support functions are loaded dynamically, to maintain backwards
compatibility with versions of Windows prior to XP, and fallback wrappers
are provided, implemented in terms of gethostbyname and gethostbyaddr.
Signed-off-by: Martin Storsjo <martin@martin.st>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The winsock library must be initialized. Since gethostbyname() is the
first function that calls into winsock, it was overridden to do the
initialization. This refactoring helps the next patch, where other
functions can be called earlier.
Signed-off-by: Martin Storsjo <martin@martin.st>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When the NO_MMAP build variable is set, the msvc linker complains:
error LNK2001: unresolved external symbol _getpagesize
The msvc libraries do not define the getpagesize() function,
so we move the mingw_getpagesize() implementation from the
conditionally built win32mmap.c file to mingw.c.
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Centralize the include of windows.h in git-compat-util.h, turn on
WIN32_LEAN_AND_MEAN to avoid including plenty of other header files
which is not needed in Git. Also ensure we load winsock2.h first,
so we don't load the older winsock definitions at a later stage,
since they contain duplicate definitions.
When moving windows.h into git-compat-util.h, we need to protect
the definition of struct pollfd in mingw.h, since this file is used
by both MinGW and MSVC, and the latter defines this struct in
winsock2.h.
We need to keep the windows.h include in compat/win32.h, since its
shared by both MinGW and Cygwin, and we're not touching Cygwin in
this commit. The include in git-compat-util.h is protected with an
ifdef WIN32, which is not the case when compiling for Cygwin.
Signed-off-by: Marius Storm-Olsen <mstormo@gmail.com>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
MSVC requires __stdcall to be between the functions return value and the
function name, and that the function pointer type is in the form of
return_type (WINAPI *function_name)(arguments...)
Signed-off-by: Frank Li <lznuaa@gmail.com>
Signed-off-by: Marius Storm-Olsen <mstormo@gmail.com>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
MinGW set the _CRT_fmode to set both the default fmode and _O_BINARY on
stdin/stdout/stderr. Rather use the main() define in mingw.h to set this
for both MinGW and MSVC.
This will ensure that a MinGW and MSVC build will handle input and output
identically.
Signed-off-by: Marius Storm-Olsen <mstormo@gmail.com>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
MSVC does not understand this C99 style.
Signed-off-by: Frank Li <lznuaa@gmail.com>
Signed-off-by: Marius Storm-Olsen <mstormo@gmail.com>
Acked-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Previously, it would not be possible to call start_command twice for the
same struct child_process that has env set.
The fix is achieved by moving the loop that modifies the environment block
into a helper function. This also allows us to make two other helper
functions static.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The original readdir implementation was fast, but didn't
support the d_type. This means that git would do additional
lstats for each entry, to figure out if the entry was a
directory or not. This unneedingly slowed down many
operations, since Windows API provides this information
directly when walking the directories.
By running this implementation on Moe's repo structure:
mkdir bummer && cd bummer; for ((i=0;i<100;i++)); do
mkdir $i && pushd $i;
for ((j=0;j<1000;j++)); do echo "$j" >$j; done;
popd;
done
We see the following speedups:
git add .
-------------------
old: 00:00:23(.087)
new: 00:00:21(.512) 1.07x
git status
-------------------
old: 00:00:03(.306)
new: 00:00:01(.684) 1.96x
git clean -dxf
-------------------
old: 00:00:01(.918)
new: 00:00:00(.295) 6.50x
Signed-off-by: Marius Storm-Olsen <marius@trolltech.com>
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
conio.h provides the declaration.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We need getpass() to activate curl on MinGW. Although the default
Makefile currently has 'NO_CURL = YesPlease', msysgit releases do
provide curl support, so getpass() is used.
[spr: - edited commit message.
- squashed commit that provides getpass() declaration.]
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
\r is common on Windows, so we should handle it gracefully.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Essentially; s/type* /type */ as per the coding guidelines.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We have replaced rename() with a version that can rename a file to a
destination that already exists. Nevertheless, many users, the author
included, observe failures in the code that are not reproducible.
The theory is that the failures are due to some other process that happens
to have opened the destination file briefly at the wrong moment. (And there
is no way on Windows to delete or replace a file that is currently open.)
The most likely candidate for such a process is a virus scanner. The
failure is more often observed while there is heavy git activity (for
example while the test suite is running or during a rebase operation).
We work around the failure by retrying the rename operation if it failed
due to ERROR_ACCESS_DENIED. The retries are delayed a bit: The first only
by giving up the time slice, the next after the minimal scheduling
granularity, and if more retries are needed, then we wait some non-trivial
amount of time with exponential back-off.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Before a process can be spawned by mingw_spawnve, arguments must be
surrounded by double-quotes if special characters are present. This is
necessary because the startup code of the spawned process will expand
arguments that look like glob patterns. "Normal" Windows command line
utilities expand only * and ?, but MSYS programs, including bash, are
different: They also expand braces, and this has already been taken care
of by compat/mingw.c:quote_arg().
But MSYS programs also treat single-quotes in a special way: Arguments
between single-quotes are spliced together (with spaces) into a word.
With this patch this treatment is avoided by quoting arguments that contain
single-quotes.
This lets t4252 pass on Windows.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This function translates many possible Win32 error codes to suitable
errno numbers. We will use it in our wrapper functions that need to call
into Win32.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The type 'off_t' should be used everywhere so that the bit-depth of that
type can be adjusted in the standard C library, and you just need to
recompile your program to benefit from the extended precision.
Only that it was not done that way in the MS runtime library.
This patch reroutes off_t to off64_t and provides the other necessary
changes so that finally, clones larger than 2 gigabyte work on Windows
(provided you are on a file system that allows files larger than 2gb).
Initial patch by Sickboy <sb@dev-heaven.net>.
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>
On POSIX, rename() can replace files that are not writable. On Windows,
however, read-only files cannot be replaced without additional efforts:
We have to make the destination writable first.
Since the situations where the destination is read-only are rare, we do not
make the destination writable on every invocation, but only if the first
try to rename a file failed with an "access denied" error.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Apparently, CREATE_NO_WINDOW makes the OS tell the process
that it has a console, but without actually creating the
window. As a result, when git is started from GUI, ssh
tries to ask its questions on the invisible console.
This patch uses DETACHED_PROCESS instead, which clearly
means that the process should be left without a console.
The downside is that if the process manually calls
AllocConsole, the window will appear. A similar thing
might occur if it calls another console executable.
Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
Acked-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Some small Win32 specific functions will be shared by MinGW and
Cygwin compatibility layer. Place them into a separate header.
Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The field device is not used by Git, and putting the number of the
current device is meaningless anyway.
Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
Acked-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Our poll() emulation did not support the timeout argument. With this patch
we support it for the simple case where poll() does not need to wait on
file descriptors as well because this case amounts to a mere Sleep().
This is needed if the user sets help.autocorrect is set to a positive
value.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This reverts commit fc2ded5b08.
As we do not need the member in struct stat, we do not need to have a
custom "struct mingw_stat" anymore.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Some platforms do not have st_blocks member in "struct stat"; mingw
already emulates it by rounding it up to closest 512-byte blocks (even
though it could overcount when a file has holes).
The reason to use the member is only to figure out how many kilobytes the
files occupy on-disk, so give a helper function in git-compat-util.h to
compute this value.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Acked-by: Johannes Sixt <johannes.sixt@telecom.at>
Without this simple fix "git gui" in the git source directory
finds the git-gui directory instead of the tcl script in /usr/bin.
Signed-off-by: Eric Raible <raible@gmail.com>
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The system's default browser for displaying HTML help pages is now used
directly on Windows, instead of launching git-web--browser, which
requires a Unix shell. Avoiding MSYS' bash when possible is good
because it avoids potential path translation issues. In this case it is
not too hard to avoid launching a shell, so let's avoid it.
The Windows-specific code is implemented in compat/mingw.c to avoid
platform-specific code in the main code base. On Windows, open_html is
provided as a define. If open_html is not defined, git-web--browse is
used. This approach avoids platform-specific ifdefs by using
per-function ifdefs. The "ifndef open_html" together with the
introductory comment should sufficiently warn developers, so that they
hopefully will not break this mechanism.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Windows's struct stat does not have a st_blocks member. Since we already
have our own stat/lstat/fstat implementations, we can just as well use
a customized struct stat. This patch introduces just that, and also fills
in the st_blocks member. On the other hand, we don't provide members that
are never used.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
This is a necessary pendant to our lstat implementation: MSVCRT's
implementations of lstat and utime do some adjustments if daylight
saving time is in effect, but our lstat implementation doesn't do these
adjustments and report the correct UTC time. With this implementation
we omit the adjustments in utime() as well and always write UTC.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
This gives us a significant speedup when adding, committing and stat'ing files.
Also, since Windows doesn't really handle symlinks, we let stat just uses lstat.
We also need to replace fstat, since our implementation and the standard stat()
functions report slightly different timestamps, possibly due to timezones.
We simply report UTC in our implementation, and do our FILETIME to time_t
conversion based on the document at http://support.microsoft.com/kb/167296.
With Moe's repo structure (100K files in 100 dirs, containing 2-4 bytes)
mkdir bummer && cd bummer; for ((i=0;i<100;i++)); do
mkdir $i && pushd $i;
for ((j=0;j<1000;j++)); do echo "$j" >$j; done;
popd;
done
We get the following performance boost:
With normal lstat & stat Custom lstat/fstat
------------------------ ------------------------
Command: git init Command: git init
------------------------ ------------------------
real 0m 0.047s real 0m 0.063s
user 0m 0.031s user 0m 0.015s
sys 0m 0.000s sys 0m 0.015s
------------------------ ------------------------
Command: git add . Command: git add .
------------------------ ------------------------
real 0m19.390s real 0m12.031s 1.6x
user 0m 0.015s user 0m 0.031s
sys 0m 0.030s sys 0m 0.000s
------------------------ ------------------------
Command: git commit -a.. Command: git commit -a..
------------------------ ------------------------
real 0m30.812s real 0m16.875s 1.8x
user 0m 0.015s user 0m 0.015s
sys 0m 0.000s sys 0m 0.015s
------------------------ ------------------------
3x Command: git-status 3x Command: git-status
------------------------ ------------------------
real 0m11.860s real 0m 5.266s 2.2x
user 0m 0.015s user 0m 0.015s
sys 0m 0.015s sys 0m 0.015s
real 0m11.703s real 0m 5.234s
user 0m 0.015s user 0m 0.015s
sys 0m 0.000s sys 0m 0.000s
real 0m11.672s real 0m 5.250s
user 0m 0.031s user 0m 0.015s
sys 0m 0.000s sys 0m 0.000s
------------------------ ------------------------
Command: git commit... Command: git commit...
(single file) (single file)
------------------------ ------------------------
real 0m14.234s real 0m 7.735s 1.8x
user 0m 0.015s user 0m 0.031s
sys 0m 0.000s sys 0m 0.000s
Signed-off-by: Marius Storm-Olsen <mstormo_git@storm-olsen.com>
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
The problem with Windows's own implementation is that it tries to be
clever when a console program is invoked from a GUI application: In this
case it sometimes automatically allocates a new console window. As a
consequence, the IO channels of the spawned program are directed to the
console, but the invoking application listens on channels that are now
directed to nowhere.
In this implementation we use the lowlevel facilities of CreateProcess(),
which offers a flag to tell the system not to open a console. As a side
effect, only stdin, stdout, and stderr channels will be accessible from
C programs that are spawned. Other channels (file handles, pipe handles,
etc.) are still inherited by the spawned program, but it doesn't get
enough information to access them.
Johannes Schindelin integrated path quoting and unified the various
*execv* and *spawnv* helpers. Eric Raible suggested to also quote '{'.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
gethostbyname() is the first function that calls into the Winsock library,
and it is wrapped only to initialize the library.
socket() is wrapped for two reasons:
- Windows's socket() creates things that are like low-level file handles,
and they must be converted into file descriptors first.
- And these handles cannot be used with plain ReadFile()/WriteFile()
because they are opened for "overlapped IO". We have to use WSASocket()
to create non-overlapped IO sockets.
connect() must be wrapped because Windows's connect() expects the low-level
sockets, not file descriptors, and we must first unwrap the file descriptor
before we can pass it on to Windows's connect().
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
This emulation of poll() is by far not general. It assumes that the
fds that are to be waited for are connected to pipes. The pipes are
polled in a loop until data becomes available in at least one of them.
If only a single fd is waited for, the implementation actually does
not wait at all, but assumes that a subsequent read() will block.
In order not to needlessly burn CPU time, the CPU is yielded to other
processes before the next round in the poll loop using Sleep(0). Note that
any sleep timeout greater than zero will reduce the efficiency by a
magnitude.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>