diff options
author | Ross Lagerwall <rosslagerwall@gmail.com> | 2013-10-17 10:05:43 +0200 |
---|---|---|
committer | Ross Lagerwall <rosslagerwall@gmail.com> | 2013-12-05 23:51:31 +0000 |
commit | 41602b74d507a7945454431e55ad9a0b56c2c903 (patch) | |
tree | d6f48a77d145772569d23ebc318656fef7c0a775 | |
parent | 6e5786f4368e7124ce316dafd607d3306c05ea11 (diff) | |
download | gvfs-41602b74d507a7945454431e55ad9a0b56c2c903.tar.gz |
sftp: Implement truncate support for output streams
https://bugzilla.gnome.org/show_bug.cgi?id=573837
-rw-r--r-- | daemon/gvfsbackendsftp.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c index abfd8e4d..fcefbd22 100644 --- a/daemon/gvfsbackendsftp.c +++ b/daemon/gvfsbackendsftp.c @@ -51,6 +51,7 @@ #include "gvfsjobwrite.h" #include "gvfsjobclosewrite.h" #include "gvfsjobseekwrite.h" +#include "gvfsjobtruncate.h" #include "gvfsjobsetdisplayname.h" #include "gvfsjobqueryinfo.h" #include "gvfsjobqueryinforead.h" @@ -3070,6 +3071,7 @@ create_reply (GVfsBackendSftp *backend, g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), handle); g_vfs_job_open_for_write_set_can_seek (G_VFS_JOB_OPEN_FOR_WRITE (job), TRUE); + g_vfs_job_open_for_write_set_can_truncate (G_VFS_JOB_OPEN_FOR_WRITE (job), TRUE); g_vfs_job_succeeded (job); } @@ -3151,6 +3153,7 @@ append_to_reply (GVfsBackendSftp *backend, g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), handle); g_vfs_job_open_for_write_set_can_seek (G_VFS_JOB_OPEN_FOR_WRITE (job), TRUE); + g_vfs_job_open_for_write_set_can_truncate (G_VFS_JOB_OPEN_FOR_WRITE (job), TRUE); g_vfs_job_succeeded (job); } @@ -3241,6 +3244,7 @@ replace_truncate_original_reply (GVfsBackendSftp *backend, g_vfs_job_open_for_write_set_handle (op_job, handle); g_vfs_job_open_for_write_set_can_seek (op_job, TRUE); + g_vfs_job_open_for_write_set_can_truncate (op_job, TRUE); g_vfs_job_succeeded (job); } @@ -3340,6 +3344,7 @@ replace_create_temp_reply (GVfsBackendSftp *backend, g_vfs_job_open_for_write_set_handle (op_job, handle); g_vfs_job_open_for_write_set_can_seek (op_job, TRUE); + g_vfs_job_open_for_write_set_can_truncate (op_job, TRUE); g_vfs_job_succeeded (job); } @@ -3580,6 +3585,7 @@ replace_exclusive_reply (GVfsBackendSftp *backend, g_vfs_job_open_for_write_set_handle (op_job, handle); g_vfs_job_open_for_write_set_can_seek (op_job, TRUE); + g_vfs_job_open_for_write_set_can_truncate (op_job, TRUE); g_vfs_job_succeeded (job); } @@ -3741,6 +3747,40 @@ try_seek_on_write (GVfsBackend *backend, return TRUE; } +static void +truncate_reply (GVfsBackendSftp *backend, + int reply_type, + GDataInputStream *reply, + guint32 len, + GVfsJob *job, + gpointer user_data) +{ + if (reply_type == SSH_FXP_STATUS) + result_from_status (job, reply, -1, -1); + else + g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Invalid reply received")); +} + +static gboolean +try_truncate (GVfsBackend *backend, + GVfsJobTruncate *job, + GVfsBackendHandle _handle, + goffset size) +{ + SftpHandle *handle = _handle; + GVfsBackendSftp *op_backend = G_VFS_BACKEND_SFTP (backend); + GDataOutputStream *command; + + command = new_command_stream (op_backend, SSH_FXP_FSETSTAT); + put_data_buffer (command, handle->raw_handle); + g_data_output_stream_put_uint32 (command, SSH_FILEXFER_ATTR_SIZE, NULL, NULL); + g_data_output_stream_put_uint64 (command, size, NULL, NULL); + queue_command_stream_and_free (op_backend, command, truncate_reply, G_VFS_JOB (job), NULL); + + return TRUE; +} + typedef struct { DataBuffer *handle; int outstanding_requests; @@ -6076,6 +6116,7 @@ g_vfs_backend_sftp_class_init (GVfsBackendSftpClass *klass) backend_class->try_replace = try_replace; backend_class->try_write = try_write; backend_class->try_seek_on_write = try_seek_on_write; + backend_class->try_truncate = try_truncate; backend_class->try_move = try_move; backend_class->try_make_symlink = try_make_symlink; backend_class->try_make_directory = try_make_directory; |