diff options
author | Alexander Larsson <alexl@redhat.com> | 2013-10-08 09:26:19 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2013-10-08 09:31:05 +0200 |
commit | 5fb056ffea07aa415a676bc22d4b02e7d3fc482a (patch) | |
tree | b5f9b03038fca24593a33f08115412f145cd98c6 | |
parent | 0e6434139716a63ce99e84525aa63890a6244378 (diff) | |
download | gvfs-5fb056ffea07aa415a676bc22d4b02e7d3fc482a.tar.gz |
sftp: Allow seek past end of file
also, don't query for the file size unless required for SEEK_END
https://bugzilla.gnome.org/show_bug.cgi?id=709432
-rw-r--r-- | daemon/gvfsbackendsftp.c | 94 |
1 files changed, 54 insertions, 40 deletions
diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c index 120343aa..d32ec694 100644 --- a/daemon/gvfsbackendsftp.c +++ b/daemon/gvfsbackendsftp.c @@ -2539,24 +2539,11 @@ seek_read_fstat_reply (GVfsBackendSftp *backend, op_job = G_VFS_JOB_SEEK_READ (job); - switch (op_job->seek_type) - { - case G_SEEK_CUR: - handle->offset += op_job->requested_offset; - break; - case G_SEEK_SET: - handle->offset = op_job->requested_offset; - break; - case G_SEEK_END: - handle->offset = file_size + op_job->requested_offset; - break; - } + handle->offset = file_size + op_job->requested_offset; if (handle->offset < 0) handle->offset = 0; - if (handle->offset > file_size) - handle->offset = file_size; - + g_vfs_job_seek_read_set_offset (op_job, handle->offset); g_vfs_job_succeeded (job); } @@ -2572,11 +2559,31 @@ try_seek_on_read (GVfsBackend *backend, GVfsBackendSftp *op_backend = G_VFS_BACKEND_SFTP (backend); GDataOutputStream *command; - command = new_command_stream (op_backend, - SSH_FXP_FSTAT); - put_data_buffer (command, handle->raw_handle); - - queue_command_stream_and_free (op_backend, command, seek_read_fstat_reply, G_VFS_JOB (job), handle); + if (job->seek_type == G_SEEK_END) + { + command = new_command_stream (op_backend, + SSH_FXP_FSTAT); + put_data_buffer (command, handle->raw_handle); + queue_command_stream_and_free (op_backend, command, seek_read_fstat_reply, G_VFS_JOB (job), handle); + } + else + { + switch (job->seek_type) + { + case G_SEEK_CUR: + handle->offset += job->requested_offset; + break; + case G_SEEK_SET: + handle->offset = job->requested_offset; + break; + } + + if (handle->offset < 0) + handle->offset = 0; + + g_vfs_job_seek_read_set_offset (job, handle->offset); + g_vfs_job_succeeded (G_VFS_JOB (job)); + } return TRUE; } @@ -3612,24 +3619,11 @@ seek_write_fstat_reply (GVfsBackendSftp *backend, op_job = G_VFS_JOB_SEEK_WRITE (job); - switch (op_job->seek_type) - { - case G_SEEK_CUR: - handle->offset += op_job->requested_offset; - break; - case G_SEEK_SET: - handle->offset = op_job->requested_offset; - break; - case G_SEEK_END: - handle->offset = file_size + op_job->requested_offset; - break; - } + handle->offset = file_size + op_job->requested_offset; if (handle->offset < 0) handle->offset = 0; - if (handle->offset > file_size) - handle->offset = file_size; - + g_vfs_job_seek_write_set_offset (op_job, handle->offset); g_vfs_job_succeeded (job); } @@ -3645,11 +3639,31 @@ try_seek_on_write (GVfsBackend *backend, GVfsBackendSftp *op_backend = G_VFS_BACKEND_SFTP (backend); GDataOutputStream *command; - command = new_command_stream (op_backend, - SSH_FXP_FSTAT); - put_data_buffer (command, handle->raw_handle); - - queue_command_stream_and_free (op_backend, command, seek_write_fstat_reply, G_VFS_JOB (job), handle); + if (job->seek_type == G_SEEK_END) + { + command = new_command_stream (op_backend, + SSH_FXP_FSTAT); + put_data_buffer (command, handle->raw_handle); + queue_command_stream_and_free (op_backend, command, seek_write_fstat_reply, G_VFS_JOB (job), handle); + } + else + { + switch (job->seek_type) + { + case G_SEEK_CUR: + handle->offset += job->requested_offset; + break; + case G_SEEK_SET: + handle->offset = job->requested_offset; + break; + } + + if (handle->offset < 0) + handle->offset = 0; + + g_vfs_job_seek_write_set_offset (job, handle->offset); + g_vfs_job_succeeded (G_VFS_JOB (job)); + } return TRUE; } |