3 #include "network_backends.h"
8 #include "stat_cache.h"
10 #include "sys-socket.h"
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
;
26 force_assert(NULL
!= c
);
27 force_assert(FILE_CHUNK
== c
->type
);
28 force_assert(c
->offset
>= 0 && c
->offset
<= c
->file
.length
);
30 offset
= c
->file
.start
+ c
->offset
;
31 toSend
= c
->file
.length
- c
->offset
;
33 if (-1 == c
->file
.fd
) {
34 stat_cache_entry
*sce
= NULL
;
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
);
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
);
45 fd_close_on_exec(c
->file
.fd
);
47 file_size
= sce
->st
.st_size
;
50 if (-1 == fstat(c
->file
.fd
, &st
)) {
51 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "fstat failed:", strerror(errno
));
54 file_size
= st
.st_size
;
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
);
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
;
70 force_assert(NULL
!= c
);
71 force_assert(FILE_CHUNK
== c
->type
);
72 force_assert(c
->offset
>= 0 && c
->offset
<= c
->file
.length
);
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
;
80 chunkqueue_remove_finished_chunks(cq
);
84 if (0 != network_open_file_chunk(srv
, con
, cq
)) return -1;
86 buffer_string_prepare_copy(srv
->tmp_buf
, toSend
);
88 if (-1 == lseek(c
->file
.fd
, offset
, SEEK_SET
)) {
89 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "lseek: ", strerror(errno
));
92 if (-1 == (toSend
= read(c
->file
.fd
, srv
->tmp_buf
->ptr
, toSend
))) {
93 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "read: ", strerror(errno
));
98 if ((r
= send(fd
, srv
->tmp_buf
->ptr
, toSend
, 0)) < 0) {
99 int lastError
= WSAGetLastError();
106 case WSAECONNABORTED
:
109 log_error_write(srv
, __FILE__
, __LINE__
, "sdd",
110 "send failed: ", lastError
, fd
);
115 if ((r
= write(fd
, srv
->tmp_buf
->ptr
, toSend
)) < 0) {
124 log_error_write(srv
, __FILE__
, __LINE__
, "ssd",
125 "write failed:", strerror(errno
), fd
);
133 chunkqueue_mark_written(cq
, r
);
136 return (r
> 0 && r
== toSend
) ? 0 : -3;