Module: wine Branch: master Commit: 54e117018cd4cc58c258da92686bfad13946bde2 URL: https://source.winehq.org/git/wine.git/?a=commit;h=54e117018cd4cc58c258da926...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Sep 21 17:07:29 2020 +0200
kernelbase: Use conhost to handle Unix consoles.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/console.c | 60 ++++++++++++++++++++++++++++++++++++++++++----- dlls/ntdll/unix/env.c | 29 ++++++++++++++++++----- 2 files changed, 77 insertions(+), 12 deletions(-)
diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 2289d7ea5f..0d105199fc 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -1656,11 +1656,18 @@ static HANDLE create_pseudo_console( COORD size, HANDLE input, HANDLE output, HA si.StartupInfo.hStdError = output; si.StartupInfo.dwFlags = STARTF_USESTDHANDLES; swprintf( conhost_path, ARRAY_SIZE(conhost_path), L"%s\conhost.exe", system_dir ); - swprintf( cmd, ARRAY_SIZE(cmd), - L""%s" --headless %s--width %u --height %u --signal 0x%x --server 0x%x", - conhost_path, (flags & PSEUDOCONSOLE_INHERIT_CURSOR) ? L"--inheritcursor " : L"", - size.X, size.Y, signal, server ); - + if (signal) + { + swprintf( cmd, ARRAY_SIZE(cmd), + L""%s" --headless %s--width %u --height %u --signal 0x%x --server 0x%x", + conhost_path, (flags & PSEUDOCONSOLE_INHERIT_CURSOR) ? L"--inheritcursor " : L"", + size.X, size.Y, signal, server ); + } + else + { + swprintf( cmd, ARRAY_SIZE(cmd), L""%s" --unix --width %u --height %u --server 0x%x", + conhost_path, size.X, size.Y, server ); + } Wow64DisableWow64FsRedirection( &redir ); res = CreateProcessW( conhost_path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si.StartupInfo, &pi ); @@ -1745,11 +1752,52 @@ HRESULT WINAPI ResizePseudoConsole( HPCON handle, COORD size ) return E_NOTIMPL; }
+static BOOL is_tty_handle( HANDLE handle ) +{ + return ((UINT_PTR)handle & 3) == 1; +} + void init_console( void ) { RTL_USER_PROCESS_PARAMETERS *params = RtlGetCurrentPeb()->ProcessParameters;
- if (params->ConsoleHandle == CONSOLE_HANDLE_ALLOC) + if (params->ConsoleHandle == CONSOLE_HANDLE_SHELL) + { + HANDLE tty_in = NULL, tty_out = NULL, process = NULL; + COORD size; + + if (is_tty_handle( params->hStdInput )) + { + tty_in = params->hStdInput; + params->hStdInput = NULL; + } + if (is_tty_handle( params->hStdOutput )) + { + tty_out = params->hStdOutput; + params->hStdOutput = NULL; + } + if (is_tty_handle( params->hStdError )) + { + if (tty_out) CloseHandle( params->hStdError ); + else tty_out = params->hStdError; + params->hStdError = NULL; + } + + size.X = params->dwXCountChars; + size.Y = params->dwYCountChars; + TRACE( "creating unix console (size %u %u)\n", size.X, size.Y ); + params->ConsoleHandle = create_pseudo_console( size, tty_in, tty_out, NULL, 0, &process ); + CloseHandle( process ); + CloseHandle( tty_in ); + CloseHandle( tty_out ); + + if (params->ConsoleHandle && create_console_connection( params->ConsoleHandle )) + { + init_console_std_handles( FALSE ); + console_flags = 0; + } + } + else if (params->ConsoleHandle == CONSOLE_HANDLE_ALLOC) { HMODULE mod = GetModuleHandleW( NULL ); params->ConsoleHandle = NULL; diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index f4d9ef15fc..876dcf0192 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -1156,12 +1156,29 @@ NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size ) void CDECL get_initial_console( RTL_USER_PROCESS_PARAMETERS *params ) { int output_fd = -1; - if (isatty(0) || isatty(1) || isatty(2)) params->ConsoleHandle = CONSOLE_HANDLE_SHELL; - if (!isatty(0)) wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE, OBJ_INHERIT, ¶ms->hStdInput ); - if (!isatty(2)) wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms->hStdError ); - else output_fd = 2; - if (!isatty(1)) wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms->hStdOutput ); - else output_fd = 1; + + wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE, OBJ_INHERIT, ¶ms->hStdInput ); + wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms->hStdOutput ); + wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms->hStdError ); + + /* mark tty handles for kernelbase, see init_console */ + if (params->hStdInput && isatty(0)) + { + params->ConsoleHandle = CONSOLE_HANDLE_SHELL; + params->hStdInput = (HANDLE)((UINT_PTR)params->hStdInput | 1); + } + if (params->hStdError && isatty(2)) + { + params->ConsoleHandle = CONSOLE_HANDLE_SHELL; + params->hStdError = (HANDLE)((UINT_PTR)params->hStdError | 1); + output_fd = 2; + } + if (params->hStdOutput && isatty(1)) + { + params->ConsoleHandle = CONSOLE_HANDLE_SHELL; + params->hStdOutput = (HANDLE)((UINT_PTR)params->hStdOutput | 1); + output_fd = 1; + }
if (output_fd != -1) {