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

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: 
                    150:                        lseek(ifd, offset, SEEK_SET);
                    151:                        if (-1 == (toSend = read(ifd, srv->tmp_buf->ptr, toSend))) {
                    152:                                log_error_write(srv, __FILE__, __LINE__, "ss", "read: ", strerror(errno));
                    153:                                close(ifd);
                    154: 
                    155:                                return -1;
                    156:                        }
                    157:                        close(ifd);
                    158: 
                    159: #ifdef __WIN32
                    160:                        if ((r = send(fd, srv->tmp_buf->ptr, toSend, 0)) < 0) {
                    161:                                /* no error handling for windows... */
                    162:                                log_error_write(srv, __FILE__, __LINE__, "ssd", "send failed: ", strerror(errno), fd);
                    163: 
                    164:                                return -1;
                    165:                        }
                    166: #else /* __WIN32 */
                    167:                        if ((r = write(fd, srv->tmp_buf->ptr, toSend)) < 0) {
                    168:                                switch (errno) {
                    169:                                case EAGAIN:
                    170:                                case EINTR:
                    171:                                        r = 0;
                    172:                                        break;
                    173:                                case EPIPE:
                    174:                                case ECONNRESET:
                    175:                                        return -2;
                    176:                                default:
                    177:                                        log_error_write(srv, __FILE__, __LINE__, "ssd",
                    178:                                                "write failed:", strerror(errno), fd);
                    179: 
                    180:                                        return -1;
                    181:                                }
                    182:                        }
                    183: #endif /* __WIN32 */
                    184: #endif /* USE_MMAP */
                    185: 
                    186:                        c->offset += r;
                    187:                        cq->bytes_out += r;
                    188:                        max_bytes -= r;
                    189: 
                    190:                        if (c->offset == c->file.length) {
                    191:                                chunk_finished = 1;
                    192:                        }
                    193: 
                    194:                        break;
                    195:                }
                    196:                default:
                    197: 
                    198:                        log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known");
                    199: 
                    200:                        return -1;
                    201:                }
                    202: 
                    203:                if (!chunk_finished) {
                    204:                        /* not finished yet */
                    205: 
                    206:                        break;
                    207:                }
                    208:        }
                    209: 
                    210:        return 0;
                    211: }
                    212: 
                    213: #if 0
                    214: network_write_init(void) {
                    215:        p->write = network_write_write_chunkset;
                    216: }
                    217: #endif

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