14#include "fuse_config.h"
27 for (i = 0; i < bufv->
count; i++) {
28 if (bufv->
buf[i].
size == SIZE_MAX)
37static size_t min_size(
size_t s1,
size_t s2)
39 return s1 < s2 ? s1 : s2;
42static ssize_t fuse_buf_write(
const struct fuse_buf *dst,
size_t dst_off,
43 const struct fuse_buf *src,
size_t src_off,
51 res = pwrite(dst->
fd, (
char *)src->
mem + src_off, len,
54 res = write(dst->
fd, (
char *)src->
mem + src_off, len);
76static ssize_t fuse_buf_read(
const struct fuse_buf *dst,
size_t dst_off,
77 const struct fuse_buf *src,
size_t src_off,
85 res = pread(src->
fd, (
char *)dst->
mem + dst_off, len,
88 res = read(src->
fd, (
char *)dst->
mem + dst_off, len);
110static ssize_t fuse_buf_fd_to_fd(
const struct fuse_buf *dst,
size_t dst_off,
111 const struct fuse_buf *src,
size_t src_off,
125 size_t this_len = min_size(tmp.
size, len);
128 res = fuse_buf_read(&tmp, 0, src, src_off, this_len);
138 res = fuse_buf_write(dst, dst_off, &tmp, 0, read_len);
161static ssize_t fuse_buf_splice(
const struct fuse_buf *dst,
size_t dst_off,
162 const struct fuse_buf *src,
size_t src_off,
165 int splice_flags = 0;
166 off_t *srcpos = NULL;
167 off_t *dstpos = NULL;
174 splice_flags |= SPLICE_F_MOVE;
176 splice_flags |= SPLICE_F_NONBLOCK;
179 srcpos_val = src->
pos + src_off;
180 srcpos = &srcpos_val;
183 dstpos_val = dst->
pos + dst_off;
184 dstpos = &dstpos_val;
188 res = splice(src->
fd, srcpos, dst->
fd, dstpos, len,
198 return fuse_buf_fd_to_fd(dst, dst_off, src, src_off,
216static ssize_t fuse_buf_splice(
const struct fuse_buf *dst,
size_t dst_off,
217 const struct fuse_buf *src,
size_t src_off,
222 return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
227static ssize_t fuse_buf_copy_one(
const struct fuse_buf *dst,
size_t dst_off,
228 const struct fuse_buf *src,
size_t src_off,
234 if (!src_is_fd && !dst_is_fd) {
235 char *dstmem = (
char *)dst->
mem + dst_off;
236 char *srcmem = (
char *)src->
mem + src_off;
238 if (dstmem != srcmem) {
239 if (dstmem + len <= srcmem || srcmem + len <= dstmem)
240 memcpy(dstmem, srcmem, len);
242 memmove(dstmem, srcmem, len);
246 }
else if (!src_is_fd) {
247 return fuse_buf_write(dst, dst_off, src, src_off, len);
248 }
else if (!dst_is_fd) {
249 return fuse_buf_read(dst, dst_off, src, src_off, len);
251 return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
253 return fuse_buf_splice(dst, dst_off, src, src_off, len,
flags);
260 return &bufv->
buf[bufv->
idx];
265static int fuse_bufvec_advance(
struct fuse_bufvec *bufv,
size_t len)
267 const struct fuse_buf *buf = fuse_bufvec_current(bufv);
273 assert(bufv->
off <= buf->
size);
293 const struct fuse_buf *src = fuse_bufvec_current(srcv);
294 const struct fuse_buf *dst = fuse_bufvec_current(dstv);
300 if (src == NULL || dst == NULL)
303 src_len = src->
size - srcv->
off;
304 dst_len = dst->
size - dstv->
off;
305 len = min_size(src_len, dst_len);
307 res = fuse_buf_copy_one(dst, dstv->
off, src, srcv->
off, len,
flags);
315 if (!fuse_bufvec_advance(srcv, res) ||
316 !fuse_bufvec_advance(dstv, res))
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src, enum fuse_buf_copy_flags flags)
@ FUSE_BUF_SPLICE_NONBLOCK
enum fuse_buf_flags flags