summaryrefslogtreecommitdiff
path: root/daemon/gvfsjobopenforwrite.c
diff options
context:
space:
mode:
authorRoss Lagerwall <rosslagerwall@gmail.com>2013-10-17 07:26:05 +0200
committerRoss Lagerwall <rosslagerwall@gmail.com>2013-12-05 23:51:30 +0000
commitc3b6615e95bd213beab32d90a8bf38f1b221a8b4 (patch)
treeb18ec470be6377b527e603d58ca274bb5c48074d /daemon/gvfsjobopenforwrite.c
parent444a63d09fdaf4db8124801ec6f4ff26ca3c7c0e (diff)
downloadgvfs-c3b6615e95bd213beab32d90a8bf38f1b221a8b4.tar.gz
Implement truncate support for output streams
Backends receive a TRUNCATE message which contains a size parameter. Truncation is signaled with a TRUNCATED message (which contains no other useful information). In more detail: Add a new dbus method, OpenForWriteFlags, which has a flags parameter to implement can_seek and can_truncate. These flags are used in GDaemonFileOutputStream. Compatability with old clients is maintained. Implement the can_truncate and truncate_fn GDaemonFileOutputStream methods. Add two new message types to the daemon socket protocol: G_VFS_DAEMON_SOCKET_PROTOCOL_REQUEST_TRUNCATE G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_TRUNCATED Add a new job type, GVfsJobTruncate. Add two new methods to GVfsBackend which backend classes can implement: truncate and try_truncate https://bugzilla.gnome.org/show_bug.cgi?id=573837
Diffstat (limited to 'daemon/gvfsjobopenforwrite.c')
-rw-r--r--daemon/gvfsjobopenforwrite.c107
1 files changed, 89 insertions, 18 deletions
diff --git a/daemon/gvfsjobopenforwrite.c b/daemon/gvfsjobopenforwrite.c
index 429e2679..1388dabf 100644
--- a/daemon/gvfsjobopenforwrite.c
+++ b/daemon/gvfsjobopenforwrite.c
@@ -81,28 +81,29 @@ g_vfs_job_open_for_write_init (GVfsJobOpenForWrite *job)
{
}
-gboolean
-g_vfs_job_open_for_write_new_handle (GVfsDBusMount *object,
- GDBusMethodInvocation *invocation,
- GUnixFDList *fd_list,
- const gchar *arg_path_data,
- guint16 arg_mode,
- const gchar *arg_etag,
- gboolean arg_make_backup,
- guint arg_flags,
- guint arg_pid,
- GVfsBackend *backend)
+static gboolean
+open_for_write_new_handle_common (GVfsDBusMount *object,
+ GDBusMethodInvocation *invocation,
+ GUnixFDList *fd_list,
+ const gchar *arg_path_data,
+ guint16 arg_mode,
+ const gchar *arg_etag,
+ gboolean arg_make_backup,
+ guint arg_flags,
+ guint arg_pid,
+ GVfsBackend *backend,
+ GVfsJobOpenForWriteVersion version)
{
GVfsJobOpenForWrite *job;
-
+
if (g_vfs_backend_invocation_first_handler (object, invocation, backend))
return TRUE;
-
+
job = g_object_new (G_VFS_TYPE_JOB_OPEN_FOR_WRITE,
"object", object,
"invocation", invocation,
NULL);
-
+
job->filename = g_strdup (arg_path_data);
job->mode = arg_mode;
if (*arg_etag != 0)
@@ -111,6 +112,7 @@ g_vfs_job_open_for_write_new_handle (GVfsDBusMount *object,
job->flags = arg_flags;
job->backend = backend;
job->pid = arg_pid;
+ job->version = version;
g_vfs_job_source_new_job (G_VFS_JOB_SOURCE (backend), G_VFS_JOB (job));
g_object_unref (job);
@@ -118,6 +120,56 @@ g_vfs_job_open_for_write_new_handle (GVfsDBusMount *object,
return TRUE;
}
+gboolean
+g_vfs_job_open_for_write_new_handle (GVfsDBusMount *object,
+ GDBusMethodInvocation *invocation,
+ GUnixFDList *fd_list,
+ const gchar *arg_path_data,
+ guint16 arg_mode,
+ const gchar *arg_etag,
+ gboolean arg_make_backup,
+ guint arg_flags,
+ guint arg_pid,
+ GVfsBackend *backend)
+{
+ return open_for_write_new_handle_common(object,
+ invocation,
+ fd_list,
+ arg_path_data,
+ arg_mode,
+ arg_etag,
+ arg_make_backup,
+ arg_flags,
+ arg_pid,
+ backend,
+ OPEN_FOR_WRITE_VERSION_ORIGINAL);
+}
+
+gboolean
+g_vfs_job_open_for_write_new_handle_with_flags (GVfsDBusMount *object,
+ GDBusMethodInvocation *invocation,
+ GUnixFDList *fd_list,
+ const gchar *arg_path_data,
+ guint16 arg_mode,
+ const gchar *arg_etag,
+ gboolean arg_make_backup,
+ guint arg_flags,
+ guint arg_pid,
+ GVfsBackend *backend)
+{
+ return open_for_write_new_handle_common(object,
+ invocation,
+ fd_list,
+ arg_path_data,
+ arg_mode,
+ arg_etag,
+ arg_make_backup,
+ arg_flags,
+ arg_pid,
+ backend,
+ OPEN_FOR_WRITE_VERSION_WITH_FLAGS);
+}
+
static void
run (GVfsJob *job)
{
@@ -233,6 +285,13 @@ g_vfs_job_open_for_write_set_can_seek (GVfsJobOpenForWrite *job,
}
void
+g_vfs_job_open_for_write_set_can_truncate (GVfsJobOpenForWrite *job,
+ gboolean can_truncate)
+{
+ job->can_truncate = can_truncate;
+}
+
+void
g_vfs_job_open_for_write_set_initial_offset (GVfsJobOpenForWrite *job,
goffset initial_offset)
{
@@ -284,10 +343,22 @@ create_reply (GVfsJob *job,
g_signal_emit_by_name (job, "new-source", open_job->write_channel);
- gvfs_dbus_mount_complete_open_for_write (object, invocation,
- fd_list, g_variant_new_handle (fd_id),
- open_job->can_seek,
- open_job->initial_offset);
+ switch (open_job->version)
+ {
+ case OPEN_FOR_WRITE_VERSION_ORIGINAL:
+ gvfs_dbus_mount_complete_open_for_write (object, invocation,
+ fd_list, g_variant_new_handle (fd_id),
+ open_job->can_seek ? OPEN_FOR_WRITE_FLAG_CAN_SEEK : 0,
+ open_job->initial_offset);
+ break;
+ case OPEN_FOR_WRITE_VERSION_WITH_FLAGS:
+ gvfs_dbus_mount_complete_open_for_write_flags (object, invocation,
+ fd_list, g_variant_new_handle (fd_id),
+ (open_job->can_seek ? OPEN_FOR_WRITE_FLAG_CAN_SEEK : 0) |
+ (open_job->can_truncate ? OPEN_FOR_WRITE_FLAG_CAN_TRUNCATE : 0),
+ open_job->initial_offset);
+ break;
+ }
close (remote_fd);
g_object_unref (fd_list);