From a4bc5a2138655409e28036c7110451fdf94c9403 Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Fri, 16 Feb 2001 19:08:19 +0000
Subject: [PATCH] Pass the stdin/stdout handles on startup to use as console
 (based on a patch by Eric Pouech).

---
 include/server.h    |  6 ++++--
 scheduler/process.c | 36 +++++++++++++++++++++++++++++++++---
 server/console.c    | 32 ++++++++++++++++++++++----------
 server/process.c    |  5 ++---
 server/trace.c      |  4 +++-
 win32/console.c     |  5 +++--
 6 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/include/server.h b/include/server.h
index 77f394d1945..858131c5c4a 100644
--- a/include/server.h
+++ b/include/server.h
@@ -176,6 +176,7 @@ struct init_process_request
     REQUEST_HEADER;                /* request header */
     IN  void*        ldt_copy;     /* addr of LDT copy */
     IN  int          ppid;         /* parent Unix pid */
+    OUT int          create_flags; /* creation flags */
     OUT int          start_flags;  /* flags from startup info */
     OUT unsigned int server_start; /* server start time (GetTickCount) */
     OUT handle_t     exe_file;     /* file handle for main exe */
@@ -738,7 +739,8 @@ struct set_console_fd_request
 {
     REQUEST_HEADER;                 /* request header */
     IN  handle_t     handle;        /* handle to the console */
-    IN  handle_t     file_handle;   /* handle of file to use as file descriptor */
+    IN  handle_t     handle_in;     /* handle of file to use as input */
+    IN  handle_t     handle_out;    /* handle of file to use as output */
     IN  int          pid;           /* pid of xterm (hack) */
 };
 
@@ -1592,7 +1594,7 @@ union generic_request
     struct async_result_request async_result;
 };
 
-#define SERVER_PROTOCOL_VERSION 36
+#define SERVER_PROTOCOL_VERSION 37
 
 /* ### make_requests end ### */
 /* Everything above this line is generated automatically by tools/make_requests */
diff --git a/scheduler/process.c b/scheduler/process.c
index f09aec74c84..a120c39db82 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -220,6 +220,31 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule )
 }
 
 
+/***********************************************************************
+ *           set_console_handles
+ *
+ * Set the console handles to use stdin/stdout.
+ */
+static void set_console_handles( HANDLE console )
+{
+    HANDLE in = FILE_DupUnixHandle( 0, GENERIC_READ );
+    HANDLE out = FILE_DupUnixHandle( 1, GENERIC_WRITE );
+
+    SERVER_START_REQ
+    {
+        struct set_console_fd_request *req = server_alloc_req( sizeof(*req), 0 );
+        req->handle     = console;
+        req->handle_in  = in;
+        req->handle_out = out;
+        req->pid = 0;
+        server_call( REQ_SET_CONSOLE_FD );
+    }
+    SERVER_END_REQ;
+    NtClose( in );
+    NtClose( out );
+}
+
+
 /***********************************************************************
  *           process_init
  *
@@ -228,6 +253,7 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule )
 static BOOL process_init( char *argv[] )
 {
     BOOL ret;
+    int create_flags = 0;
 
     /* store the program name */
     argv0 = argv[0];
@@ -259,20 +285,24 @@ static BOOL process_init( char *argv[] )
             memcpy( main_exe_name, server_data_ptr(req), len );
             main_exe_name[len] = 0;
             main_exe_file = req->exe_file;
+            create_flags  = req->create_flags;
             current_startupinfo.dwFlags     = req->start_flags;
             server_startticks               = req->server_start;
             current_startupinfo.wShowWindow = req->cmd_show;
             current_startupinfo.hStdInput   = req->hstdin;
             current_startupinfo.hStdOutput  = req->hstdout;
             current_startupinfo.hStdError   = req->hstderr;
-            SetStdHandle( STD_INPUT_HANDLE,  current_startupinfo.hStdInput );
-            SetStdHandle( STD_OUTPUT_HANDLE, current_startupinfo.hStdOutput );
-            SetStdHandle( STD_ERROR_HANDLE,  current_startupinfo.hStdError );
         }
     }
     SERVER_END_REQ;
     if (!ret) return FALSE;
 
+    SetStdHandle( STD_INPUT_HANDLE,  current_startupinfo.hStdInput );
+    SetStdHandle( STD_OUTPUT_HANDLE, current_startupinfo.hStdOutput );
+    SetStdHandle( STD_ERROR_HANDLE,  current_startupinfo.hStdError );
+    if (create_flags & CREATE_NEW_CONSOLE)
+        set_console_handles( current_startupinfo.hStdOutput );
+
     /* Create the system and process heaps */
     if (!HEAP_CreateSystemHeap()) return FALSE;
     current_process.heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
diff --git a/server/console.c b/server/console.c
index f389e25a85c..34190704e5c 100644
--- a/server/console.c
+++ b/server/console.c
@@ -477,24 +477,36 @@ DECL_HANDLER(get_console_info)
 /* set a console fd */
 DECL_HANDLER(set_console_fd)
 {
-    struct object *obj;
+    struct object *obj_in, *obj_out;
     int fd_in, fd_out;
 
-    if (!(obj = get_handle_obj( current->process, req->file_handle,
-                                GENERIC_READ | GENERIC_WRITE, NULL ))) return;
-    if ((fd_in = dup(obj->ops->get_fd( obj ))) == -1)
+    if (!(obj_in = get_handle_obj( current->process, req->handle_in, GENERIC_READ, NULL )))
+        return;
+    if ((fd_in = dup(obj_in->ops->get_fd( obj_in ))) == -1)
     {
-        release_object( obj );
+        release_object( obj_in );
         return;
     }
-    fd_out = dup( fd_in );
-    release_object( obj );
-    if (fd_out != -1)
+    release_object( obj_in );
+
+    if (!(obj_out = get_handle_obj( current->process, req->handle_out, GENERIC_WRITE, NULL )))
+    {
+        close( fd_in );
+        return;
+    }
+    if ((fd_out = dup(obj_out->ops->get_fd( obj_out ))) == -1)
+    {
+        release_object( obj_out );
+        close( fd_in );
+        return;
+    }
+    release_object( obj_out );
+
+    if (!set_console_fd( req->handle, fd_in, fd_out, req->pid ))
     {
-        if (set_console_fd( req->handle, fd_in, fd_out, req->pid )) return;
         close( fd_out );
+        close( fd_in );
     }
-    close( fd_in );
 }
 
 /* get a console mode (input or output) */
diff --git a/server/process.c b/server/process.c
index cd5889c5041..21a50caf338 100644
--- a/server/process.c
+++ b/server/process.c
@@ -222,9 +222,7 @@ static void init_process( int ppid, struct init_process_request *req )
     process->create_flags = info ? info->create_flags : CREATE_NEW_CONSOLE;
 
     /* create the handle table */
-    if (parent && info->inherit_all == 2)  /* HACK! */
-        process->handles = grab_object( parent->handles );
-    else if (parent && info->inherit_all)
+    if (parent && info->inherit_all)
         process->handles = copy_handle_table( process, parent );
     else
         process->handles = alloc_handle_table( process, 0 );
@@ -272,6 +270,7 @@ static void init_process( int ppid, struct init_process_request *req )
         req->cmd_show     = 0;
         set_req_data_size( req, 0 );
     }
+    req->create_flags = process->create_flags;
     req->server_start = server_start_ticks;
  error:
 }
diff --git a/server/trace.c b/server/trace.c
index 66905780fa0..c47b4bad8fc 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -321,6 +321,7 @@ static void dump_init_process_request( const struct init_process_request *req )
 
 static void dump_init_process_reply( const struct init_process_request *req )
 {
+    fprintf( stderr, " create_flags=%d,", req->create_flags );
     fprintf( stderr, " start_flags=%d,", req->start_flags );
     fprintf( stderr, " server_start=%08x,", req->server_start );
     fprintf( stderr, " exe_file=%d,", req->exe_file );
@@ -861,7 +862,8 @@ static void dump_open_console_reply( const struct open_console_request *req )
 static void dump_set_console_fd_request( const struct set_console_fd_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
-    fprintf( stderr, " file_handle=%d,", req->file_handle );
+    fprintf( stderr, " handle_in=%d,", req->handle_in );
+    fprintf( stderr, " handle_out=%d,", req->handle_out );
     fprintf( stderr, " pid=%d", req->pid );
 }
 
diff --git a/win32/console.c b/win32/console.c
index 1bf40e9b6b3..acd4cecfd8c 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -632,8 +632,9 @@ static BOOL CONSOLE_make_complex(HANDLE handle)
         SERVER_START_REQ
         {
             struct set_console_fd_request *req = server_alloc_req( sizeof(*req), 0 );
-            req->handle = handle;
-            req->file_handle = pty_handle;
+            req->handle     = handle;
+            req->handle_in  = pty_handle;
+            req->handle_out = pty_handle;
             req->pid = xpid;
             server_call( REQ_SET_CONSOLE_FD );
         }
-- 
GitLab