diff -r 8a0a7754f123 -r c93be34fde76 src/server/util/io.c --- a/src/server/util/io.c Sat Oct 31 20:10:21 2015 +0100 +++ b/src/server/util/io.c Mon Nov 02 11:13:38 2015 +0000 @@ -34,9 +34,16 @@ #include #include #include + #ifndef BSD #include +#else +#if defined(__NetBSD__) || defined(__OpenBSD__) +#define WS_NO_SENDFILE +#define net_stream_sendfile net_fallback_sendfile #endif +#endif + #include /* asprintf */ #include "../daemon/vfs.h" @@ -145,6 +152,7 @@ return r; } +#ifndef WS_NO_SENDFILE ssize_t net_stream_sendfile(NetIOStream *st, sendfiledata *sfd) { ssize_t ret = 0; off_t fileoffset = sfd->offset; @@ -191,6 +199,7 @@ return ret; } +#endif void net_stream_close(NetIOStream *st) { close(st->fd); @@ -285,66 +294,7 @@ } else { // stream/file does not support sendfile // do regular copy - char *buf = malloc(4096); - if(!buf) { - // TODO: out of memory error - return IO_ERROR; - } - char *header = (char*)sfd->header; - int hlen = sfd->hlen; - char *trailer = (char*)sfd->trailer; - int tlen = sfd->tlen; - if(header == NULL) { - hlen = 0; - } - if(trailer == NULL) { - tlen = 0; - } - - ssize_t r; - while(hlen > 0) { - r = out->st.write(fd, header, hlen); - header += r; - hlen -= r; - if(r <= 0) { - free(buf); - return IO_ERROR; - } - } - - if(system_lseek(sfd->fd, sfd->offset, SEEK_SET) == -1) { - free(buf); - return IO_ERROR; - } - - size_t length = sfd->len; - while(length > 0) { - if((r = system_fread(sfd->fd, buf, 4096)) <= 0) { - break; - } - char *write_buf = buf; - while(r > 0) { - ssize_t w = out->st.write(fd, write_buf, r); - r -= w; - length -= w; - write_buf += w; - } - } - free(buf); - if(length > 0) { - return IO_ERROR; - } - - while(tlen > 0) { - r = out->st.write(fd, trailer, tlen); - trailer += r; - tlen -= r; - if(r <= 0) { - return IO_ERROR; - } - } - - return sfd->hlen + sfd->len + sfd->tlen; + return net_fallback_sendfile(fd, sfd); } return IO_ERROR; } @@ -363,6 +313,72 @@ } +ssize_t net_fallback_sendfile(NetIOStream *st, sendfiledata *sfd) { + SYS_NETFD fd = st; + + char *buf = malloc(4096); + if(!buf) { + // TODO: out of memory error + return IO_ERROR; + } + char *header = (char*)sfd->header; + int hlen = sfd->hlen; + char *trailer = (char*)sfd->trailer; + int tlen = sfd->tlen; + if(header == NULL) { + hlen = 0; + } + if(trailer == NULL) { + tlen = 0; + } + + ssize_t r; + while(hlen > 0) { + r = st->st.write(fd, header, hlen); + header += r; + hlen -= r; + if(r <= 0) { + free(buf); + return IO_ERROR; + } + } + + if(system_lseek(sfd->fd, sfd->offset, SEEK_SET) == -1) { + free(buf); + return IO_ERROR; + } + + size_t length = sfd->len; + while(length > 0) { + if((r = system_fread(sfd->fd, buf, 4096)) <= 0) { + break; + } + char *write_buf = buf; + while(r > 0) { + ssize_t w = st->st.write(fd, write_buf, r); + r -= w; + length -= w; + write_buf += w; + } + } + free(buf); + if(length > 0) { + return IO_ERROR; + } + + while(tlen > 0) { + r = st->st.write(fd, trailer, tlen); + trailer += r; + tlen -= r; + if(r <= 0) { + return IO_ERROR; + } + } + + return sfd->hlen + sfd->len + sfd->tlen; +} + + /* iovec buffer */ iovec_buf_t *iovec_buf_create(pool_handle_t *pool) { iovec_buf_t *buf = pool_malloc(pool, sizeof(iovec_buf_t));