From edf3b6146531bb3f15442bbb0cdad7b03be9650b Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Mon, 27 Apr 2015 12:16:16 +0200 Subject: [PATCH] s3:util: use pread/pwrite in transfer_file read/write aren't overloaded in the streams VFS modules, using pread/pwrite instead this makes it possible to use transfer_file() with named streams. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11317 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/include/transfer_file.h | 4 ++-- source3/lib/util_transfer_file.c | 23 +++++++++++++---------- source3/smbd/vfs.c | 10 +++++----- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/source3/include/transfer_file.h b/source3/include/transfer_file.h index 546104f8f37..2f1bff4bf11 100644 --- a/source3/include/transfer_file.h +++ b/source3/include/transfer_file.h @@ -24,8 +24,8 @@ ssize_t transfer_file_internal(void *in_file, void *out_file, size_t n, - ssize_t (*read_fn)(void *, void *, size_t), - ssize_t (*write_fn)(void *, const void *, size_t)); + ssize_t (*pread_fn)(void *, void *, size_t, off_t), + ssize_t (*pwrite_fn)(void *, const void *, size_t, off_t)); off_t transfer_file(int infd, int outfd, off_t n); diff --git a/source3/lib/util_transfer_file.c b/source3/lib/util_transfer_file.c index d415d7f98e0..91f4f6f7f2e 100644 --- a/source3/lib/util_transfer_file.c +++ b/source3/lib/util_transfer_file.c @@ -36,8 +36,8 @@ ssize_t transfer_file_internal(void *in_file, void *out_file, size_t n, - ssize_t (*read_fn)(void *, void *, size_t), - ssize_t (*write_fn)(void *, const void *, size_t)) + ssize_t (*pread_fn)(void *, void *, size_t, off_t), + ssize_t (*pwrite_fn)(void *, const void *, size_t, off_t)) { char *buf; size_t total = 0; @@ -45,6 +45,7 @@ ssize_t transfer_file_internal(void *in_file, ssize_t write_ret; size_t num_to_read_thistime; size_t num_written = 0; + off_t offset = 0; if (n == 0) { return 0; @@ -57,7 +58,7 @@ ssize_t transfer_file_internal(void *in_file, do { num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE); - read_ret = (*read_fn)(in_file, buf, num_to_read_thistime); + read_ret = (*pread_fn)(in_file, buf, num_to_read_thistime, offset); if (read_ret == -1) { DEBUG(0,("transfer_file_internal: read failure. " "Error = %s\n", strerror(errno) )); @@ -71,8 +72,9 @@ ssize_t transfer_file_internal(void *in_file, num_written = 0; while (num_written < read_ret) { - write_ret = (*write_fn)(out_file, buf + num_written, - read_ret - num_written); + write_ret = (*pwrite_fn)(out_file, buf + num_written, + read_ret - num_written, + offset + num_written); if (write_ret == -1) { DEBUG(0,("transfer_file_internal: " @@ -89,28 +91,29 @@ ssize_t transfer_file_internal(void *in_file, } total += (size_t)read_ret; + offset += (off_t)read_ret; } while (total < n); SAFE_FREE(buf); return (ssize_t)total; } -static ssize_t sys_read_fn(void *file, void *buf, size_t len) +static ssize_t sys_pread_fn(void *file, void *buf, size_t len, off_t offset) { int *fd = (int *)file; - return sys_read(*fd, buf, len); + return sys_pread(*fd, buf, len, offset); } -static ssize_t sys_write_fn(void *file, const void *buf, size_t len) +static ssize_t sys_pwrite_fn(void *file, const void *buf, size_t len, off_t offset) { int *fd = (int *)file; - return sys_write(*fd, buf, len); + return sys_pwrite(*fd, buf, len, offset); } off_t transfer_file(int infd, int outfd, off_t n) { return (off_t)transfer_file_internal(&infd, &outfd, (size_t)n, - sys_read_fn, sys_write_fn); + sys_pread_fn, sys_pwrite_fn); } diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 4ab7723aefc..b2673879f5a 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -756,24 +756,24 @@ int vfs_fill_sparse(files_struct *fsp, off_t len) Transfer some data (n bytes) between two file_struct's. ****************************************************************************/ -static ssize_t vfs_read_fn(void *file, void *buf, size_t len) +static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset) { struct files_struct *fsp = (struct files_struct *)file; - return SMB_VFS_READ(fsp, buf, len); + return SMB_VFS_PREAD(fsp, buf, len, offset); } -static ssize_t vfs_write_fn(void *file, const void *buf, size_t len) +static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset) { struct files_struct *fsp = (struct files_struct *)file; - return SMB_VFS_WRITE(fsp, buf, len); + return SMB_VFS_PWRITE(fsp, buf, len, offset); } off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n) { return transfer_file_internal((void *)in, (void *)out, n, - vfs_read_fn, vfs_write_fn); + vfs_pread_fn, vfs_pwrite_fn); } /******************************************************************* -- 2.11.4.GIT