1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

New Seat method, notify_remote_disconnect.

This notifies the Seat that the entire backend session has finished
and closed its network connection - or rather, that it _might_ have
done, and that the frontend should check backend_connected() if it
wasn't planning to do so already.

The existing Seat implementations haven't needed this: the GUI ones
don't actually need to do anything specific when the network
connection goes away, and the CLI ones deal with it by being in charge
of their own event loop so that they can easily check
backend_connected() at every possible opportunity in any case. But I'm
about to introduce a new Seat implementation that does need to know
this, and doesn't have any other way to get notified of it.
This commit is contained in:
Simon Tatham 2021-05-22 12:47:51 +01:00
parent 62b694affc
commit 0553aec60a
15 changed files with 43 additions and 0 deletions

View File

@ -52,6 +52,7 @@ static void raw_check_close(Raw *raw)
sk_close(raw->s); sk_close(raw->s);
raw->s = NULL; raw->s = NULL;
seat_notify_remote_exit(raw->seat); seat_notify_remote_exit(raw->seat);
seat_notify_remote_disconnect(raw->seat);
} }
} }
} }
@ -68,6 +69,7 @@ static void raw_closing(Plug *plug, const char *error_msg, int error_code,
raw->s = NULL; raw->s = NULL;
raw->closed_on_socket_error = true; raw->closed_on_socket_error = true;
seat_notify_remote_exit(raw->seat); seat_notify_remote_exit(raw->seat);
seat_notify_remote_disconnect(raw->seat);
} }
logevent(raw->logctx, error_msg); logevent(raw->logctx, error_msg);
seat_connection_fatal(raw->seat, "%s", error_msg); seat_connection_fatal(raw->seat, "%s", error_msg);

View File

@ -63,6 +63,7 @@ static void rlogin_closing(Plug *plug, const char *error_msg, int error_code,
if (error_msg) if (error_msg)
rlogin->closed_on_socket_error = true; rlogin->closed_on_socket_error = true;
seat_notify_remote_exit(rlogin->seat); seat_notify_remote_exit(rlogin->seat);
seat_notify_remote_disconnect(rlogin->seat);
} }
if (error_msg) { if (error_msg) {
/* A socket error has occurred. */ /* A socket error has occurred. */

View File

@ -581,6 +581,7 @@ static void supdup_closing(Plug *plug, const char *error_msg, int error_code,
if (error_msg) if (error_msg)
supdup->closed_on_socket_error = true; supdup->closed_on_socket_error = true;
seat_notify_remote_exit(supdup->seat); seat_notify_remote_exit(supdup->seat);
seat_notify_remote_disconnect(supdup->seat);
} }
if (error_msg) { if (error_msg) {
logevent(supdup->logctx, error_msg); logevent(supdup->logctx, error_msg);

View File

@ -639,6 +639,7 @@ static void telnet_closing(Plug *plug, const char *error_msg, int error_code,
if (error_msg) if (error_msg)
telnet->closed_on_socket_error = true; telnet->closed_on_socket_error = true;
seat_notify_remote_exit(telnet->seat); seat_notify_remote_exit(telnet->seat);
seat_notify_remote_disconnect(telnet->seat);
} }
if (error_msg) { if (error_msg) {
logevent(telnet->logctx, error_msg); logevent(telnet->logctx, error_msg);

1
pscp.c
View File

@ -67,6 +67,7 @@ static const SeatVtable pscp_seat_vt = {
.eof = pscp_eof, .eof = pscp_eof,
.get_userpass_input = filexfer_get_userpass_input, .get_userpass_input = filexfer_get_userpass_input,
.notify_remote_exit = nullseat_notify_remote_exit, .notify_remote_exit = nullseat_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = console_connection_fatal, .connection_fatal = console_connection_fatal,
.update_specials_menu = nullseat_update_specials_menu, .update_specials_menu = nullseat_update_specials_menu,
.get_ttymode = nullseat_get_ttymode, .get_ttymode = nullseat_get_ttymode,

View File

@ -49,6 +49,7 @@ static const SeatVtable psftp_seat_vt = {
.eof = psftp_eof, .eof = psftp_eof,
.get_userpass_input = filexfer_get_userpass_input, .get_userpass_input = filexfer_get_userpass_input,
.notify_remote_exit = nullseat_notify_remote_exit, .notify_remote_exit = nullseat_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = console_connection_fatal, .connection_fatal = console_connection_fatal,
.update_specials_menu = nullseat_update_specials_menu, .update_specials_menu = nullseat_update_specials_menu,
.get_ttymode = nullseat_get_ttymode, .get_ttymode = nullseat_get_ttymode,

26
putty.h
View File

@ -924,6 +924,29 @@ struct SeatVtable {
*/ */
void (*notify_remote_exit)(Seat *seat); void (*notify_remote_exit)(Seat *seat);
/*
* Notify the seat that the whole connection has finished.
* (Distinct from notify_remote_exit, e.g. in the case where you
* have port forwardings still active when the main foreground
* session goes away: then you'd get notify_remote_exit when the
* foreground session dies, but notify_remote_disconnect when the
* last forwarding vanishes and the network connection actually
* closes.)
*
* This function might be called multiple times by accident; seats
* should be prepared to cope.
*
* More precisely: this function notifies the seat that
* backend_connected() might now return false where previously it
* returned true. (Note the 'might': an accidental duplicate call
* might happen when backend_connected() was already returning
* false. Or even, in weird situations, when it hadn't stopped
* returning true yet. The point is, when you get this
* notification, all it's really telling you is that it's worth
* _checking_ backend_connected, if you weren't already.)
*/
void (*notify_remote_disconnect)(Seat *seat);
/* /*
* Notify the seat that the connection has suffered a fatal error. * Notify the seat that the connection has suffered a fatal error.
*/ */
@ -1095,6 +1118,8 @@ static inline int seat_get_userpass_input(
{ return seat->vt->get_userpass_input(seat, p, input); } { return seat->vt->get_userpass_input(seat, p, input); }
static inline void seat_notify_remote_exit(Seat *seat) static inline void seat_notify_remote_exit(Seat *seat)
{ seat->vt->notify_remote_exit(seat); } { seat->vt->notify_remote_exit(seat); }
static inline void seat_notify_remote_disconnect(Seat *seat)
{ seat->vt->notify_remote_disconnect(seat); }
static inline void seat_update_specials_menu(Seat *seat) static inline void seat_update_specials_menu(Seat *seat)
{ seat->vt->update_specials_menu(seat); } { seat->vt->update_specials_menu(seat); }
static inline char *seat_get_ttymode(Seat *seat, const char *mode) static inline char *seat_get_ttymode(Seat *seat, const char *mode)
@ -1163,6 +1188,7 @@ size_t nullseat_output(
bool nullseat_eof(Seat *seat); bool nullseat_eof(Seat *seat);
int nullseat_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input); int nullseat_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input);
void nullseat_notify_remote_exit(Seat *seat); void nullseat_notify_remote_exit(Seat *seat);
void nullseat_notify_remote_disconnect(Seat *seat);
void nullseat_connection_fatal(Seat *seat, const char *message); void nullseat_connection_fatal(Seat *seat, const char *message);
void nullseat_update_specials_menu(Seat *seat); void nullseat_update_specials_menu(Seat *seat);
char *nullseat_get_ttymode(Seat *seat, const char *mode); char *nullseat_get_ttymode(Seat *seat, const char *mode);

View File

@ -109,6 +109,7 @@ static const SeatVtable server_seat_vt = {
.eof = nullseat_eof, .eof = nullseat_eof,
.get_userpass_input = nullseat_get_userpass_input, .get_userpass_input = nullseat_get_userpass_input,
.notify_remote_exit = nullseat_notify_remote_exit, .notify_remote_exit = nullseat_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = nullseat_connection_fatal, .connection_fatal = nullseat_connection_fatal,
.update_specials_menu = nullseat_update_specials_menu, .update_specials_menu = nullseat_update_specials_menu,
.get_ttymode = nullseat_get_ttymode, .get_ttymode = nullseat_get_ttymode,

View File

@ -188,6 +188,7 @@ static const SeatVtable sesschan_seat_vt = {
.eof = sesschan_seat_eof, .eof = sesschan_seat_eof,
.get_userpass_input = nullseat_get_userpass_input, .get_userpass_input = nullseat_get_userpass_input,
.notify_remote_exit = sesschan_notify_remote_exit, .notify_remote_exit = sesschan_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = sesschan_connection_fatal, .connection_fatal = sesschan_connection_fatal,
.update_specials_menu = nullseat_update_specials_menu, .update_specials_menu = nullseat_update_specials_menu,
.get_ttymode = nullseat_get_ttymode, .get_ttymode = nullseat_get_ttymode,

View File

@ -387,6 +387,7 @@ static void ssh_bpp_output_raw_data_callback(void *vctx)
if (ssh->pending_close) { if (ssh->pending_close) {
sk_close(ssh->s); sk_close(ssh->s);
ssh->s = NULL; ssh->s = NULL;
seat_notify_remote_disconnect(ssh->seat);
} }
} }
@ -428,6 +429,7 @@ static void ssh_shutdown(Ssh *ssh)
if (ssh->s) { if (ssh->s) {
sk_close(ssh->s); sk_close(ssh->s);
ssh->s = NULL; ssh->s = NULL;
seat_notify_remote_disconnect(ssh->seat);
} }
bufchain_clear(&ssh->in_raw); bufchain_clear(&ssh->in_raw);
@ -788,6 +790,7 @@ static char *connect_to_host(
if ((err = sk_socket_error(ssh->s)) != NULL) { if ((err = sk_socket_error(ssh->s)) != NULL) {
ssh->s = NULL; ssh->s = NULL;
seat_notify_remote_exit(ssh->seat); seat_notify_remote_exit(ssh->seat);
seat_notify_remote_disconnect(ssh->seat);
return dupstr(err); return dupstr(err);
} }
} }

View File

@ -391,6 +391,7 @@ static const SeatVtable plink_seat_vt = {
.eof = plink_eof, .eof = plink_eof,
.get_userpass_input = plink_get_userpass_input, .get_userpass_input = plink_get_userpass_input,
.notify_remote_exit = nullseat_notify_remote_exit, .notify_remote_exit = nullseat_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = console_connection_fatal, .connection_fatal = console_connection_fatal,
.update_specials_menu = nullseat_update_specials_menu, .update_specials_menu = nullseat_update_specials_menu,
.get_ttymode = plink_get_ttymode, .get_ttymode = plink_get_ttymode,

View File

@ -391,6 +391,7 @@ static const SeatVtable gtk_seat_vt = {
.eof = gtk_seat_eof, .eof = gtk_seat_eof,
.get_userpass_input = gtk_seat_get_userpass_input, .get_userpass_input = gtk_seat_get_userpass_input,
.notify_remote_exit = gtk_seat_notify_remote_exit, .notify_remote_exit = gtk_seat_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = gtk_seat_connection_fatal, .connection_fatal = gtk_seat_connection_fatal,
.update_specials_menu = gtk_seat_update_specials_menu, .update_specials_menu = gtk_seat_update_specials_menu,
.get_ttymode = gtk_seat_get_ttymode, .get_ttymode = gtk_seat_get_ttymode,

View File

@ -10,6 +10,7 @@ bool nullseat_eof(Seat *seat) { return true; }
int nullseat_get_userpass_input( int nullseat_get_userpass_input(
Seat *seat, prompts_t *p, bufchain *input) { return 0; } Seat *seat, prompts_t *p, bufchain *input) { return 0; }
void nullseat_notify_remote_exit(Seat *seat) {} void nullseat_notify_remote_exit(Seat *seat) {}
void nullseat_notify_remote_disconnect(Seat *seat) {}
void nullseat_connection_fatal(Seat *seat, const char *message) {} void nullseat_connection_fatal(Seat *seat, const char *message) {}
void nullseat_update_specials_menu(Seat *seat) {} void nullseat_update_specials_menu(Seat *seat) {}
char *nullseat_get_ttymode(Seat *seat, const char *mode) { return NULL; } char *nullseat_get_ttymode(Seat *seat, const char *mode) { return NULL; }

View File

@ -85,6 +85,7 @@ static const SeatVtable plink_seat_vt = {
.eof = plink_eof, .eof = plink_eof,
.get_userpass_input = plink_get_userpass_input, .get_userpass_input = plink_get_userpass_input,
.notify_remote_exit = nullseat_notify_remote_exit, .notify_remote_exit = nullseat_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = console_connection_fatal, .connection_fatal = console_connection_fatal,
.update_specials_menu = nullseat_update_specials_menu, .update_specials_menu = nullseat_update_specials_menu,
.get_ttymode = nullseat_get_ttymode, .get_ttymode = nullseat_get_ttymode,

View File

@ -332,6 +332,7 @@ static const SeatVtable win_seat_vt = {
.eof = win_seat_eof, .eof = win_seat_eof,
.get_userpass_input = win_seat_get_userpass_input, .get_userpass_input = win_seat_get_userpass_input,
.notify_remote_exit = win_seat_notify_remote_exit, .notify_remote_exit = win_seat_notify_remote_exit,
.notify_remote_disconnect = nullseat_notify_remote_disconnect,
.connection_fatal = win_seat_connection_fatal, .connection_fatal = win_seat_connection_fatal,
.update_specials_menu = win_seat_update_specials_menu, .update_specials_menu = win_seat_update_specials_menu,
.get_ttymode = win_seat_get_ttymode, .get_ttymode = win_seat_get_ttymode,