Annotation of embedaddon/lighttpd/src/network_write_no_mmap.c, revision 1.1.1.1
1.1 misho 1: #include "first.h"
2:
3: #include "network_backends.h"
4:
5: #include "network.h"
6: #include "fdevent.h"
7: #include "log.h"
8: #include "stat_cache.h"
9:
10: #include "sys-socket.h"
11:
12: #include <sys/time.h>
13: #include <stdlib.h>
14:
15: #include <fcntl.h>
16: #include <sys/stat.h>
17: #include <unistd.h>
18:
19: #include <errno.h>
20: #include <string.h>
21:
22: int network_open_file_chunk(server *srv, connection *con, chunkqueue *cq) {
23: chunk* const c = cq->first;
24: off_t file_size, offset, toSend;
25:
26: force_assert(NULL != c);
27: force_assert(FILE_CHUNK == c->type);
28: force_assert(c->offset >= 0 && c->offset <= c->file.length);
29:
30: offset = c->file.start + c->offset;
31: toSend = c->file.length - c->offset;
32:
33: if (-1 == c->file.fd) {
34: stat_cache_entry *sce = NULL;
35:
36: if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) {
37: log_error_write(srv, __FILE__, __LINE__, "ssb", "stat-cache failed:", strerror(errno), c->file.name);
38: return -1;
39: }
40:
41: if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY|O_NOCTTY))) {
42: log_error_write(srv, __FILE__, __LINE__, "ssb", "open failed:", strerror(errno), c->file.name);
43: return -1;
44: }
45: fd_close_on_exec(c->file.fd);
46:
47: file_size = sce->st.st_size;
48: } else {
49: struct stat st;
50: if (-1 == fstat(c->file.fd, &st)) {
51: log_error_write(srv, __FILE__, __LINE__, "ss", "fstat failed:", strerror(errno));
52: return -1;
53: }
54: file_size = st.st_size;
55: }
56:
57: if (offset > file_size || toSend > file_size || offset > file_size - toSend) {
58: log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
59: return -1;
60: }
61:
62: return 0;
63: }
64:
65: int network_write_file_chunk_no_mmap(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes) {
66: chunk* const c = cq->first;
67: off_t offset, toSend;
68: ssize_t r;
69:
70: force_assert(NULL != c);
71: force_assert(FILE_CHUNK == c->type);
72: force_assert(c->offset >= 0 && c->offset <= c->file.length);
73:
74: offset = c->file.start + c->offset;
75: toSend = c->file.length - c->offset;
76: if (toSend > 64*1024) toSend = 64*1024; /* max read 64kb in one step */
77: if (toSend > *p_max_bytes) toSend = *p_max_bytes;
78:
79: if (0 == toSend) {
80: chunkqueue_remove_finished_chunks(cq);
81: return 0;
82: }
83:
84: if (0 != network_open_file_chunk(srv, con, cq)) return -1;
85:
86: buffer_string_prepare_copy(srv->tmp_buf, toSend);
87:
88: if (-1 == lseek(c->file.fd, offset, SEEK_SET)) {
89: log_error_write(srv, __FILE__, __LINE__, "ss", "lseek: ", strerror(errno));
90: return -1;
91: }
92: if (-1 == (toSend = read(c->file.fd, srv->tmp_buf->ptr, toSend))) {
93: log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
94: return -1;
95: }
96:
97: #if defined(__WIN32)
98: if ((r = send(fd, srv->tmp_buf->ptr, toSend, 0)) < 0) {
99: int lastError = WSAGetLastError();
100: switch (lastError) {
101: case WSAEINTR:
102: case WSAEWOULDBLOCK:
103: break;
104: case WSAECONNRESET:
105: case WSAETIMEDOUT:
106: case WSAECONNABORTED:
107: return -2;
108: default:
109: log_error_write(srv, __FILE__, __LINE__, "sdd",
110: "send failed: ", lastError, fd);
111: return -1;
112: }
113: }
114: #else /* __WIN32 */
115: if ((r = write(fd, srv->tmp_buf->ptr, toSend)) < 0) {
116: switch (errno) {
117: case EAGAIN:
118: case EINTR:
119: break;
120: case EPIPE:
121: case ECONNRESET:
122: return -2;
123: default:
124: log_error_write(srv, __FILE__, __LINE__, "ssd",
125: "write failed:", strerror(errno), fd);
126: return -1;
127: }
128: }
129: #endif /* __WIN32 */
130:
131: if (r >= 0) {
132: *p_max_bytes -= r;
133: chunkqueue_mark_written(cq, r);
134: }
135:
136: return (r > 0 && r == toSend) ? 0 : -3;
137: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>