ssize_t (*read_fn)(void *, void *, size_t),
ssize_t (*write_fn)(void *, const void *, size_t));
+ssize_t transfer_file_internal_offset(void *in_file,
+ void *out_file,
+ size_t n,
+ 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);
#endif /* __TRANSFER_FILE_H__ */
return (ssize_t)total;
}
+ssize_t transfer_file_internal_offset(void *in_file,
+ void *out_file,
+ size_t n,
+ 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;
+ ssize_t read_ret;
+ ssize_t write_ret;
+ size_t num_to_read_thistime;
+ size_t num_written = 0;
+ off_t offset = 0;
+
+ if (n == 0) {
+ return 0;
+ }
+
+ if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL) {
+ return -1;
+ }
+
+ do {
+ num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
+
+ 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) ));
+ SAFE_FREE(buf);
+ return -1;
+ }
+ if (read_ret == 0) {
+ break;
+ }
+
+ num_written = 0;
+
+ while (num_written < read_ret) {
+ 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: "
+ "write failure. Error = %s\n",
+ strerror(errno) ));
+ SAFE_FREE(buf);
+ return -1;
+ }
+ if (write_ret == 0) {
+ return (ssize_t)total;
+ }
+
+ num_written += (size_t)write_ret;
+ }
+
+ 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)
{
int *fd = (int *)file;
return sys_write(*fd, buf, len);
}
+static ssize_t sys_pread_fn(void *file, void *buf, size_t len, off_t offset)
+{
+ int *fd = (int *)file;
+
+ return sys_pread(*fd, buf, len, offset);
+}
+
+static ssize_t sys_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
+{
+ int *fd = (int *)file;
+
+ 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);
+ return (off_t)transfer_file_internal_offset(&infd, &outfd, (size_t)n,
+ sys_pread_fn, sys_pwrite_fn);
}
return SMB_VFS_WRITE(fsp, buf, 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_PREAD(fsp, buf, len, offset);
+}
+
+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_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);
+ return transfer_file_internal_offset((void *)in, (void *)out, n,
+ vfs_pread_fn, vfs_pwrite_fn);
}
/*******************************************************************