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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/*
* Copyright (C) Igor Sysoev
* Copyright (C) NGINX, Inc.
*/
#include <nxt_main.h>
#ifdef NXT_TEST_BUILD_HPUX_SENDFILE
ssize_t nxt_hpux_event_conn_io_sendfile(nxt_event_conn_t *c, nxt_buf_t *b,
size_t limit);
static ssize_t nxt_sys_sendfile(int s, int fd, off_t offset, size_t nbytes,
const struct iovec *hdtrl, int flags)
{
return -1;
}
#else
/* sendfile() is not declared if _XOPEN_SOURCE_EXTENDED is defined. */
sbsize_t sendfile(int s, int fd, off_t offset, bsize_t nbytes,
const struct iovec *hdtrl, int flags);
#define nxt_sys_sendfile sendfile
#endif
ssize_t
nxt_hpux_event_conn_io_sendfile(nxt_event_conn_t *c, nxt_buf_t *b, size_t limit)
{
size_t file_size;
ssize_t n;
nxt_buf_t *fb;
nxt_err_t err;
nxt_uint_t nhd, ntr;
struct iovec iov[NXT_IOBUF_MAX], *hdtrl;
nxt_sendbuf_coalesce_t sb;
sb.buf = b;
sb.iobuf = iov;
sb.nmax = NXT_IOBUF_MAX;
sb.sync = 0;
sb.size = 0;
sb.limit = limit;
nhd = nxt_sendbuf_mem_coalesce(c->socket.task, &sb);
if (nhd == 0 && sb.sync) {
return 0;
}
if (nhd > 1 || sb.buf == NULL || !nxt_buf_is_file(sb.buf)) {
return nxt_event_conn_io_writev(c, iov, nhd);
}
fb = sb.buf;
file_size = nxt_sendbuf_file_coalesce(&sb);
if (file_size == 0) {
return nxt_event_conn_io_writev(c, iov, nhd);
}
sb.iobuf = &iov[1];
sb.nmax = 1;
ntr = nxt_sendbuf_mem_coalesce(c->socket.task, &sb);
/*
* Disposal of surplus kernel operations
* if there are no headers and trailers.
*/
if (nhd == 0) {
hdtrl = NULL;
iov[0].iov_base = NULL;
iov[0].iov_len = 0;
} else {
hdtrl = iov;
}
if (ntr == 0) {
iov[1].iov_base = NULL;
iov[1].iov_len = 0;
} else {
hdtrl = iov;
}
nxt_debug(c->socket.task, "sendfile(%d, %FD, @%O, %uz) hd:%ui tr:%ui",
c->socket.fd, fb->file->fd, fb->file_pos, file_size,
nhd, ntr);
n = nxt_sys_sendfile(c->socket.fd, fb->file->fd, fb->file_pos,
file_size, hdtrl, 0);
err = (n == -1) ? nxt_errno : 0;
nxt_debug(c->socket.task, "sendfile(): %uz", n);
if (n == -1) {
switch (err) {
case NXT_EAGAIN:
c->socket.write_ready = 0;
break;
case NXT_EINTR:
break;
default:
c->socket.error = err;
nxt_log(c->socket.task, nxt_socket_error_level(err),
"sendfile(%d, %FD, @%O, %uz) failed \"%FN\" hd:%ui tr:%ui",
c->socket.fd, fb->file_pos, file_size, &fb->file->name,
nhd, ntr);
return NXT_ERROR;
}
nxt_debug(c->socket.task, "sendfile() %E", err);
return 0;
}
if (n < (ssize_t) sb.size) {
c->socket.write_ready = 0;
}
return n;
}
|