Commit 751a3325 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

server/console: Ensure conhost has created the TTY input stream before waiting.

Some PE executables (like mingw's gdb port) just do something like: - WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), INFINITE) and hang for ever (the read operations are done *after* the wait operation succeeds) (of course, the real wait operation is more complex, but the problematic part boils down to that) This hangs for ever because conhost's main input thread hasn't been started yet. Signed-off-by: 's avatarEric Pouech <eric.pouech@gmail.com> Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 44cb2ba9
...@@ -71,13 +71,14 @@ static struct object *console_lookup_name( struct object *obj, struct unicode_st ...@@ -71,13 +71,14 @@ static struct object *console_lookup_name( struct object *obj, struct unicode_st
unsigned int attr, struct object *root ); unsigned int attr, struct object *root );
static struct object *console_open_file( struct object *obj, unsigned int access, static struct object *console_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options ); unsigned int sharing, unsigned int options );
static int console_add_queue( struct object *obj, struct wait_queue_entry *entry );
static const struct object_ops console_ops = static const struct object_ops console_ops =
{ {
sizeof(struct console), /* size */ sizeof(struct console), /* size */
&file_type, /* type */ &file_type, /* type */
console_dump, /* dump */ console_dump, /* dump */
add_queue, /* add_queue */ console_add_queue, /* add_queue */
remove_queue, /* remove_queue */ remove_queue, /* remove_queue */
console_signaled, /* signaled */ console_signaled, /* signaled */
no_satisfied, /* satisfied */ no_satisfied, /* satisfied */
...@@ -129,14 +130,15 @@ struct console_host_ioctl ...@@ -129,14 +130,15 @@ struct console_host_ioctl
struct console_server struct console_server
{ {
struct object obj; /* object header */ struct object obj; /* object header */
struct fd *fd; /* pseudo-fd for ioctls */ struct fd *fd; /* pseudo-fd for ioctls */
struct console *console; /* attached console */ struct console *console; /* attached console */
struct list queue; /* ioctl queue */ struct list queue; /* ioctl queue */
struct list read_queue; /* blocking read queue */ struct list read_queue; /* blocking read queue */
int busy; /* flag if server processing an ioctl */ unsigned int busy : 1; /* flag if server processing an ioctl */
int term_fd; /* UNIX terminal fd */ unsigned int once_input : 1; /* flag if input thread has already been requested */
struct termios termios; /* original termios */ int term_fd; /* UNIX terminal fd */
struct termios termios; /* original termios */
}; };
static void console_server_dump( struct object *obj, int verbose ); static void console_server_dump( struct object *obj, int verbose );
...@@ -462,6 +464,23 @@ static const struct fd_ops console_connection_fd_ops = ...@@ -462,6 +464,23 @@ static const struct fd_ops console_connection_fd_ops =
static struct list screen_buffer_list = LIST_INIT(screen_buffer_list); static struct list screen_buffer_list = LIST_INIT(screen_buffer_list);
static int queue_host_ioctl( struct console_server *server, unsigned int code, unsigned int output,
struct async *async, struct async_queue *queue );
static int console_add_queue( struct object *obj, struct wait_queue_entry *entry )
{
struct console *console = (struct console*)obj;
assert( obj->ops == &console_ops );
/* before waiting, ensure conhost's input thread has been started */
if (console->server && !console->server->once_input)
{
console->server->once_input = 1;
if (console->server->term_fd == -1)
queue_host_ioctl( console->server, IOCTL_CONDRV_PEEK, 0, NULL, NULL );
}
return add_queue( &console->obj, entry );
}
static int console_signaled( struct object *obj, struct wait_queue_entry *entry ) static int console_signaled( struct object *obj, struct wait_queue_entry *entry )
{ {
struct console *console = (struct console*)obj; struct console *console = (struct console*)obj;
...@@ -889,9 +908,10 @@ static struct object *create_console_server( void ) ...@@ -889,9 +908,10 @@ static struct object *create_console_server( void )
struct console_server *server; struct console_server *server;
if (!(server = alloc_object( &console_server_ops ))) return NULL; if (!(server = alloc_object( &console_server_ops ))) return NULL;
server->console = NULL; server->console = NULL;
server->busy = 0; server->busy = 0;
server->term_fd = -1; server->once_input = 0;
server->term_fd = -1;
list_init( &server->queue ); list_init( &server->queue );
list_init( &server->read_queue ); list_init( &server->read_queue );
server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT ); server->fd = alloc_pseudo_fd( &console_server_fd_ops, &server->obj, FILE_SYNCHRONOUS_IO_NONALERT );
...@@ -1315,7 +1335,7 @@ static int console_input_add_queue( struct object *obj, struct wait_queue_entry ...@@ -1315,7 +1335,7 @@ static int console_input_add_queue( struct object *obj, struct wait_queue_entry
set_error( STATUS_ACCESS_DENIED ); set_error( STATUS_ACCESS_DENIED );
return 0; return 0;
} }
return add_queue( &current->process->console->obj, entry ); return console_add_queue( &current->process->console->obj, entry );
} }
static struct fd *console_input_get_fd( struct object *obj ) static struct fd *console_input_get_fd( struct object *obj )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment