From 96b720b3fd7ef33da4898dbe00101cfbf9164e24 Mon Sep 17 00:00:00 2001 From: simon Date: Sat, 22 Dec 2012 09:40:47 +0000 Subject: [PATCH] Ronald Landheer-Cieslak points out that the various back ends which treat all socket closures as clean exits (because the protocol doesn't provide for transferring a process exit code) could usefully at least treat _socket errors_ as unclean exits. Patch the Telnet, Rlogin and Raw backends to retain that information and return INT_MAX to the frontend. I wasn't sure whether it was better to solve this by modifying each affected frontend, or each affected backend. Neither is really ideal; this is the sort of thing that makes me wish we had a piece of fixed middleware in between, independent of both platform and protocol. git-svn-id: svn://svn.tartarus.org/sgt/putty@9730 cda61777-01e9-0310-a592-d414129be87e --- raw.c | 6 ++++++ rlogin.c | 7 +++++++ telnet.c | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/raw.c b/raw.c index 5bf63564..698d7e4f 100644 --- a/raw.c +++ b/raw.c @@ -4,6 +4,7 @@ #include #include +#include #include "putty.h" @@ -21,6 +22,7 @@ typedef struct raw_backend_data { /* the above field _must_ be first in the structure */ Socket s; + int closed_on_socket_error; int bufsize; void *frontend; int sent_console_eof, sent_socket_eof; @@ -75,6 +77,7 @@ static int raw_closing(Plug plug, const char *error_msg, int error_code, if (raw->s) { sk_close(raw->s); raw->s = NULL; + raw->closed_on_socket_error = TRUE; notify_remote_exit(raw->frontend); } logevent(raw->frontend, error_msg); @@ -139,6 +142,7 @@ static const char *raw_init(void *frontend_handle, void **backend_handle, raw = snew(struct raw_backend_data); raw->fn = &fn_table; raw->s = NULL; + raw->closed_on_socket_error = FALSE; *backend_handle = raw; raw->sent_console_eof = raw->sent_socket_eof = FALSE; @@ -306,6 +310,8 @@ static int raw_exitcode(void *handle) Raw raw = (Raw) handle; if (raw->s != NULL) return -1; /* still connected */ + else if (raw->closed_on_socket_error) + return INT_MAX; /* a socket error counts as an unclean exit */ else /* Exit codes are a meaningless concept in the Raw protocol */ return 0; diff --git a/rlogin.c b/rlogin.c index fecc9d4b..faf3daf9 100644 --- a/rlogin.c +++ b/rlogin.c @@ -4,6 +4,7 @@ #include #include +#include #include #include "putty.h" @@ -22,6 +23,7 @@ typedef struct rlogin_tag { /* the above field _must_ be first in the structure */ Socket s; + int closed_on_socket_error; int bufsize; int firstbyte; int cansize; @@ -72,6 +74,8 @@ static int rlogin_closing(Plug plug, const char *error_msg, int error_code, if (rlogin->s) { sk_close(rlogin->s); rlogin->s = NULL; + if (error_msg) + rlogin->closed_on_socket_error = TRUE; notify_remote_exit(rlogin->frontend); } if (error_msg) { @@ -175,6 +179,7 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle, rlogin = snew(struct rlogin_tag); rlogin->fn = &fn_table; rlogin->s = NULL; + rlogin->closed_on_socket_error = FALSE; rlogin->frontend = frontend_handle; rlogin->term_width = conf_get_int(conf, CONF_width); rlogin->term_height = conf_get_int(conf, CONF_height); @@ -392,6 +397,8 @@ static int rlogin_exitcode(void *handle) Rlogin rlogin = (Rlogin) handle; if (rlogin->s != NULL) return -1; /* still connected */ + else if (rlogin->closed_on_socket_error) + return INT_MAX; /* a socket error counts as an unclean exit */ else /* If we ever implement RSH, we'll probably need to do this properly */ return 0; diff --git a/telnet.c b/telnet.c index dc98a727..3536414c 100644 --- a/telnet.c +++ b/telnet.c @@ -4,6 +4,7 @@ #include #include +#include #include "putty.h" @@ -181,6 +182,7 @@ typedef struct telnet_tag { /* the above field _must_ be first in the structure */ Socket s; + int closed_on_socket_error; void *frontend; void *ldisc; @@ -676,6 +678,8 @@ static int telnet_closing(Plug plug, const char *error_msg, int error_code, if (telnet->s) { sk_close(telnet->s); telnet->s = NULL; + if (error_msg) + telnet->closed_on_socket_error = TRUE; notify_remote_exit(telnet->frontend); } if (error_msg) { @@ -729,6 +733,7 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle, telnet->fn = &fn_table; telnet->conf = conf_copy(conf); telnet->s = NULL; + telnet->closed_on_socket_error = FALSE; telnet->echoing = TRUE; telnet->editing = TRUE; telnet->activated = FALSE; @@ -1096,6 +1101,8 @@ static int telnet_exitcode(void *handle) Telnet telnet = (Telnet) handle; if (telnet->s != NULL) return -1; /* still connected */ + else if (telnet->closed_on_socket_error) + return INT_MAX; /* a socket error counts as an unclean exit */ else /* Telnet doesn't transmit exit codes back to the client */ return 0; -- 2.11.0