From b8a51419ef55eba354a49e05cd90d934b878bbaf Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 19 May 2022 17:44:39 +0100 Subject: [PATCH] Move contents of win_seat_notify_remote_exit into a callback. This matches the way it's done in the GTK backend: the only thing that happens inside seat_notify_remote_exit is that we schedule a toplevel callback, and all the real work happens later on when that callback is called. The particular situation where this makes a difference is if you perform a user abort during proxy authentication (e.g. hit ^D at a proxy password prompt), so that the main SSH backend gets PLUGCLOSE_USER_ABORT and calls ssh_user_close. That doesn't immediately close the socket; it just sets ssh->pending_close, schedules a run of ssh_bpp_output_raw_data_callback, and returns. So if seat_notify_remote_exit calls back _synchronously_ to ssh_return_exitcode, it will see that the socket is still open and return -1. But if it schedules a callback and waits, then the callback to ssh_bpp_output_raw_data_callback will happen first, which will close the socket, and then the exit processing will get the right answer. So the user-visible effect is that if you ^D a proxy auth prompt, GTK PuTTY will close the whole window (assuming you didn't set close-on- exit to 'never'), whereas Windows PuTTY will leave the window open, and not even know that the connection is now shut (in that it'll still ask 'Are you sure you want to close this session?' if you try to close it by hand). With this fix, Windows PuTTY behaves the same as GTK in this respect. --- windows/window.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/windows/window.c b/windows/window.c index 5a70098c..4b1e4f05 100644 --- a/windows/window.c +++ b/windows/window.c @@ -2106,7 +2106,7 @@ static bool is_alt_pressed(void) static bool resizing; -static void win_seat_notify_remote_exit(Seat *seat) +static void exit_callback(void *vctx) { int exitcode, close_on_exit; @@ -2133,6 +2133,11 @@ static void win_seat_notify_remote_exit(Seat *seat) } } +static void win_seat_notify_remote_exit(Seat *seat) +{ + queue_toplevel_callback(exit_callback, NULL); +} + void timer_change_notify(unsigned long next) { unsigned long now = GETTICKCOUNT();