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);
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.
*/
* 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 {
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);
}
exit(1);
}
+void frontend_net_error_pending(void) {}
+
int main(int argc, char **argv)
{
int sending;
back->unthrottle(backhandle, try_output(TRUE));
}
+ net_pending_errors();
+
if ((!connopen || !back->connected(backhandle)) &&
bufchain_size(&stdout_data) == 0 &&
bufchain_size(&stderr_data) == 0)
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)
{
/*
}
}
+void frontend_net_error_pending(void) {}
+
/*
* Main program: do platform-specific initialisation and then call
* psftp_main().