Arrange to call net_pending_errors on Unix, which we've never actually
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 8 Dec 2011 19:15:57 +0000 (19:15 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 8 Dec 2011 19:15:57 +0000 (19:15 +0000)
remembered to do before! Also some related fixes, such as that after
we do so we should immediately stop selecting on the socket in
question.

git-svn-id: svn://svn.tartarus.org/sgt/putty@9363 cda61777-01e9-0310-a592-d414129be87e

unix/gtkwin.c
unix/unix.h
unix/uxnet.c
unix/uxplink.c
unix/uxpterm.c
unix/uxsftp.c

index 334decb..4b8a8dd 100644 (file)
@@ -2725,6 +2725,24 @@ 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);
+    }
+}
+
 void setup_fonts_ucs(struct gui_data *inst)
 {
     int shadowbold = conf_get_int(inst->conf, CONF_shadowbold);
index 37649d5..2ffc356 100644 (file)
@@ -171,6 +171,13 @@ 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.
  */
index 45ea55d..e2302aa 100644 (file)
@@ -1048,6 +1048,16 @@ void try_send(Actual_Socket s)
                 * plug_closing()) at some suitable future moment.
                 */
                s->pending_error = err;
+                /*
+                 * Immediately cease selecting on this socket, so that
+                 * we don't tight-loop repeatedly trying to do
+                 * whatever it was that went wrong.
+                 */
+                uxsel_tell(s);
+                /*
+                 * Notify the front end that it might want to call us.
+                 */
+                frontend_net_error_pending();
                return;
            }
        } else {
@@ -1414,15 +1424,17 @@ static void sk_tcp_set_frozen(Socket sock, int is_frozen)
 static void uxsel_tell(Actual_Socket s)
 {
     int rwx = 0;
-    if (s->listener) {
-       rwx |= 1;                       /* read == accept */
-    } else {
-       if (!s->connected)
-           rwx |= 2;                   /* write == connect */
-       if (s->connected && !s->frozen && !s->incomingeof)
-           rwx |= 1 | 4;               /* read, except */
-       if (bufchain_size(&s->output_data))
-           rwx |= 2;                   /* write */
+    if (!s->pending_error) {
+        if (s->listener) {
+            rwx |= 1;                  /* read == accept */
+        } else {
+            if (!s->connected)
+                rwx |= 2;              /* write == connect */
+            if (s->connected && !s->frozen && !s->incomingeof)
+                rwx |= 1 | 4;          /* read, except */
+            if (bufchain_size(&s->output_data))
+                rwx |= 2;              /* write */
+        }
     }
     uxsel_set(s->s, rwx, net_select_result);
 }
index b3e5679..85f5352 100644 (file)
@@ -585,6 +585,8 @@ static void version(void)
     exit(1);
 }
 
+void frontend_net_error_pending(void) {}
+
 int main(int argc, char **argv)
 {
     int sending;
@@ -1107,6 +1109,8 @@ int main(int argc, char **argv)
            back->unthrottle(backhandle, try_output(TRUE));
        }
 
+        net_pending_errors();
+
        if ((!connopen || !back->connected(backhandle)) &&
            bufchain_size(&stdout_data) == 0 &&
            bufchain_size(&stderr_data) == 0)
index 370527a..c18505b 100644 (file)
@@ -17,6 +17,16 @@ 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)
 {
     /*
index 61847d8..c266fb7 100644 (file)
@@ -605,6 +605,8 @@ char *ssh_sftp_get_cmdline(char *prompt, int no_fds_ok)
     }
 }
 
+void frontend_net_error_pending(void) {}
+
 /*
  * Main program: do platform-specific initialisation and then call
  * psftp_main().