1 #include "network_backends.h"
6 #include "stat_cache.h"
8 #include "sys-socket.h"
10 #include <sys/types.h>
19 #ifdef HAVE_SYS_FILIO_H
20 # include <sys/filio.h>
23 #ifdef HAVE_SYS_RESOURCE_H
24 # include <sys/resource.h>
27 int network_write_chunkqueue_write(server
*srv
, connection
*con
, int fd
, chunkqueue
*cq
, off_t max_bytes
) {
30 for(c
= cq
->first
; (max_bytes
> 0) && (NULL
!= c
); c
= c
->next
) {
31 int chunk_finished
= 0;
39 if (buffer_string_is_empty(c
->mem
)) {
44 offset
= c
->mem
->ptr
+ c
->offset
;
45 toSend
= buffer_string_length(c
->mem
) - c
->offset
;
46 if (toSend
> max_bytes
) toSend
= max_bytes
;
49 if ((r
= send(fd
, offset
, toSend
, 0)) < 0) {
50 /* no error handling for windows... */
51 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "send failed: ", strerror(errno
), fd
);
56 if ((r
= write(fd
, offset
, toSend
)) < 0) {
66 log_error_write(srv
, __FILE__
, __LINE__
, "ssd",
67 "write failed:", strerror(errno
), fd
);
78 if (c
->offset
== (off_t
)buffer_string_length(c
->mem
)) {
91 stat_cache_entry
*sce
= NULL
;
94 if (HANDLER_ERROR
== stat_cache_get_entry(srv
, con
, c
->file
.name
, &sce
)) {
95 log_error_write(srv
, __FILE__
, __LINE__
, "sb",
96 strerror(errno
), c
->file
.name
);
100 offset
= c
->file
.start
+ c
->offset
;
101 toSend
= c
->file
.length
- c
->offset
;
103 if (toSend
> max_bytes
) toSend
= max_bytes
;
105 if (offset
> sce
->st
.st_size
) {
106 log_error_write(srv
, __FILE__
, __LINE__
, "sb", "file was shrinked:", c
->file
.name
);
111 if (-1 == (ifd
= open(c
->file
.name
->ptr
, O_RDONLY
))) {
112 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "open failed: ", strerror(errno
));
118 if (MAP_FAILED
== (p
= mmap(0, sce
->st
.st_size
, PROT_READ
, MAP_SHARED
, ifd
, 0))) {
119 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "mmap failed: ", strerror(errno
));
127 if ((r
= write(fd
, p
+ offset
, toSend
)) <= 0) {
135 munmap(p
, sce
->st
.st_size
);
138 log_error_write(srv
, __FILE__
, __LINE__
, "ssd",
139 "write failed:", strerror(errno
), fd
);
140 munmap(p
, sce
->st
.st_size
);
146 munmap(p
, sce
->st
.st_size
);
148 buffer_string_prepare_copy(srv
->tmp_buf
, toSend
);
150 if (-1 == lseek(ifd
, offset
, SEEK_SET
)) {
151 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "lseek: ", strerror(errno
));
155 if (-1 == (toSend
= read(ifd
, srv
->tmp_buf
->ptr
, toSend
))) {
156 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "read: ", strerror(errno
));
163 if ((r
= send(fd
, srv
->tmp_buf
->ptr
, toSend
, 0)) < 0) {
164 /* no error handling for windows... */
165 log_error_write(srv
, __FILE__
, __LINE__
, "ssd", "send failed: ", strerror(errno
), fd
);
170 if ((r
= write(fd
, srv
->tmp_buf
->ptr
, toSend
)) < 0) {
180 log_error_write(srv
, __FILE__
, __LINE__
, "ssd",
181 "write failed:", strerror(errno
), fd
);
187 #endif /* USE_MMAP */
193 if (c
->offset
== c
->file
.length
) {
201 log_error_write(srv
, __FILE__
, __LINE__
, "ds", c
, "type not known");
206 if (!chunk_finished
) {
207 /* not finished yet */
217 network_write_init(void) {
218 p
->write
= network_write_write_chunkset
;