X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=unix%2Fuxnet.c;h=9fc649f75d6392a7f3451cba1b089c6f96074058;hb=1472aa2a265dfbfe7225729862ea21b5fb2da22f;hp=02894bd9ab8e683842365fd8800f9a8c07c82594;hpb=b4268722196a3d93183252584b86cbb719187a38;p=PuTTY.git diff --git a/unix/uxnet.c b/unix/uxnet.c index 02894bd9..9fc649f7 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -80,8 +80,6 @@ struct Socket_tag { int connected; /* irrelevant for listening sockets */ int writable; int frozen; /* this causes readability notifications to be ignored */ - int frozen_readable; /* this means we missed at least one readability - * notification while we were frozen */ int localhost_only; /* for listening sockets */ char oobdata[1]; int sending_oob; @@ -343,7 +341,7 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen) } } -int sk_hostname_is_local(char *name) +int sk_hostname_is_local(const char *name) { return !strcmp(name, "localhost") || !strcmp(name, "::1") || @@ -507,7 +505,6 @@ Socket sk_register(OSSocket sockfd, Plug plug) ret->writable = 1; /* to start with */ ret->sending_oob = 0; ret->frozen = 1; - ret->frozen_readable = 0; ret->localhost_only = 0; /* unused, but best init anyway */ ret->pending_error = 0; ret->oobpending = FALSE; @@ -743,7 +740,6 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, ret->writable = 0; /* to start with */ ret->sending_oob = 0; ret->frozen = 0; - ret->frozen_readable = 0; ret->localhost_only = 0; /* unused, but best init anyway */ ret->pending_error = 0; ret->parent = ret->child = NULL; @@ -797,7 +793,6 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, i ret->writable = 0; /* to start with */ ret->sending_oob = 0; ret->frozen = 0; - ret->frozen_readable = 0; ret->localhost_only = local_host_only; ret->pending_error = 0; ret->parent = ret->child = NULL; @@ -1030,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. @@ -1078,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 { @@ -1277,10 +1293,8 @@ static int net_select_result(int fd, int event) */ /* In the case the socket is still frozen, we don't even bother */ - if (s->frozen) { - s->frozen_readable = 1; + if (s->frozen) break; - } /* * We have received data on the socket. For an oobinline @@ -1359,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. @@ -1433,11 +1410,6 @@ static void sk_tcp_set_frozen(Socket sock, int is_frozen) if (s->frozen == is_frozen) return; s->frozen = is_frozen; - if (!is_frozen && s->frozen_readable) { - char c; - recv(s->s, &c, 1, MSG_PEEK); - } - s->frozen_readable = 0; uxsel_tell(s); }