From: Eric Pouech epouech@codeweavers.com
Since dcf0bf1f, one could no longer kill a GUI application launched from unix shell (with start.exe /exec) with ctrl-c.
Basically, when a GUI program is run from a unix shell, we must propagate ctrl-c using the unix process group.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/ntdll/loader.c | 2 +- include/wine/condrv.h | 5 +++-- programs/conhost/conhost.c | 2 +- server/console.c | 35 ++++++++++++++++++++--------------- 4 files changed, 25 insertions(+), 19 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index fc2d2ff7a12..29297202784 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3219,7 +3219,7 @@ NTSTATUS WINAPI __wine_ctrl_routine( void *arg ) { DWORD ret = 0;
- if (pCtrlRoutine && NtCurrentTeb()->Peb->ProcessParameters->ConsoleHandle) ret = pCtrlRoutine( arg ); + if (pCtrlRoutine) ret = pCtrlRoutine( arg ); RtlExitUserThread( ret ); }
diff --git a/include/wine/condrv.h b/include/wine/condrv.h index 51534720444..1a5c4f4555b 100644 --- a/include/wine/condrv.h +++ b/include/wine/condrv.h @@ -190,8 +190,9 @@ struct condrv_scroll_params /* IOCTL_CONDRV_CTRL_EVENT params */ struct condrv_ctrl_event { - int event; /* the event to send */ - unsigned int group_id; /* the group to send the event to */ + int event; /* the event to send */ + unsigned int group_id; /* the group to send the event to */ + /* (when from server, target process group: 0 = windows, 1 = unix) */ };
/* Wine specific values for console inheritance (params->ConsoleHandle) */ diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index eb3c574789f..38cfb16dbdb 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -1518,7 +1518,7 @@ NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *recor IO_STATUS_BLOCK io;
ctrl_event.event = event; - ctrl_event.group_id = 0; + ctrl_event.group_id = console->is_unix; NtDeviceIoControlFile( console->server, NULL, NULL, NULL, &io, IOCTL_CONDRV_CTRL_EVENT, &ctrl_event, sizeof(ctrl_event), NULL, 0 ); } diff --git a/server/console.c b/server/console.c index b64283baf4a..87ea6ec1808 100644 --- a/server/console.c +++ b/server/console.c @@ -663,16 +663,22 @@ struct thread *console_get_renderer( struct console *console )
struct console_signal_info { - struct console *console; - process_id_t group; - int signal; + struct console *console; + process_id_t group; + int unix_pgid; + int signal; };
static int propagate_console_signal_cb(struct process *process, void *user) { struct console_signal_info* csi = (struct console_signal_info*)user; + unsigned cmp;
- if (process->console == csi->console && (!csi->group || process->group_id == csi->group)) + if (csi->unix_pgid) + cmp = csi->unix_pgid == getpgid(process->unix_pid) && csi->console->renderer->process != process; + else + cmp = process->console == csi->console && (!csi->group || process->group_id == csi->group); + if (cmp) { /* find a suitable thread to signal */ struct thread *thread; @@ -684,8 +690,8 @@ static int propagate_console_signal_cb(struct process *process, void *user) return FALSE; }
-static void propagate_console_signal( struct console *console, - int sig, process_id_t group_id ) +static void propagate_console_signal( int sig, struct console *console, + process_id_t group_id, int unix_pgid ) { struct console_signal_info csi;
@@ -703,8 +709,9 @@ static void propagate_console_signal( struct console *console, set_error( STATUS_NOT_IMPLEMENTED ); return; } - csi.console = console; - csi.group = group_id; + csi.console = console; + csi.group = group_id; + csi.unix_pgid = unix_pgid;
enum_processes(propagate_console_signal_cb, &csi); } @@ -983,7 +990,7 @@ static void console_ioctl( struct fd *fd, ioctl_code_t code, struct async *async set_error( STATUS_INVALID_PARAMETER ); return; } - propagate_console_signal( console, event->event, group ); + propagate_console_signal( event->event, console, group, 0 ); return; }
@@ -1141,12 +1148,10 @@ static void console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async set_error( STATUS_INVALID_PARAMETER ); return; } - if (!server->console) - { - set_error( STATUS_INVALID_HANDLE ); - return; - } - propagate_console_signal( server->console, event->event, event->group_id ); + if (event->group_id) + propagate_console_signal( event->event, server->console, 0, getpgid(server->console->renderer->process->unix_pid)); + else + propagate_console_signal( event->event, server->console, 0, 0); return; }