Browse Source

[mod_cgi] use splice() to send input to CGI

use splice(), if available (Linux), to send input from temp files to CGI
master
Glenn Strauss 7 months ago
parent
commit
a3ccc46be1
  1. 17
      src/mod_cgi.c

17
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) {

Loading…
Cancel
Save