Module: wine Branch: master Commit: 52f6a56a1aa450c893e19a0e63a90c60626d3dcf URL: https://source.winehq.org/git/wine.git/?a=commit;h=52f6a56a1aa450c893e19a0e6...
Author: Jacek Caban jacek@codeweavers.com Date: Mon Sep 21 17:06:26 2020 +0200
server: Introduce IOCTL_CONDRV_SETUP_INPUT ioctl.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
include/wine/condrv.h | 5 ++++- server/console.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ server/trace.c | 1 + 3 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/include/wine/condrv.h b/include/wine/condrv.h index e5ba9c7444..b82531280b 100644 --- a/include/wine/condrv.h +++ b/include/wine/condrv.h @@ -50,7 +50,10 @@ #define IOCTL_CONDRV_SCROLL CTL_CODE(FILE_DEVICE_CONSOLE, 37, METHOD_BUFFERED, FILE_WRITE_ACCESS)
/* console connection ioctls */ -#define IOCTL_CONDRV_BIND_PID CTL_CODE(FILE_DEVICE_CONSOLE, 51, METHOD_BUFFERED, FILE_READ_PROPERTIES) +#define IOCTL_CONDRV_BIND_PID CTL_CODE(FILE_DEVICE_CONSOLE, 51, METHOD_BUFFERED, FILE_ANY_ACCESS) + +/* console server ioctls */ +#define IOCTL_CONDRV_SETUP_INPUT CTL_CODE(FILE_DEVICE_CONSOLE, 60, METHOD_BUFFERED, FILE_ANY_ACCESS)
/* console renderer ioctls */ #define IOCTL_CONDRV_GET_RENDERER_EVENTS CTL_CODE(FILE_DEVICE_CONSOLE, 70, METHOD_BUFFERED, FILE_READ_ACCESS) diff --git a/server/console.c b/server/console.c index a946abacbb..2a5d7733fe 100644 --- a/server/console.c +++ b/server/console.c @@ -28,6 +28,8 @@ #include <stdio.h> #include <unistd.h> #include <signal.h> +#include <sys/ioctl.h> +#include <termios.h>
#include "ntstatus.h" #define WIN32_NO_STATUS @@ -198,6 +200,8 @@ struct console_server struct list queue; /* ioctl queue */ struct list read_queue; /* blocking read queue */ int busy; /* flag if server processing an ioctl */ + int term_fd; /* UNIX terminal fd */ + struct termios termios; /* original termios */ };
static void console_server_dump( struct object *obj, int verbose ); @@ -665,6 +669,13 @@ static void disconnect_console_server( struct console_server *server ) console_host_ioctl_terminate( call, STATUS_CANCELLED ); }
+ if (server->term_fd != -1) + { + tcsetattr( server->term_fd, TCSANOW, &server->termios ); + close( server->term_fd ); + server->term_fd = -1; + } + if (server->console) { assert( server->console->server == server ); @@ -1772,6 +1783,7 @@ static struct object *create_console_server( void ) if (!(server = alloc_object( &console_server_ops ))) return NULL; server->console = NULL; server->busy = 0; + server->term_fd = -1; list_init( &server->queue ); list_init( &server->read_queue ); server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT ); @@ -2337,6 +2349,53 @@ static int console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async return !get_error(); }
+ case IOCTL_CONDRV_SETUP_INPUT: + { + struct termios term; + obj_handle_t handle; + struct file *file; + int unix_fd; + + if (get_req_data_size() != sizeof(unsigned int) || get_reply_max_size()) + { + set_error( STATUS_INVALID_PARAMETER ); + return 0; + } + if (server->term_fd != -1) + { + tcsetattr( server->term_fd, TCSANOW, &server->termios ); + close( server->term_fd ); + server->term_fd = -1; + } + handle = *(unsigned int *)get_req_data(); + if (!handle) return 1; + if (!(file = get_file_obj( current->process, handle, FILE_READ_DATA ))) + { + return 0; + } + unix_fd = get_file_unix_fd( file ); + release_object( file ); + + if (tcgetattr( unix_fd, &server->termios )) + { + file_set_error(); + return 0; + } + term = server->termios; + term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN); + term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + term.c_cflag &= ~(CSIZE | PARENB); + term.c_cflag |= CS8; + term.c_cc[VMIN] = 1; + term.c_cc[VTIME] = 0; + if (tcsetattr( unix_fd, TCSANOW, &term ) || (server->term_fd = dup( unix_fd )) == -1) + { + file_set_error(); + return 0; + } + return 1; + } + default: set_error( STATUS_INVALID_HANDLE ); return 0; diff --git a/server/trace.c b/server/trace.c index 91e3208c49..707a952357 100644 --- a/server/trace.c +++ b/server/trace.c @@ -129,6 +129,7 @@ static void dump_ioctl_code( const char *prefix, const ioctl_code_t *code ) CASE(IOCTL_CONDRV_READ_OUTPUT); CASE(IOCTL_CONDRV_SET_MODE); CASE(IOCTL_CONDRV_SET_OUTPUT_INFO); + CASE(IOCTL_CONDRV_SETUP_INPUT); CASE(IOCTL_CONDRV_WRITE_CONSOLE); CASE(IOCTL_CONDRV_WRITE_INPUT); CASE(IOCTL_CONDRV_WRITE_OUTPUT);