diff --git a/network.h b/network.h index b432ccae..f390a5d0 100644 --- a/network.h +++ b/network.h @@ -190,12 +190,6 @@ const char *sk_addr_error(SockAddr addr); */ #define sk_set_frozen(s, is_frozen) (((*s)->set_frozen) (s, is_frozen)) -/* - * Call this after an operation that might have tried to send on a - * socket, to clean up any pending network errors. - */ -void net_pending_errors(void); - /* * Simple wrapper on getservbyname(), needed by ssh.c. Returns the * port number, in host byte order (suitable for printf and so on). diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 7bc41cc9..59a5c383 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -2843,24 +2843,6 @@ void uxsel_input_remove(int id) { gdk_input_remove(id); } -int frontend_net_pending_error_idle_id; -int frontend_got_net_pending_errors = FALSE; -gboolean frontend_net_pending_errors(gpointer data) -{ - net_pending_errors(); - gtk_idle_remove(frontend_net_pending_error_idle_id); - frontend_got_net_pending_errors = FALSE; - return FALSE; -} -void frontend_net_error_pending(void) -{ - if (!frontend_got_net_pending_errors) { - frontend_got_net_pending_errors = TRUE; - frontend_net_pending_error_idle_id = - gtk_idle_add(frontend_net_pending_errors, NULL); - } -} - char *setup_fonts_ucs(struct gui_data *inst) { int shadowbold = conf_get_int(inst->conf, CONF_shadowbold); diff --git a/unix/unix.h b/unix/unix.h index a9f00bf2..c2f9aeb1 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -173,13 +173,6 @@ int init_ucs(struct unicode_data *ucsdata, char *line_codepage, */ void *sk_getxdmdata(void *sock, int *lenp); -/* - * Function provided by front ends, and called by uxnet.c to indicate - * that net_pending_errors() would like to be called back when the - * front end has a spare moment and isn't deep in any other recursion. - */ -void frontend_net_error_pending(void); - /* * General helpful Unix stuff: more helpful version of the FD_SET * macro, which also handles maxfd. diff --git a/unix/uxnet.c b/unix/uxnet.c index d8460c19..9fc649f7 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -1025,6 +1025,26 @@ void *sk_getxdmdata(void *sock, int *lenp) return buf; } +/* + * Deal with socket errors detected in try_send(). + */ +static void socket_error_callback(void *vs) +{ + Actual_Socket s = (Actual_Socket)vs; + + /* + * Just in case other socket work has caused this socket to vanish + * or become somehow non-erroneous before this callback arrived... + */ + if (!find234(sktree, s, NULL) || !s->pending_error) + return; + + /* + * An error has occurred on this socket. Pass it to the plug. + */ + plug_closing(s->plug, strerror(s->pending_error), s->pending_error, 0); +} + /* * The function which tries to send on a socket once it's deemed * writable. @@ -1073,9 +1093,10 @@ void try_send(Actual_Socket s) */ uxsel_tell(s); /* - * Notify the front end that it might want to call us. + * Arrange to be called back from the top level to + * deal with the error condition on this socket. */ - frontend_net_error_pending(); + queue_toplevel_callback(socket_error_callback, s); return; } } else { @@ -1352,43 +1373,6 @@ static int net_select_result(int fd, int event) return 1; } -/* - * Deal with socket errors detected in try_send(). - */ -void net_pending_errors(void) -{ - int i; - Actual_Socket s; - - /* - * This might be a fiddly business, because it's just possible - * that handling a pending error on one socket might cause - * others to be closed. (I can't think of any reason this might - * happen in current SSH implementation, but to maintain - * generality of this network layer I'll assume the worst.) - * - * So what we'll do is search the socket list for _one_ socket - * with a pending error, and then handle it, and then search - * the list again _from the beginning_. Repeat until we make a - * pass with no socket errors present. That way we are - * protected against the socket list changing under our feet. - */ - - do { - for (i = 0; (s = index234(sktree, i)) != NULL; i++) { - if (s->pending_error) { - /* - * An error has occurred on this socket. Pass it to the - * plug. - */ - plug_closing(s->plug, strerror(s->pending_error), - s->pending_error, 0); - break; - } - } - } while (s); -} - /* * Each socket abstraction contains a `void *' private field in * which the client can keep state. diff --git a/unix/uxplink.c b/unix/uxplink.c index 36f3e2fc..85f91224 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -1116,8 +1116,6 @@ int main(int argc, char **argv) back->unthrottle(backhandle, try_output(TRUE)); } - net_pending_errors(); - run_toplevel_callbacks(); if ((!connopen || !back->connected(backhandle)) && diff --git a/unix/uxpterm.c b/unix/uxpterm.c index 6542fbba..1f4f20c2 100644 --- a/unix/uxpterm.c +++ b/unix/uxpterm.c @@ -17,16 +17,6 @@ Backend *select_backend(Conf *conf) return &pty_backend; } -void net_pending_errors(void) -{ - /* - * Stub version of net_pending_errors(), because gtkwin.c has to - * be prepared to call it when linked into PuTTY and therefore we - * have to avoid a link failure when linking gtkwin.c in turn into - * a non-networked application. - */ -} - int cfgbox(Conf *conf) { /* diff --git a/windows/window.c b/windows/window.c index 77e4e9eb..b5a18e5a 100644 --- a/windows/window.c +++ b/windows/window.c @@ -874,8 +874,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) if (pending_netevent) enact_pending_netevent(); - - net_pending_errors(); } finished: @@ -2349,7 +2347,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, InvalidateRect(hwnd, NULL, TRUE); reset_window(init_lvl); - net_pending_errors(); conf_free(prev_conf); } @@ -2412,7 +2409,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, break; if (back) back->special(backhandle, specials[i].code); - net_pending_errors(); } } break; @@ -2705,7 +2701,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, if (WSAGETSELECTEVENT(lParam) != FD_READ) enact_pending_netevent(); - net_pending_errors(); return 0; case WM_SETFOCUS: term_set_focus(term, TRUE); @@ -3087,7 +3082,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, } } } - net_pending_errors(); return 0; case WM_INPUTLANGCHANGE: /* wParam == Font number */ diff --git a/windows/winnet.c b/windows/winnet.c index 4fddd72c..00a8290d 100644 --- a/windows/winnet.c +++ b/windows/winnet.c @@ -1345,6 +1345,26 @@ static void sk_tcp_close(Socket sock) sfree(s); } +/* + * Deal with socket errors detected in try_send(). + */ +static void socket_error_callback(void *vs) +{ + Actual_Socket s = (Actual_Socket)vs; + + /* + * Just in case other socket work has caused this socket to vanish + * or become somehow non-erroneous before this callback arrived... + */ + if (!find234(sktree, s, NULL) || !s->pending_error) + return; + + /* + * An error has occurred on this socket. Pass it to the plug. + */ + plug_closing(s->plug, strerror(s->pending_error), s->pending_error, 0); +} + /* * The function which tries to send on a socket once it's deemed * writable. @@ -1394,6 +1414,7 @@ void try_send(Actual_Socket s) * plug_closing()) at some suitable future moment. */ s->pending_error = err; + queue_toplevel_callback(socket_error_callback, s); return; } else { /* We're inside the Windows frontend here, so we know @@ -1666,44 +1687,6 @@ int select_result(WPARAM wParam, LPARAM lParam) return 1; } -/* - * Deal with socket errors detected in try_send(). - */ -void net_pending_errors(void) -{ - int i; - Actual_Socket s; - - /* - * This might be a fiddly business, because it's just possible - * that handling a pending error on one socket might cause - * others to be closed. (I can't think of any reason this might - * happen in current SSH implementation, but to maintain - * generality of this network layer I'll assume the worst.) - * - * So what we'll do is search the socket list for _one_ socket - * with a pending error, and then handle it, and then search - * the list again _from the beginning_. Repeat until we make a - * pass with no socket errors present. That way we are - * protected against the socket list changing under our feet. - */ - - do { - for (i = 0; (s = index234(sktree, i)) != NULL; i++) { - if (s->pending_error) { - /* - * An error has occurred on this socket. Pass it to the - * plug. - */ - plug_closing(s->plug, - winsock_error_string(s->pending_error), - s->pending_error, 0); - break; - } - } - } while (s); -} - /* * Each socket abstraction contains a `void *' private field in * which the client can keep state.