Annotation of embedaddon/lighttpd/src/network_write_no_mmap.c, revision 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>