diff --git a/src/mod_cgi.c b/src/mod_cgi.c index d7d12bd5..7659281d 100644 --- a/src/mod_cgi.c +++ b/src/mod_cgi.c @@ -526,6 +526,7 @@ static int cgi_env_add(void *venv, const char *key, size_t key_len, const char * return 0; } +#ifndef SPLICE_F_NONBLOCK /*(improved from network_write_mmap.c)*/ static off_t mmap_align_offset(off_t start) { static off_t pagemask = 0; @@ -536,6 +537,7 @@ static off_t mmap_align_offset(off_t start) { } return (start & pagemask); } +#endif /* returns: 0: continue, -1: fatal error, -2: connection reset */ /* similar to network_write_file_chunk_mmap, but doesn't use send on windows (because we're on pipes), @@ -546,10 +548,8 @@ static off_t mmap_align_offset(off_t start) { */ static ssize_t cgi_write_file_chunk_mmap(request_st * const r, int fd, chunkqueue *cq) { chunk* const c = cq->first; - off_t offset, toSend, file_end; + off_t offset, toSend; ssize_t wr; - size_t mmap_offset, mmap_avail; - char *data = NULL; force_assert(NULL != c); force_assert(FILE_CHUNK == c->type); @@ -557,13 +557,21 @@ static ssize_t cgi_write_file_chunk_mmap(request_st * const r, int fd, chunkqueu offset = c->file.start + c->offset; toSend = c->file.length - c->offset; - file_end = c->file.start + c->file.length; /* offset to file end in this chunk */ if (0 == toSend) { chunkqueue_remove_finished_chunks(cq); return 0; } + #ifdef SPLICE_F_NONBLOCK + loff_t abs_offset = offset; + wr = splice(c->file.fd, &abs_offset, fd, NULL, + (size_t)toSend, SPLICE_F_NONBLOCK); + #else + size_t mmap_offset, mmap_avail; + char *data = NULL; + off_t file_end = c->file.start + c->file.length; /* offset to file end in this chunk */ + /*(simplified from chunk.c:chunkqueue_open_file_chunk())*/ if (-1 == c->file.fd) { if (-1 == (c->file.fd = fdevent_open_cloexec(c->mem->ptr, r->conf.follow_symlink, O_RDONLY, 0))) { @@ -619,6 +627,7 @@ static ssize_t cgi_write_file_chunk_mmap(request_st * const r, int fd, chunkqueu wr = write(fd, data, toSend); if (MAP_FAILED == c->file.mmap.start) free(data); + #endif if (wr < 0) { switch (errno) {