diff options
author | Ondrej Holy <oholy@redhat.com> | 2020-10-05 11:33:45 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2020-12-01 09:21:56 +0000 |
commit | 6af03154d8ca46bf91281cd30f84a2b9ede08689 (patch) | |
tree | e352a315d0af9f6a8b555017a8993b14c747bf03 | |
parent | 552a2b77b3f64365c947d53133eb100793834fa3 (diff) | |
download | gvfs-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.c | 56 |
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); |