summaryrefslogtreecommitdiff
path: root/src/tipideed/send_file.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-12-20 14:08:25 +0000
committerLaurent Bercot <ska@appnovation.com>2023-12-20 14:08:25 +0000
commit51d0fdce74aeb23ef28336037b2d35aa4c955cee (patch)
tree9c178c8e6756ec770b85efd54235cd7c2a97888f /src/tipideed/send_file.c
parentd2959364ef8d6bc948474a8facf497788b4e768b (diff)
downloadtipidee-51d0fdce74aeb23ef28336037b2d35aa4c955cee.tar.xz
Major refactors; implement ranges
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/tipideed/send_file.c')
-rw-r--r--src/tipideed/send_file.c74
1 files changed, 71 insertions, 3 deletions
diff --git a/src/tipideed/send_file.c b/src/tipideed/send_file.c
index 6d97167..bcbd1c7 100644
--- a/src/tipideed/send_file.c
+++ b/src/tipideed/send_file.c
@@ -2,6 +2,66 @@
#include <skalibs/sysdeps.h>
+#ifdef SKALIBS_HASSENDFILE
+
+#include <sys/types.h>
+#include <sys/sendfile.h>
+#include <limits.h>
+
+#include <skalibs/uint64.h>
+#include <skalibs/strerr.h>
+#include <skalibs/tai.h>
+#include <skalibs/unix-timed.h>
+
+#include "tipideed-internal.h"
+
+void init_splice_pipe (void)
+{
+}
+
+struct sendfile_s
+{
+ int fd ;
+ off_t pos ;
+ uint64_t n ;
+} ;
+
+static int s_getfd (void *p)
+{
+ (void)p ;
+ return 1 ;
+}
+
+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(1, 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_range (int fd, uint64_t offset, uint64_t n, char const *fn)
+{
+ struct sendfile_s sf = { .pos = offset, .n = n, .fd = fd } ;
+ tain deadline ;
+ tain_add_g(&deadline, &g.writetto) ;
+ if (!buffer_timed_flush_g(buffer_1, &deadline))
+ strerr_diefu2sys(111, "write", " to stdout") ;
+ if (!timed_flush_g(&sf, &s_getfd, &s_isnonempty, &s_flush, &deadline))
+ strerr_diefu3sys(111, "sendfile ", fn, " to stdout") ;
+}
+
+#else
#ifdef SKALIBS_HASSPLICE
#include <skalibs/nonposix.h>
@@ -10,7 +70,9 @@
#include <stdint.h>
#include <unistd.h>
+#include <skalibs/uint64.h>
#include <skalibs/strerr.h>
+#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <skalibs/unix-timed.h>
@@ -53,7 +115,7 @@ static int flush (void *b)
return 1 ;
}
-void send_file (int fd, uint64_t n, char const *fn)
+void send_file_range (int fd, uint64_t offset, uint64_t n, char const *fn)
{
tain deadline ;
struct spliceinfo_s si = { .last = 0 } ;
@@ -62,7 +124,7 @@ void send_file (int fd, uint64_t n, char const *fn)
strerr_diefu2sys(111, "write", " to stdout") ;
while (n)
{
- si.n = splice(fd, 0, g.p[1], 0, n, 0) ;
+ si.n = splice(fd, &offset, g.p[1], 0, n, 0) ;
if (si.n == -1) strerr_diefu2sys(111, "read from ", fn) ;
else if (!si.n) strerr_diefu3x(111, "serve ", fn, ": file was truncated") ;
else if (si.n > n)
@@ -81,7 +143,10 @@ void send_file (int fd, uint64_t n, char const *fn)
#else
#include <sys/uio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <skalibs/uint64.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/buffer.h>
#include <skalibs/strerr.h>
@@ -94,12 +159,14 @@ void init_splice_pipe (void)
{
}
-void send_file (int fd, uint64_t n, char const *fn)
+void send_file_range (int fd, uint64_t offset, uint64_t n, char const *fn)
{
tain deadline ;
struct iovec v[2] ;
ssize_t r ;
if (!n) goto flushit ; /* I know, I know, but do-while SUCKS */
+ if (offset && lseek(fd, offset, SEEK_SET) == -1)
+ strerr_diefu2sys(111, "lseek on ", fn) ;
fillit:
buffer_wpeek(buffer_1, v) ;
r = allreadv(fd, v, 2) ;
@@ -120,3 +187,4 @@ void send_file (int fd, uint64_t n, char const *fn)
}
#endif
+#endif