From 21d51f7e0a639a3224ffc45dc3c06854decf1d45 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 30 Jan 2024 20:51:38 +0000 Subject: Initial commit Signed-off-by: Laurent Bercot --- src/client/send_file.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/client/send_file.c (limited to 'src/client/send_file.c') diff --git a/src/client/send_file.c b/src/client/send_file.c new file mode 100644 index 0000000..4da8412 --- /dev/null +++ b/src/client/send_file.c @@ -0,0 +1,93 @@ +/* ISC license. */ + +#include + +#ifdef SKALIBS_HASSENDFILE + +#include +#include +#include + +#include +#include +#include +#include + +struct sendfile_s +{ + int fd ; + buffer *out ; + off_t pos ; + uint64_t n ; +} ; + +static int s_getfd (void *p) +{ + struct sendfile_s *sf = p ; + return buffer_fd(sf->out) ; +} + +static int s_isnonempty (void *p) +{ + struct sendfile_s *sf = p ; + return !!sf->n ; +} + +static int s_flush (void *p) +{ + struct sendfile_s *sf = p ; + while (sf->n) + { + ssize_t r = sendfile(buffer_fd(sf->out), sf->fd, &sf->pos, sf->n > SSIZE_MAX ? SSIZE_MAX : sf->n) ; + if (r == -1) return 0 ; + sf->n -= r ; + } + return 1 ; +} + +void send_file (buffer *b, int fd, off_t size, char const *fn, tain const *deadline, tain *stamp) +{ + struct sendfile_s sf = { .fd = fd, .out = b, .pos = 0, .n = size } ; + if (!buffer_timed_flush(b, deadline, stamp)) + strerr_diefu1sys(111, "write to network") ; + if (!timed_flush(&sf, &s_getfd, &s_isnonempty, &s_flush, deadline, stamp)) + strerr_diefu3sys(111, "sendfile ", fn, " to network") ; +} + +#else + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +void send_file (buffer *b, int fd, uint64_t n, char const *fn, tain const *deadline, tain *stamp) +{ + struct iovec v[2] ; + ssize_t r ; + if (!n) goto flushit ; + fillit: + buffer_wpeek(b, v) ; + r = allreadv(fd, v, 2) ; + if (r == -1) strerr_diefu2sys(111, "read from ", fn) ; + if (!r) strerr_diefu3x(111, "send ", fn, ": file was truncated") ; + if (r > n) + { + r = n ; + strerr_warnw2x("sending elongated file: ", fn) ; + } + buffer_wseek(b, r) ; + n -= r ; + flushit: + if (!buffer_timed_flush(b, deadline, stamp)) + strerr_diefu1sys(111, "write to network") ; + if (n) goto fillit ; +} + +#endif -- cgit v1.3.1