Changeset 1934

Show
Ignore:
Timestamp:
08/17/2007 10:22:32 PM (11 months ago)
Author:
jan
Message:

fixed endless loop on shrinked files on *BSD (fixes #1289)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/network_freebsd_sendfile.c

    r1493 r1934  
    8282                                ((1 << 30) - 1) : c->file.length - c->offset; 
    8383 
    84                         if (offset > sce->st.st_size) { 
    85                                 log_error_write(srv, __FILE__, __LINE__, "sb", "file was shrinked:", c->file.name); 
     84                        if (-1 == c->file.fd) { 
     85                                if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY))) { 
     86                                        switch (errno) { 
     87                                        case EMFILE: 
     88                                                return NETWORK_STATUS_WAIT_FOR_FD; 
     89                                        default: 
     90                                                ERROR("opening '%s' failed: %s", BUF_STR(c->file.name), strerror(errno)); 
    8691 
    87                                 return NETWORK_STATUS_FATAL_ERROR; 
    88                        
     92                                               return NETWORK_STATUS_FATAL_ERROR; 
     93                                       
    8994 
    90                         if (-1 == (ifd = open(c->file.name->ptr, O_RDONLY))) { 
    91                                 log_error_write(srv, __FILE__, __LINE__, "ss", "open failed: ", strerror(errno)); 
    92  
    93                                 return NETWORK_STATUS_FATAL_ERROR; 
     95                                        return NETWORK_STATUS_FATAL_ERROR; 
     96                                } 
    9497                        } 
    9598 
     
    97100 
    98101                        /* FreeBSD sendfile() */ 
    99                         if (-1 == sendfile(ifd, sock->fd, offset, toSend, NULL, &r, 0)) { 
     102                        if (-1 == sendfile(c->file.fd, sock->fd, offset, toSend, NULL, &r, 0)) { 
    100103                                switch(errno) { 
    101104                                case EAGAIN: 
     
    110113                                } 
    111114                        } 
    112                         close(ifd); 
     115 
     116                        if (r == 0) { 
     117                                /* We got an event to write but we wrote nothing 
     118                                 * 
     119                                 * - the file shrinked -> error 
     120                                 * - the remote side closed inbetween -> remote-close */ 
     121 
     122                                if (HANDLER_ERROR == stat_cache_get_entry(srv, con, c->file.name, &sce)) { 
     123                                        /* file is gone ? */ 
     124                                        return NETWORK_STATUS_FATAL_ERROR; 
     125                                } 
     126 
     127                                if (offset > sce->st.st_size) { 
     128                                        /* file shrinked, close the connection */ 
     129                                        return NETWORK_STATUS_FATAL_ERROR; 
     130                                } 
     131 
     132                                return NETWORK_STATUS_CONNECTION_CLOSE; 
     133                        } 
    113134 
    114135                        c->offset += r; 
     
    122143                } 
    123144                default: 
    124  
    125                         log_error_write(srv, __FILE__, __LINE__, "ds", c, "type not known"); 
     145                        ERROR("chunk-type '%d' not known", c->type); 
    126146 
    127147                        return NETWORK_STATUS_FATAL_ERROR;