1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-03-22 14:39:24 -05:00

handle_{got,sent}data: separate length and error params.

Now we pass an error code in a separate dedicated parameter, instead
of overloading the length parameter so that a negative value means an
error code. This enables length to become unsigned without causing
trouble.
This commit is contained in:
Simon Tatham 2019-02-06 20:36:11 +00:00
parent a742abae27
commit f60fe670ad
5 changed files with 29 additions and 34 deletions

View File

@ -664,9 +664,9 @@ void handle_got_event(HANDLE event)
* EOF, or (nearly equivalently) read error. * EOF, or (nearly equivalently) read error.
*/ */
h->u.i.defunct = true; h->u.i.defunct = true;
h->u.i.gotdata(h, NULL, -h->u.i.readerr); h->u.i.gotdata(h, NULL, 0, h->u.i.readerr);
} else { } else {
backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len); backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len, 0);
handle_throttle(&h->u.i, backlog); handle_throttle(&h->u.i, backlog);
} }
break; break;
@ -686,11 +686,11 @@ void handle_got_event(HANDLE event)
* thread is terminating by now). * thread is terminating by now).
*/ */
h->u.o.defunct = true; h->u.o.defunct = true;
h->u.o.sentdata(h, -h->u.o.writeerr); h->u.o.sentdata(h, 0, h->u.o.writeerr);
} else { } else {
bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten); bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten);
noise_ultralight(NOISE_SOURCE_IOLEN, h->u.o.lenwritten); noise_ultralight(NOISE_SOURCE_IOLEN, h->u.o.lenwritten);
h->u.o.sentdata(h, bufchain_size(&h->u.o.queued_data)); h->u.o.sentdata(h, bufchain_size(&h->u.o.queued_data), 0);
handle_try_output(&h->u.o); handle_try_output(&h->u.o);
} }
break; break;

View File

@ -45,11 +45,11 @@ typedef struct HandleSocket {
Socket sock; Socket sock;
} HandleSocket; } HandleSocket;
static int handle_gotdata(struct handle *h, const void *data, int len) static int handle_gotdata(struct handle *h, const void *data, int len, int err)
{ {
HandleSocket *hs = (HandleSocket *)handle_get_privdata(h); HandleSocket *hs = (HandleSocket *)handle_get_privdata(h);
if (len < 0) { if (err) {
plug_closing(hs->plug, "Read error from handle", 0, 0); plug_closing(hs->plug, "Read error from handle", 0, 0);
return 0; return 0;
} else if (len == 0) { } else if (len == 0) {
@ -79,25 +79,22 @@ static int handle_gotdata(struct handle *h, const void *data, int len)
} }
} }
static int handle_stderr(struct handle *h, const void *data, int len) static int handle_stderr(struct handle *h, const void *data, int len, int err)
{ {
HandleSocket *hs = (HandleSocket *)handle_get_privdata(h); HandleSocket *hs = (HandleSocket *)handle_get_privdata(h);
if (len > 0) if (!err && len > 0)
log_proxy_stderr(hs->plug, &hs->stderrdata, data, len); log_proxy_stderr(hs->plug, &hs->stderrdata, data, len);
return 0; return 0;
} }
static void handle_sentdata(struct handle *h, int new_backlog) static void handle_sentdata(struct handle *h, int new_backlog, int err)
{ {
HandleSocket *hs = (HandleSocket *)handle_get_privdata(h); HandleSocket *hs = (HandleSocket *)handle_get_privdata(h);
if (new_backlog < 0) { if (err) {
/* Special case: this is actually reporting an error writing plug_closing(hs->plug, win_strerror(err), err, 0);
* to the underlying handle, and our input value is the error
* code itself, negated. */
plug_closing(hs->plug, win_strerror(-new_backlog), -new_backlog, 0);
return; return;
} }

View File

@ -205,14 +205,11 @@ char *do_select(SOCKET skt, bool startup)
return NULL; return NULL;
} }
int stdin_gotdata(struct handle *h, const void *data, int len) int stdin_gotdata(struct handle *h, const void *data, int len, int err)
{ {
if (len < 0) { if (err) {
/*
* Special case: report read error.
*/
char buf[4096]; char buf[4096];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -len, 0, FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0,
buf, lenof(buf), NULL); buf, lenof(buf), NULL);
buf[lenof(buf)-1] = '\0'; buf[lenof(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\n') if (buf[strlen(buf)-1] == '\n')
@ -232,14 +229,11 @@ int stdin_gotdata(struct handle *h, const void *data, int len)
return 0; return 0;
} }
void stdouterr_sent(struct handle *h, int new_backlog) void stdouterr_sent(struct handle *h, int new_backlog, int err)
{ {
if (new_backlog < 0) { if (err) {
/*
* Special case: report write error.
*/
char buf[4096]; char buf[4096];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -new_backlog, 0, FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0,
buf, lenof(buf), NULL); buf, lenof(buf), NULL);
buf[lenof(buf)-1] = '\0'; buf[lenof(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\n') if (buf[strlen(buf)-1] == '\n')
@ -248,6 +242,7 @@ void stdouterr_sent(struct handle *h, int new_backlog)
(h == stdout_handle ? "output" : "error"), buf); (h == stdout_handle ? "output" : "error"), buf);
cleanup_exit(0); cleanup_exit(0);
} }
if (backend_connected(backend)) { if (backend_connected(backend)) {
backend_unthrottle(backend, (handle_backlog(stdout_handle) + backend_unthrottle(backend, (handle_backlog(stdout_handle) +
handle_backlog(stderr_handle))); handle_backlog(stderr_handle)));

View File

@ -40,10 +40,11 @@ static void serial_terminate(Serial *serial)
} }
} }
static int serial_gotdata(struct handle *h, const void *data, int len) static int serial_gotdata(
struct handle *h, const void *data, int len, int err)
{ {
Serial *serial = (Serial *)handle_get_privdata(h); Serial *serial = (Serial *)handle_get_privdata(h);
if (len <= 0) { if (err || len == 0) {
const char *error_msg; const char *error_msg;
/* /*
@ -53,7 +54,7 @@ static int serial_gotdata(struct handle *h, const void *data, int len)
* pipes or some other non-serial device, in which case EOF * pipes or some other non-serial device, in which case EOF
* may become meaningful here. * may become meaningful here.
*/ */
if (len == 0) if (!err)
error_msg = "End of file reading from serial device"; error_msg = "End of file reading from serial device";
else else
error_msg = "Error reading from serial device"; error_msg = "Error reading from serial device";
@ -66,16 +67,16 @@ static int serial_gotdata(struct handle *h, const void *data, int len)
seat_connection_fatal(serial->seat, "%s", error_msg); seat_connection_fatal(serial->seat, "%s", error_msg);
return 0; /* placate optimiser */ return 0;
} else { } else {
return seat_stdout(serial->seat, data, len); return seat_stdout(serial->seat, data, len);
} }
} }
static void serial_sentdata(struct handle *h, int new_backlog) static void serial_sentdata(struct handle *h, int new_backlog, int err)
{ {
Serial *serial = (Serial *)handle_get_privdata(h); Serial *serial = (Serial *)handle_get_privdata(h);
if (new_backlog < 0) { if (err) {
const char *error_msg = "Error writing to serial device"; const char *error_msg = "Error writing to serial device";
serial_terminate(serial); serial_terminate(serial);

View File

@ -603,8 +603,10 @@ void init_ucs(Conf *, struct unicode_data *);
#define HANDLE_FLAG_IGNOREEOF 2 #define HANDLE_FLAG_IGNOREEOF 2
#define HANDLE_FLAG_UNITBUFFER 4 #define HANDLE_FLAG_UNITBUFFER 4
struct handle; struct handle;
typedef int (*handle_inputfn_t)(struct handle *h, const void *data, int len); typedef int (*handle_inputfn_t)(
typedef void (*handle_outputfn_t)(struct handle *h, int new_backlog); struct handle *h, const void *data, int len, int err);
typedef void (*handle_outputfn_t)(
struct handle *h, int new_backlog, int err);
struct handle *handle_input_new(HANDLE handle, handle_inputfn_t gotdata, struct handle *handle_input_new(HANDLE handle, handle_inputfn_t gotdata,
void *privdata, int flags); void *privdata, int flags);
struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata, struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata,