summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2020-10-05 11:33:45 +0200
committerOndrej Holy <oholy@redhat.com>2020-12-01 09:21:56 +0000
commit6af03154d8ca46bf91281cd30f84a2b9ede08689 (patch)
treee352a315d0af9f6a8b555017a8993b14c747bf03
parent552a2b77b3f64365c947d53133eb100793834fa3 (diff)
downloadgvfs-6af03154d8ca46bf91281cd30f84a2b9ede08689.tar.gz
ftp: Close output stream properly in pull job
The output stream is not properly closed in pull job, which might potentially lead to data loss. Let's use the recently added splice function and close the output stream with the help of G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET flag.
-rw-r--r--daemon/gvfsbackendftp.c56
1 files changed, 8 insertions, 48 deletions
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
index e86f5e91..1f2f23ad 100644
--- a/daemon/gvfsbackendftp.c
+++ b/daemon/gvfsbackendftp.c
@@ -1533,47 +1533,6 @@ out:
g_vfs_ftp_task_done (&task);
}
-static gssize
-ftp_output_stream_splice (GOutputStream *output,
- GInputStream *input,
- goffset total_size,
- GFileProgressCallback progress_callback,
- gpointer progress_callback_data,
- GCancellable *cancellable,
- GError **error)
-{
- gssize n_read, n_written;
- gssize bytes_copied;
- char buffer[8192], *p;
-
- bytes_copied = 0;
- for (;;)
- {
- n_read = g_input_stream_read (input, buffer, sizeof (buffer), cancellable, error);
- if (n_read == -1)
- return -1;
- if (n_read == 0)
- break;
-
- p = buffer;
- while (n_read > 0)
- {
- n_written = g_output_stream_write (output, p, n_read, cancellable, error);
- if (n_written == -1)
- return -1;
-
- p += n_written;
- n_read -= n_written;
- bytes_copied += n_written;
-
- if (progress_callback)
- progress_callback (bytes_copied, total_size, progress_callback_data);
- }
- }
-
- return bytes_copied;
-}
-
static void
do_pull_improve_error_message (GVfsFtpTask *task,
GFile *dest,
@@ -1735,13 +1694,14 @@ do_pull (GVfsBackend * backend,
}
input = g_io_stream_get_input_stream (g_vfs_ftp_connection_get_data_stream (task.conn));
- ftp_output_stream_splice (output,
- input,
- total_size,
- progress_callback,
- progress_callback_data,
- task.cancellable,
- &task.error);
+ gvfs_output_stream_splice (output,
+ input,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ total_size,
+ progress_callback,
+ progress_callback_data,
+ task.cancellable,
+ &task.error);
g_vfs_ftp_task_close_data_connection (&task);
g_vfs_ftp_task_receive (&task, 0, NULL);
g_object_unref (output);