Changeset 1933

Show
Ignore:
Timestamp:
08/17/2007 10:18:18 PM (14 months ago)
Author:
jan
Message:

fixed endless loop on shrinked files with sendfile() on BSD

- merged the shrinked file handling from linux-sendfile

Location:
branches/lighttpd-1.4.x
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • branches/lighttpd-1.4.x/NEWS

    r1929 r1933  
    1515  * fixed invalid char in header values (#1286) 
    1616  * fixed invalid "304 Not Modified" on broken timestamps 
     17  * fixed endless loop on shrinked files with sendfile() on BSD (#1289) 
    1718 
    1819- 1.4.16 -  
  • branches/lighttpd-1.4.x/src/network_freebsd_sendfile.c

    r1492 r1933  
    137137                        size_t toSend; 
    138138                        stat_cache_entry *sce = NULL; 
    139                         int ifd; 
    140139 
    141140                        if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { 
     
    150149                                ((1 << 30) - 1) : c->file.length - c->offset; 
    151150 
    152                         if (offset > sce->st.st_size) { 
    153                                 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name); 
    154  
    155                                 return -1; 
    156                         } 
    157  
    158                         if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) { 
    159                                 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); 
    160  
    161                                 return -1; 
     151                        if (-1 == c->file.fd) { 
     152                                if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { 
     153                                        log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); 
     154 
     155                                        return -1; 
     156                                } 
     157 
     158#ifdef FD_CLOEXEC 
     159                                fcntl(c->file.fd, F_SETFD, FD_CLOEXEC); 
     160#endif 
    162161                        } 
    163162 
     
    165164 
    166165                        /* FreeBSD sendfile() */ 
    167                         if (-1 == sendfile(ifd, fd, offset, toSend, NULL, &r, 0)) { 
     166                        if (-1 == sendfile(c->file.fd, fd, offset, toSend, NULL, &r, 0)) { 
    168167                                switch(errno) { 
    169168                                case EAGAIN: 
     
    178177                                } 
    179178                        } 
    180                         close(ifd); 
     179 
     180                        if (r == 0) { 
     181                                int oerrno = errno; 
     182                                /* We got an event to write but we wrote nothing 
     183                                 * 
     184                                 * - the file shrinked -> error 
     185                                 * - the remote side closed inbetween -> remote-close */ 
     186 
     187                                if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { 
     188                                        /* file is gone ? */ 
     189                                        return -1; 
     190                                } 
     191 
     192                                if (offset >= sce->st.st_size) { 
     193                                        /* file shrinked, close the connection */ 
     194                                        errno = oerrno; 
     195 
     196                                        return -1; 
     197                                } 
     198 
     199                                errno = oerrno; 
     200                                return -2; 
     201                        } 
    181202 
    182203                        c->offset += r;