1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/* ISC license. */
#include <skalibs/sysdeps.h>
#ifdef SKALIBS_HASSPLICE
#include <skalibs/nonposix.h>
#include <fcntl.h>
#include <stdint.h>
#include <unistd.h>
#include <skalibs/strerr.h>
#include <skalibs/djbunix.h>
#include <skalibs/unix-timed.h>
#include "tipideed-internal.h"
void init_splice_pipe (void)
{
if (pipenbcoe(g.p) == -1)
strerr_diefu1sys(111, "pipe2") ;
}
struct spliceinfo_s
{
ssize_t n ;
uint32_t last : 1 ;
} ;
static int getfd (void *b)
{
(void)b ;
return 1 ;
}
static int isnonempty (void *b)
{
struct spliceinfo_s *si = b ;
return !!si->n ;
}
static int flush (void *b)
{
struct spliceinfo_s *si = b ;
while (si->n)
{
ssize_t r = splice(g.p[0], 0, 1, 0, si->n, SPLICE_F_NONBLOCK | (si->last ? 0 : SPLICE_F_MORE)) ;
if (r == -1) return 0 ;
if (!r) return 1 ;
si->n -= r ;
}
return 1 ;
}
void send_file (int fd, uint64_t n, char const *fn)
{
tain deadline ;
struct spliceinfo_s si = { .last = 0 } ;
tain_add_g(&deadline, &g.writetto) ;
if (!buffer_timed_flush_g(buffer_1, &deadline))
strerr_diefu2sys(111, "write", " to stdout") ;
while (n)
{
si.n = splice(fd, 0, 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)
{
si.n = n ;
if (g.verbosity >= 2)
strerr_warnw2x("serving elongated file: ", fn) ;
}
n -= si.n ;
if (!n) si.last = 1 ;
tain_add_g(&deadline, &g.writetto) ;
if (!timed_flush_g(&si, &getfd, &isnonempty, &flush, &deadline))
strerr_diefu2sys(111, "splice", " to stdout") ;
}
}
#else
#include <sys/uio.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/buffer.h>
#include <skalibs/strerr.h>
#include <skalibs/tai.h>
#include "tipideed-internal.h"
void init_splice_pipe (void)
{
}
void send_file (int fd, uint64_t n, char const *fn)
{
tain deadline ;
struct iovec v[2] ;
while (n)
{
ssize_t r ;
buffer_rpeek(buffer_1, v) ;
r = allreadv(fd, v, 2) ;
if (r > n)
if (r == -1) strerr_diefu2sys(111, "read from ", fn) ;
if (!r) strerr_diefu3x(111, "serve ", fn, ": file was truncated") ;
if (r > n)
{
r = n ;
if (g.verbosity >= 2)
strerr_warnw2x("serving elongated file: ", fn)
}
buffer_rseek(b, r) ;
tain_add_g(&deadline, g.writetto) ;
if (!buffer_timed_flush_g(buffer_1, &deadline))
strerr_diefu1sys(111, "write to stdout") ;
n -= r ;
}
}
#endif
|