Annotation of embedaddon/lighttpd/src/network_write.c, revision 1.1.1.2

1.1       misho       1: #include "network_backends.h"
                      2: 
                      3: #include "network.h"
                      4: #include "fdevent.h"
                      5: #include "log.h"
                      6: #include "stat_cache.h"
                      7: 
                      8: #include "sys-socket.h"
                      9: 
                     10: #include <sys/types.h>
                     11: #include <sys/stat.h>
                     12: #include <sys/time.h>
                     13: #include <errno.h>
                     14: #include <fcntl.h>
                     15: #include <unistd.h>
                     16: #include <string.h>
                     17: #include <stdlib.h>
                     18: 
                     19: #ifdef HAVE_SYS_FILIO_H
                     20: # include <sys/filio.h>
                     21: #endif
                     22: 
                     23: #ifdef HAVE_SYS_RESOURCE_H
                     24: # include <sys/resource.h>
                     25: #endif
                     26: 
                     27: int network_write_chunkqueue_write(server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes) {
                     28:        chunk *c;
                     29: 
                     30:        for(c = cq->first; (max_bytes > 0) && (NULL != c); c = c->next) {
                     31:                int chunk_finished = 0;
                     32: 
                     33:                switch(c->type) {
                     34:                case MEM_CHUNK: {
                     35:                        char * offset;
                     36:                        off_t toSend;
                     37:                        ssize_t r;
                     38: 
                     39:                        if (c->mem->used == 0) {
                     40:                                chunk_finished = 1;
                     41:                                break;
                     42:                        }
                     43: 
                     44:                        offset = c->mem->ptr + c->offset;
                     45:                        toSend = c->mem->used - 1 - c->offset;
                     46:                        if (toSend > max_bytes) toSend = max_bytes;
                     47: 
                     48: #ifdef __WIN32
                     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);
                     52: 
                     53:                                return -1;
                     54:                        }
                     55: #else
                     56:                        if ((r = write(fd, offset, toSend)) < 0) {
                     57:                                switch (errno) {
                     58:                                case EAGAIN:
                     59:                                case EINTR:
                     60:                                        r = 0;
                     61:                                        break;
                     62:                                case EPIPE:
                     63:                                case ECONNRESET:
                     64:                                        return -2;
                     65:                                default:
                     66:                                        log_error_write(srv, __FILE__, __LINE__, "ssd",
                     67:                                                "write failed:", strerror(errno), fd);
                     68: 
                     69:                                        return -1;
                     70:                                }
                     71:                        }
                     72: #endif
                     73: 
                     74:                        c->offset += r;
                     75:                        cq->bytes_out += r;
                     76:                        max_bytes -= r;
                     77: 
                     78:                        if (c->offset == (off_t)c->mem->used - 1) {
                     79:                                chunk_finished = 1;
                     80:                        }
                     81: 
                     82:                        break;
                     83:                }
                     84:                case FILE_CHUNK: {
                     85: #ifdef USE_MMAP
                     86:                        char *p = NULL;
                     87: #endif
                     88:                        ssize_t r;
                     89:                        off_t offset;
                     90:                        off_t toSend;
                     91:                        stat_cache_entry *sce = NULL;
                     92:                        int ifd;
                     93: 
                     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);
                     97:                                return -1;
                     98:                        }
                     99: 
                    100:                        offset = c->file.start + c->offset;
                    101:                        toSend = c->file.length - c->offset;
                    102: 
                    103:                        if (toSend > max_bytes) toSend = max_bytes;
                    104: 
                    105:                        if (offset > sce->st.st_size) {
                    106:                                log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name);
                    107: 
                    108:                                return -1;
                    109:                        }
                    110: 
                    111:                        if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) {
                    112:                                log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno));
                    113: 
                    114:                                return -1;
                    115:                        }
                    116: 
                    117: #ifdef USE_MMAP
                    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));
                    120: 
                    121:                                close(ifd);
                    122: 
                    123:                                return -1;
                    124:                        }
                    125:                        close(ifd);
                    126: 
                    127:                        if ((r = write(fd, p + offset, toSend)) <= 0) {
                    128:                                switch (errno) {
                    129:                                case EAGAIN:
                    130:                                case EINTR:
                    131:                                        r = 0;
                    132:                                        break;
                    133:                                case EPIPE:
                    134:                                case ECONNRESET:
                    135:                                        munmap(p, sce->st.st_size);
                    136:                                        return -2;
                    137:                                default:
                    138:                                        log_error_write(srv, __FILE__, __LINE__, "ssd",
                    139:                                                "write failed:", strerror(errno), fd);
                    140:                                        munmap(p, sce->st.st_size);
                    141: 
                    142:                                        return -1;
                    143:                                }
                    144:                        }
                    145: 
                    146:                        munmap(p, sce->st.st_size);
                    147: #else /* USE_MMAP */
                    148:                        buffer_prepare_copy(srv->tmp_buf, toSend);
                    149: 
1.1.1.2 ! misho     150:                        if (-1 == lseek(ifd, offset, SEEK_SET)) {
        !           151:                                log_error_write(srv, __FILE__, __LINE__, "ss", "lseek: ", strerror(errno));
        !           152:                                close(ifd);
        !           153:                                return -1;
        !           154:                        }
1.1       misho     155:                        if (-1 == (toSend = read(ifd, srv->tmp_buf->ptr, toSend))) {
                    156:                                log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
                    157:                                close(ifd);
                    158:                                return -1;
                    159:                        }
                    160:                        close(ifd);
                    161: 
                    162: #ifdef __WIN32
                    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);
                    166: 
                    167:                                return -1;
                    168:                        }
                    169: #else /* __WIN32 */
                    170:                        if ((r = write(fd, srv->tmp_buf->ptr, toSend)) < 0) {
                    171:                                switch (errno) {
                    172:                                case EAGAIN:
                    173:                                case EINTR:
                    174:                                        r = 0;
                    175:                                        break;
                    176:                                case EPIPE:
                    177:                                case ECONNRESET:
                    178:                                        return -2;
                    179:                                default:
                    180:                                        log_error_write(srv, __FILE__, __LINE__, "ssd",
                    181:                                                "write failed:", strerror(errno), fd);
                    182: 
                    183:                                        return -1;
                    184:                                }
                    185:                        }
                    186: #endif /* __WIN32 */
                    187: #endif /* USE_MMAP */
                    188: 
                    189:                        c->offset += r;
                    190:                        cq->bytes_out += r;
                    191:                        max_bytes -= r;
                    192: 
                    193:                        if (c->offset == c->file.length) {
                    194:                                chunk_finished = 1;
                    195:                        }
                    196: 
                    197:                        break;
                    198:                }
                    199:                default:
                    200: 
                    201:                        log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
                    202: 
                    203:                        return -1;
                    204:                }
                    205: 
                    206:                if (!chunk_finished) {
                    207:                        /* not finished yet */
                    208: 
                    209:                        break;
                    210:                }
                    211:        }
                    212: 
                    213:        return 0;
                    214: }
                    215: 
                    216: #if 0
                    217: network_write_init(void) {
                    218:        p->write = network_write_write_chunkset;
                    219: }
                    220: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>