diff options
author | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2011-08-14 14:57:54 +0200 |
---|---|---|
committer | Christian Kellner <gicmo@gnome.org> | 2011-08-25 21:19:55 +0200 |
commit | e83e66caff7b8084b575c5fa38219b40c6c377b3 (patch) | |
tree | 46ec2290fca57d5c018775360e387e1dab189b84 /daemon/gvfsafpconnection.c | |
parent | 936a4dc3d63f4def4ef6e5eae716da26e8b8f98d (diff) | |
download | gvfs-e83e66caff7b8084b575c5fa38219b40c6c377b3.tar.gz |
afp: fix some memoryleaks
change g_vfs_afp_connection_send_command to take a "char *reply_buf" paramater
to use for storing the reply data instead of reusing the buf data pointer in
GVfsAfpCommand
Diffstat (limited to 'daemon/gvfsafpconnection.c')
-rw-r--r-- | daemon/gvfsafpconnection.c | 98 |
1 files changed, 49 insertions, 49 deletions
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c index 4c369a8f..b725f545 100644 --- a/daemon/gvfsafpconnection.c +++ b/daemon/gvfsafpconnection.c @@ -88,6 +88,7 @@ struct _GVfsAfpReply char *data; gsize len; + gboolean free_data; goffset pos; }; @@ -103,12 +104,24 @@ g_vfs_afp_reply_init (GVfsAfpReply *reply) } static void +g_vfs_afp_reply_finalize (GObject *object) +{ + GVfsAfpReply *reply = (GVfsAfpReply *)object; + + if (reply->free_data) + g_free (reply->data); +} + +static void g_vfs_afp_reply_class_init (GVfsAfpReplyClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = g_vfs_afp_reply_finalize; } static GVfsAfpReply * -g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len) +g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len, gboolean take_data) { GVfsAfpReply *reply; @@ -117,6 +130,7 @@ g_vfs_afp_reply_new (AfpResultCode result_code, char *data, gsize len) reply->result_code = result_code; reply->len = len; reply->data = data; + reply->free_data = take_data; return reply; } @@ -407,11 +421,15 @@ g_vfs_afp_command_class_init (GVfsAfpCommandClass *klass) GVfsAfpCommand * g_vfs_afp_command_new (AfpCommandType type) { + GOutputStream *mem_stream; GVfsAfpCommand *comm; + mem_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); comm = g_object_new (G_VFS_TYPE_AFP_COMMAND, - "base-stream", g_memory_output_stream_new (NULL, 0, g_realloc, g_free), + "base-stream", mem_stream, NULL); + + g_object_unref (mem_stream); comm->type = type; g_vfs_afp_command_put_byte (comm, type); @@ -569,7 +587,8 @@ struct _GVfsAfpConnectionPrivate /* read loop */ gboolean read_loop_running; DSIHeader read_dsi_header; - char *data; + char *reply_buf; + gboolean free_reply_buf; }; typedef enum @@ -605,6 +624,7 @@ typedef struct RequestType type; GVfsAfpCommand *command; + char *reply_buf; GSimpleAsyncResult *simple; GCancellable *cancellable; } RequestData; @@ -778,10 +798,9 @@ dispatch_reply (GVfsAfpConnection *afp_connection) { guint8 attention_code; - attention_code = priv->data[0] >> 4; + attention_code = priv->reply_buf[0] >> 4; g_signal_emit (afp_connection, signals[ATTENTION], 0, attention_code); - g_free (priv->data); break; } @@ -796,8 +815,9 @@ dispatch_reply (GVfsAfpConnection *afp_connection) { GVfsAfpReply *reply; - reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->data, - dsi_header->totalDataLength); + reply = g_vfs_afp_reply_new (dsi_header->errorCode, priv->reply_buf, + dsi_header->totalDataLength, priv->free_reply_buf); + priv->free_reply_buf = FALSE; g_simple_async_result_set_op_res_gpointer (req_data->simple, reply, g_object_unref); @@ -806,9 +826,6 @@ dispatch_reply (GVfsAfpConnection *afp_connection) g_hash_table_remove (priv->request_hash, GUINT_TO_POINTER ((guint)dsi_header->requestID)); } - else - g_free (priv->data); - break; } @@ -816,31 +833,13 @@ dispatch_reply (GVfsAfpConnection *afp_connection) g_assert_not_reached (); } } - -static void -skip_data_cb (GObject *object, GAsyncResult *res, gpointer user_data) -{ - GInputStream *input = G_INPUT_STREAM (object); - GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data); - - gsize bytes_skipped; - GError *err = NULL; - - bytes_skipped = g_input_stream_skip_finish (input, res, &err); - if (bytes_skipped == -1) - { - g_warning ("FAIL!!! \"%s\"\n", err->message); - g_error_free (err); - } - - read_reply (afp_connection); -} static void read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data) { GInputStream *input = G_INPUT_STREAM (object); GVfsAfpConnection *afp_connection = G_VFS_AFP_CONNECTION (user_data); + GVfsAfpConnectionPrivate *priv = afp_connection->priv; gboolean result; GError *err = NULL; @@ -853,6 +852,10 @@ read_data_cb (GObject *object, GAsyncResult *res, gpointer user_data) } dispatch_reply (afp_connection); + + if (priv->free_reply_buf) + g_free (priv->reply_buf); + read_reply (afp_connection); } @@ -886,23 +889,20 @@ read_dsi_header_cb (GObject *object, GAsyncResult *res, gpointer user_data) req_data = g_hash_table_lookup (priv->request_hash, GUINT_TO_POINTER ((guint)dsi_header->requestID)); - if (req_data) + if (req_data && req_data->reply_buf) { - if (req_data->command->type == AFP_COMMAND_READ_EXT && req_data->command->buf) - priv->data = req_data->command->buf; - else - priv->data = g_malloc (dsi_header->totalDataLength); - - read_all_async (input, priv->data, dsi_header->totalDataLength, - 0, NULL, read_data_cb, afp_conn); + priv->reply_buf = req_data->reply_buf; + priv->free_reply_buf = FALSE; } else { - /* TODO: should really do a skip_all */ - g_input_stream_skip_async (input, dsi_header->totalDataLength, 0, NULL, - skip_data_cb, afp_conn); + priv->reply_buf = g_malloc (dsi_header->totalDataLength); + priv->free_reply_buf = TRUE; } + read_all_async (input, priv->reply_buf, dsi_header->totalDataLength, + 0, NULL, read_data_cb, afp_conn); + return; } @@ -919,8 +919,6 @@ read_reply (GVfsAfpConnection *afp_connection) input = g_io_stream_get_input_stream (priv->conn); - priv->data = NULL; - read_all_async (input, &priv->read_dsi_header, sizeof (DSIHeader), 0, NULL, read_dsi_header_cb, afp_connection); } @@ -1236,11 +1234,12 @@ send_request (GVfsAfpConnection *afp_connection) } void -g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection, - GVfsAfpCommand *command, - GAsyncReadyCallback callback, - GCancellable *cancellable, - gpointer user_data) +g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection, + GVfsAfpCommand *command, + char *reply_buf, + GAsyncReadyCallback callback, + GCancellable *cancellable, + gpointer user_data) { GVfsAfpConnectionPrivate *priv = afp_connection->priv; @@ -1249,6 +1248,7 @@ g_vfs_afp_connection_send_command (GVfsAfpConnection *afp_connection, req_data = g_slice_new0 (RequestData); req_data->type = REQUEST_TYPE_COMMAND; req_data->command = g_object_ref (command); + req_data->reply_buf = reply_buf; req_data->simple = g_simple_async_result_new (G_OBJECT (afp_connection), callback, user_data, @@ -1352,7 +1352,7 @@ g_vfs_afp_connection_read_reply_sync (GVfsAfpConnection *afp_connection, if (!res) return NULL; - return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength); + return g_vfs_afp_reply_new (dsi_header.errorCode, data, dsi_header.totalDataLength, TRUE); } static gboolean @@ -1569,7 +1569,7 @@ g_vfs_afp_connection_get_server_info (GVfsAfpConnection *afp_connection, g_object_unref (conn); return g_vfs_afp_reply_new (dsi_header.errorCode, data, - dsi_header.totalDataLength); + dsi_header.totalDataLength, TRUE); } GVfsAfpConnection * |