Win32: Thread-safe windows console output
commit44fbf4a7be26df1f8c819a254b4d187e135d703b
authorKarsten Blees <blees@dcon.de>
Fri, 7 Jan 2011 20:30:50 +0000 (7 21:30 +0100)
committerKarsten Blees <blees@dcon.de>
Sat, 8 Jan 2011 16:30:19 +0000 (8 17:30 +0100)
tree472d383da1526f01522ea1d1f42d023c2e036d64
parent0c2c850f341aee398a7c04cdaa1a4f31d3ddeb51
Win32: Thread-safe windows console output

Replace stdout and stderr with 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.

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.

Due to the byte-oriented pipe, ANSI escape 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.

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.

Signed-off-by: Karsten Blees <blees@dcon.de>
compat/mingw.c
compat/mingw.h
compat/winansi.c