178 lines
5.8 KiB
Diff
178 lines
5.8 KiB
Diff
From bcbf85cc1f9bd8c1cb673a5d7d3f9907d84e3caa Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Holy <oholy@redhat.com>
|
|
Date: Wed, 13 Nov 2024 11:52:28 +0100
|
|
Subject: [PATCH] smb: Implement support for edit mode
|
|
|
|
Implement support for the newly added edit mode in the SMB backend.
|
|
|
|
Related: https://gitlab.gnome.org/GNOME/gvfs/-/issues/249
|
|
---
|
|
daemon/gvfsbackendsmb.c | 109 +++++++++++++++++++---------------------
|
|
1 file changed, 53 insertions(+), 56 deletions(-)
|
|
|
|
diff --git a/daemon/gvfsbackendsmb.c b/daemon/gvfsbackendsmb.c
|
|
index f287264b..4fbdfd23 100644
|
|
--- a/daemon/gvfsbackendsmb.c
|
|
+++ b/daemon/gvfsbackendsmb.c
|
|
@@ -793,10 +793,11 @@ smb_write_handle_free (SmbWriteHandle *handle)
|
|
}
|
|
|
|
static void
|
|
-do_create (GVfsBackend *backend,
|
|
- GVfsJobOpenForWrite *job,
|
|
- const char *filename,
|
|
- GFileCreateFlags flags)
|
|
+open_for_write (GVfsBackend *backend,
|
|
+ GVfsJobOpenForWrite *job,
|
|
+ const char *filename,
|
|
+ GFileCreateFlags flags,
|
|
+ int open_flags)
|
|
{
|
|
GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
|
|
char *uri;
|
|
@@ -804,12 +805,12 @@ do_create (GVfsBackend *backend,
|
|
SmbWriteHandle *handle;
|
|
smbc_open_fn smbc_open;
|
|
int errsv;
|
|
+ off_t initial_offset = 0;
|
|
|
|
uri = create_smb_uri (op_backend->server, op_backend->port, op_backend->share, filename);
|
|
smbc_open = smbc_getFunctionOpen (op_backend->smb_context);
|
|
errno = 0;
|
|
- file = smbc_open (op_backend->smb_context, uri,
|
|
- O_CREAT|O_RDWR|O_EXCL, 0666);
|
|
+ file = smbc_open (op_backend->smb_context, uri, open_flags, 0666);
|
|
g_free (uri);
|
|
|
|
if (file == NULL)
|
|
@@ -817,48 +818,16 @@ do_create (GVfsBackend *backend,
|
|
errsv = fixup_open_errno (errno);
|
|
|
|
/* We guarantee EEXIST on create on existing dir */
|
|
- if (errsv == EISDIR)
|
|
+ if (job->mode == OPEN_FOR_WRITE_CREATE && errsv == EISDIR)
|
|
errsv = EEXIST;
|
|
g_vfs_job_failed_from_errno (G_VFS_JOB (job), errsv);
|
|
+ return;
|
|
}
|
|
- else
|
|
- {
|
|
- handle = g_new0 (SmbWriteHandle, 1);
|
|
- handle->file = file;
|
|
- handle->mode = job->mode;
|
|
-
|
|
- g_vfs_job_open_for_write_set_can_seek (job, TRUE);
|
|
- g_vfs_job_open_for_write_set_can_truncate (job, TRUE);
|
|
- g_vfs_job_open_for_write_set_handle (job, handle);
|
|
- g_vfs_job_succeeded (G_VFS_JOB (job));
|
|
- }
|
|
-}
|
|
|
|
-static void
|
|
-do_append_to (GVfsBackend *backend,
|
|
- GVfsJobOpenForWrite *job,
|
|
- const char *filename,
|
|
- GFileCreateFlags flags)
|
|
-{
|
|
- GVfsBackendSmb *op_backend = G_VFS_BACKEND_SMB (backend);
|
|
- char *uri;
|
|
- SMBCFILE *file;
|
|
- SmbWriteHandle *handle;
|
|
- off_t initial_offset;
|
|
- smbc_open_fn smbc_open;
|
|
- smbc_lseek_fn smbc_lseek;
|
|
-
|
|
- uri = create_smb_uri (op_backend->server, op_backend->port, op_backend->share, filename);
|
|
- smbc_open = smbc_getFunctionOpen (op_backend->smb_context);
|
|
- errno = 0;
|
|
- file = smbc_open (op_backend->smb_context, uri,
|
|
- O_CREAT|O_RDWR|O_APPEND, 0666);
|
|
- g_free (uri);
|
|
-
|
|
- if (file == NULL)
|
|
- g_vfs_job_failed_from_errno (G_VFS_JOB (job), fixup_open_errno (errno));
|
|
- else
|
|
+ if (job->mode == OPEN_FOR_WRITE_APPEND)
|
|
{
|
|
+ smbc_lseek_fn smbc_lseek;
|
|
+
|
|
smbc_lseek = smbc_getFunctionLseek (op_backend->smb_context);
|
|
initial_offset = smbc_lseek (op_backend->smb_context, file,
|
|
0, SEEK_CUR);
|
|
@@ -868,24 +837,51 @@ do_append_to (GVfsBackend *backend,
|
|
fixup_open_errno (errno));
|
|
return;
|
|
}
|
|
+ }
|
|
|
|
- handle = g_new0 (SmbWriteHandle, 1);
|
|
- handle->file = file;
|
|
- handle->mode = job->mode;
|
|
+ handle = g_new0 (SmbWriteHandle, 1);
|
|
+ handle->file = file;
|
|
+ handle->mode = job->mode;
|
|
|
|
- g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
|
|
+ g_vfs_job_open_for_write_set_initial_offset (job, initial_offset);
|
|
|
|
- /* The O_APPEND flag is not properly supported by the libsmbclient library
|
|
- * when seeking. See:
|
|
- * https://github.com/samba-team/samba/blob/e4e3f05/source3/libsmb/libsmb_file.c#L162-L183
|
|
- */
|
|
- g_vfs_job_open_for_write_set_can_seek (job, FALSE);
|
|
- g_vfs_job_open_for_write_set_can_truncate (job, TRUE);
|
|
- g_vfs_job_open_for_write_set_handle (job, handle);
|
|
- g_vfs_job_succeeded (G_VFS_JOB (job));
|
|
- }
|
|
+ /* The O_APPEND flag is not properly supported by the libsmbclient library
|
|
+ * when seeking. See:
|
|
+ * https://github.com/samba-team/samba/blob/e4e3f05/source3/libsmb/libsmb_file.c#L162-L183
|
|
+ */
|
|
+ g_vfs_job_open_for_write_set_can_seek (job,
|
|
+ job->mode != OPEN_FOR_WRITE_APPEND);
|
|
+ g_vfs_job_open_for_write_set_can_truncate (job, TRUE);
|
|
+ g_vfs_job_open_for_write_set_handle (job, handle);
|
|
+ g_vfs_job_succeeded (G_VFS_JOB (job));
|
|
}
|
|
|
|
+static void
|
|
+do_create (GVfsBackend *backend,
|
|
+ GVfsJobOpenForWrite *job,
|
|
+ const char *filename,
|
|
+ GFileCreateFlags flags)
|
|
+{
|
|
+ open_for_write (backend, job, filename, flags, O_CREAT|O_RDWR|O_EXCL);
|
|
+}
|
|
+
|
|
+static void
|
|
+do_append_to (GVfsBackend *backend,
|
|
+ GVfsJobOpenForWrite *job,
|
|
+ const char *filename,
|
|
+ GFileCreateFlags flags)
|
|
+{
|
|
+ open_for_write (backend, job, filename, flags, O_CREAT|O_RDWR|O_APPEND);
|
|
+}
|
|
+
|
|
+static void
|
|
+do_edit (GVfsBackend *backend,
|
|
+ GVfsJobOpenForWrite *job,
|
|
+ const char *filename,
|
|
+ GFileCreateFlags flags)
|
|
+{
|
|
+ open_for_write (backend, job, filename, flags, O_CREAT|O_RDWR);
|
|
+}
|
|
|
|
static char *
|
|
get_dir_from_uri (const char *uri)
|
|
@@ -2153,6 +2149,7 @@ g_vfs_backend_smb_class_init (GVfsBackendSmbClass *klass)
|
|
backend_class->close_read = do_close_read;
|
|
backend_class->create = do_create;
|
|
backend_class->append_to = do_append_to;
|
|
+ backend_class->edit = do_edit;
|
|
backend_class->replace = do_replace;
|
|
backend_class->write = do_write;
|
|
backend_class->seek_on_write = do_seek_on_write;
|
|
--
|
|
2.46.2
|
|
|