[telepathy-doc/master] Update example to use GIOChannel, release channel at the right time, etc.
Davyd Madeley
davyd at madeley.id.au
Tue Apr 7 08:09:38 PDT 2009
---
docs/examples/glib_salut_ft/example.c | 86 +++++++++++++++++++++------------
1 files changed, 55 insertions(+), 31 deletions(-)
diff --git a/docs/examples/glib_salut_ft/example.c b/docs/examples/glib_salut_ft/example.c
index 4a20454..9690678 100644
--- a/docs/examples/glib_salut_ft/example.c
+++ b/docs/examples/glib_salut_ft/example.c
@@ -23,6 +23,14 @@ static GMainLoop *loop = NULL;
static TpDBusDaemon *bus_daemon = NULL;
static TpConnection *conn = NULL;
+struct ft_state
+{
+ GIOChannel *channel;
+ guint64 offset;
+
+ struct sockaddr_un sa;
+};
+
static void
handle_error (const GError *error)
{
@@ -41,16 +49,38 @@ file_transfer_unix_cb (TpChannel *channel,
gpointer user_data,
GObject *weak_obj)
{
- struct sockaddr_un *sa = (struct sockaddr_un *) user_data;
+ struct ft_state *state = (struct ft_state *) user_data;
handle_error (in_error);
const char *address = g_value_get_string (addressv);
- strncpy (sa->sun_path, address, UNIX_PATH_MAX);
+ strncpy (state->sa.sun_path, address, UNIX_PATH_MAX);
g_print (" > file_transfer_unix_cb (%s)\n", address);
}
+static gboolean
+file_transfer_data_received (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer data)
+{
+ char buf[1024];
+ gsize bytes_read;
+ GError *error = NULL;
+
+ if (condition & G_IO_HUP) return FALSE; /* this channel is done */
+
+ g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read,
+ &error);
+ handle_error (error);
+
+ buf[bytes_read] = '\0';
+
+ g_print ("%s", buf);
+
+ return TRUE;
+}
+
static void
file_transfer_unix_state_changed_cb (TpChannel *channel,
guint state,
@@ -58,45 +88,45 @@ file_transfer_unix_state_changed_cb (TpChannel *channel,
gpointer user_data,
GObject *weak_obj)
{
- struct sockaddr_un *sa = (struct sockaddr_un *) user_data;
+ struct ft_state *ftstate = (struct ft_state *) user_data;
+ GError *error = NULL;
g_print (" :: file_transfer_state_changed_cb (%i)\n", state);
if (state == TP_FILE_TRANSFER_STATE_OPEN)
{
- int sock = socket (sa->sun_family, SOCK_STREAM, 0);
+ int sock = socket (ftstate->sa.sun_family, SOCK_STREAM, 0);
if (sock == -1)
{
int e = errno;
g_error ("UNABLE TO GET SOCKET: %s", strerror (e));
}
- if (connect (sock, (struct sockaddr *) sa, sizeof (struct sockaddr_un)))
+ if (connect (sock, (struct sockaddr *) &ftstate->sa,
+ sizeof (struct sockaddr_un)))
{
int e = errno;
g_error ("UNABLE TO CONNECT: %s", strerror (e));
}
- /* The Telepathy spec states that as the receiver, we should
- * not trust the number of bytes in the file */
- ssize_t count;
- char buf[1024];
- while ((count = read (sock, buf, sizeof (buf))))
- {
- if (count == -1) continue;
-
- buf[count + 1] = '\0';
- g_print ("%s", buf);
- }
-
- g_print ("\n-------- EOF ----------\n");
- close (sock);
+ /* turn the socket into an IOChannel, so that we can work
+ * with our main loop */
+ ftstate->channel = g_io_channel_unix_new (sock);
+ g_io_add_watch (ftstate->channel, G_IO_IN | G_IO_HUP,
+ file_transfer_data_received,
+ ftstate);
}
else if (state == TP_FILE_TRANSFER_STATE_COMPLETED ||
state == TP_FILE_TRANSFER_STATE_CANCELLED)
{
- /* free the sockaddr struct */
- g_slice_free (struct sockaddr_un, sa);
+ g_print ("\n--------------EOF--------------\n");
+ /* close the socket */
+ g_io_channel_shutdown (ftstate->channel, TRUE, &error);
+ handle_error (error);
+ /* release our resources */
+ g_io_channel_unref (ftstate->channel);
+ g_slice_free (struct ft_state, ftstate);
+ tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
}
}
@@ -109,12 +139,6 @@ file_transfer_channel_ready (TpChannel *channel,
handle_error (in_error);
-
-#if 0
- /* close the channel - we don't want it */
- tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
-#endif
-
GHashTable *map = tp_channel_borrow_immutable_properties (channel);
tp_asv_dump (map);
@@ -143,12 +167,12 @@ file_transfer_channel_ready (TpChannel *channel,
else if (g_hash_table_lookup (sockets,
GINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX)))
{
- struct sockaddr_un *sa = g_slice_new (struct sockaddr_un);
- sa->sun_family = AF_UNIX;
+ struct ft_state *state = g_slice_new (struct ft_state);
+ state->sa.sun_family = AF_UNIX;
tp_cli_channel_type_file_transfer_connect_to_file_transfer_state_changed (
channel, file_transfer_unix_state_changed_cb,
- sa, NULL, NULL, &error);
+ state, NULL, NULL, &error);
handle_error (error);
GValue *value = tp_g_value_slice_new_static_string ("");
@@ -159,7 +183,7 @@ file_transfer_channel_ready (TpChannel *channel,
TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
value, 0,
file_transfer_unix_cb,
- sa, NULL, NULL);
+ state, NULL, NULL);
tp_g_value_slice_free (value);
}
--
1.5.6.5
More information about the telepathy-commits
mailing list