From ba6fe1ef7076e4e6ec6c945aeca63f1092011281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 3 Feb 2014 15:47:11 +0100 Subject: [PATCH] channel: add spice_channel_get_error() Add a function to retrieve the last GError from a channel, this may be useful to provide additional error details to the client. Conflicts: gtk/spice-session.c --- doc/reference/spice-gtk-sections.txt | 1 + gtk/map-file | 1 + gtk/spice-channel-priv.h | 1 + gtk/spice-channel.c | 30 +++++++++++++++++++++++++++--- gtk/spice-channel.h | 2 ++ gtk/spice-glib-sym-file | 1 + gtk/spice-session-priv.h | 2 +- gtk/spice-session.c | 6 +++--- gtk/spicy.c | 6 ++++++ 9 files changed, 43 insertions(+), 7 deletions(-) diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt index 8d61aa9..1aebe58 100644 --- a/doc/reference/spice-gtk-sections.txt +++ b/doc/reference/spice-gtk-sections.txt @@ -102,6 +102,7 @@ spice_channel_string_to_type spice_channel_set_capability spice_channel_flush_async spice_channel_flush_finish +spice_channel_get_error SPICE_TYPE_CHANNEL_EVENT spice_channel_event_get_type diff --git a/gtk/map-file b/gtk/map-file index 368b44f..399fa62 100644 --- a/gtk/map-file +++ b/gtk/map-file @@ -7,6 +7,7 @@ spice_channel_connect; spice_channel_destroy; spice_channel_disconnect; spice_channel_event_get_type; +spice_channel_get_error; spice_channel_get_type; spice_channel_new; spice_channel_open_fd; diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h index 0816061..fef58bf 100644 --- a/gtk/spice-channel-priv.h +++ b/gtk/spice-channel-priv.h @@ -134,6 +134,7 @@ struct _SpiceChannelPrivate { GSList *flushing; gboolean disable_channel_msg; + GError *error; }; SpiceMsgIn *spice_msg_in_new(SpiceChannel *channel); diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c index 9a2b5b4..1a92669 100644 --- a/gtk/spice-channel.c +++ b/gtk/spice-channel.c @@ -154,6 +154,8 @@ static void spice_channel_dispose(GObject *gobject) c->session = NULL; } + g_clear_error(&c->error); + /* Chain up to the parent class */ if (G_OBJECT_CLASS(spice_channel_parent_class)->dispose) G_OBJECT_CLASS(spice_channel_parent_class)->dispose(gobject); @@ -317,7 +319,9 @@ static void spice_channel_class_init(SpiceChannelClass *klass) * @event: a #SpiceChannelEvent * * The #SpiceChannel::channel-event signal is emitted when the - * state of the connection change. + * state of the connection is changed. In case of errors, + * spice_channel_get_error() may provide additional informations + * on the source of the error. **/ signals[SPICE_CHANNEL_EVENT] = g_signal_new("channel-event", @@ -2206,6 +2210,25 @@ static int spice_channel_load_ca(SpiceChannel *channel) return count; } +/** + * spice_channel_get_error: + * @channel: + * + * Retrieves the #GError currently set on channel, if the #SpiceChannel + * is in error state and can provide additional error details. + * + * Returns: the pointer to the error, or %NULL + * Since: 0.24 + **/ +const GError* spice_channel_get_error(SpiceChannel *self) +{ + SpiceChannelPrivate *c; + + g_return_val_if_fail(SPICE_IS_CHANNEL(self), NULL); + c = self->priv; + + return c->error; +} /* coroutine context */ static void *spice_channel_coroutine(void *data) @@ -2241,15 +2264,16 @@ static void *spice_channel_coroutine(void *data) } reconnect: - c->conn = spice_session_channel_open_host(c->session, channel, &c->tls); + c->conn = spice_session_channel_open_host(c->session, channel, &c->tls, &c->error); if (c->conn == NULL) { - if (!c->tls) { + if (!c->error && !c->tls) { CHANNEL_DEBUG(channel, "trying with TLS port"); c->tls = true; /* FIXME: does that really work with provided fd */ goto reconnect; } else { CHANNEL_DEBUG(channel, "Connect error"); emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_CONNECT); + g_clear_error(&c->error); goto cleanup; } } diff --git a/gtk/spice-channel.h b/gtk/spice-channel.h index 705dddf..1c303b4 100644 --- a/gtk/spice-channel.h +++ b/gtk/spice-channel.h @@ -123,6 +123,8 @@ void spice_channel_set_capability(SpiceChannel *channel, guint32 cap); const gchar* spice_channel_type_to_string(gint type); gint spice_channel_string_to_type(const gchar *str); +const GError* spice_channel_get_error(SpiceChannel *channel); + G_END_DECLS #endif /* __SPICE_CLIENT_CHANNEL_H__ */ diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file index 4fc8643..d48ef7f 100644 --- a/gtk/spice-glib-sym-file +++ b/gtk/spice-glib-sym-file @@ -7,6 +7,7 @@ spice_channel_disconnect spice_channel_event_get_type spice_channel_flush_async spice_channel_flush_finish +spice_channel_get_error spice_channel_get_type spice_channel_new spice_channel_open_fd diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h index 55fee47..d127f16 100644 --- a/gtk/spice-session-priv.h +++ b/gtk/spice-session-priv.h @@ -117,7 +117,7 @@ int spice_session_get_connection_id(SpiceSession *session); gboolean spice_session_get_client_provided_socket(SpiceSession *session); GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel, - gboolean *use_tls); + gboolean *use_tls, GError **error); void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel); void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel); void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel); diff --git a/gtk/spice-session.c b/gtk/spice-session.c index b4675d8..4032ebe 100644 --- a/gtk/spice-session.c +++ b/gtk/spice-session.c @@ -1806,7 +1806,7 @@ static gboolean connect_timeout(gpointer data) /* coroutine context */ G_GNUC_INTERNAL GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel, - gboolean *use_tls) + gboolean *use_tls, GError **error) { SpiceSessionPrivate *s = session->priv; SpiceChannelPrivate *c = channel->priv; @@ -1855,8 +1855,8 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC #endif if (open_host.error != NULL) { - g_warning("%s", open_host.error->message); - g_clear_error(&open_host.error); + SPICE_DEBUG("open host: %s", open_host.error->message); + g_propagate_error(error, open_host.error); } else if (open_host.connection != NULL) { GSocket *socket; socket = g_socket_connection_get_socket(open_host.connection); diff --git a/gtk/spicy.c b/gtk/spicy.c index 916d5d0..0da0bb8 100644 --- a/gtk/spicy.c +++ b/gtk/spicy.c @@ -1208,6 +1208,7 @@ static void recent_add(SpiceSession *session) static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event, gpointer data) { + const GError *error = NULL; spice_connection *conn = data; char password[64]; int rc; @@ -1231,7 +1232,12 @@ static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event, case SPICE_CHANNEL_ERROR_TLS: case SPICE_CHANNEL_ERROR_LINK: case SPICE_CHANNEL_ERROR_CONNECT: + error = spice_channel_get_error(channel); g_message("main channel: failed to connect"); + if (error) { + g_message("channel error: %s", error->message); + } + rc = connect_dialog(conn->session); if (rc == 0) { connection_connect(conn); -- 1.9.3