[Spice-devel] [PATCHv3 spice-gtk 13/14] channel: add spice_channel_get_error()
Marc-André Lureau
marcandre.lureau at gmail.com
Mon Feb 17 13:35:52 PST 2014
Add a function to retrieve the last GError from a channel, this may be
useful to provide additional error details to the client.
---
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 411ca0e..9f0cf67 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
<SUBSECTION Standard>
SPICE_TYPE_CHANNEL_EVENT
spice_channel_event_get_type
diff --git a/gtk/map-file b/gtk/map-file
index 82a10eb..0067960 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 f38156e..607c0d4 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -136,6 +136,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 1b8ec10..a9c1076 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",
@@ -2220,6 +2224,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)
@@ -2257,15 +2280,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 3dc709a..9d5001a 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 85a1dad..cf9f9d1 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -119,7 +119,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 19057bf..5e76b5f 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -1796,7 +1796,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 = SPICE_SESSION_GET_PRIVATE(session);
SpiceChannelPrivate *c = channel->priv;
@@ -1845,8 +1845,8 @@ GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceC
#endif
if (open_host.error != NULL) {
- g_warning("open host: %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 3e280a0..038d622 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.8.4.2
More information about the Spice-devel
mailing list