From a4bc5a2138655409e28036c7110451fdf94c9403 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard 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 | 34 +++++++++++++++++++++++----------- server/process.c | 5 ++--- server/trace.c | 4 +++- win32/console.c | 5 +++-- 6 files changed, 68 insertions(+), 22 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 ))) { - if (set_console_fd( req->handle, fd_in, fd_out, req->pid )) return; - close( fd_out ); + 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 )) + { + 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 ); }