Browse Source

[mmap] handle SIGBUS in network; those get triggered if the file gets smaller during reading

From: Stefan Bühler <stbuehler@web.de>

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3031 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.37
Stefan Bühler 6 years ago
parent
commit
0b02cd2690
  1. 1
      NEWS
  2. 43
      src/network_write_mmap.c

1
NEWS

@ -17,6 +17,7 @@ NEWS
* [mod_cgi] rewrite mmap and generic (post body) send error handling
* [mmap] fix mmap alignment
* [plugins] when modules are linked statically still only load the modules given in the config
* [mmap] handle SIGBUS in network; those get triggered if the file gets smaller during reading
- 1.4.36 - 2015-07-26
* use keep-alive timeout while waiting for HTTP headers; use always the read timeout while waiting for the HTTP body

43
src/network_write_mmap.c

@ -4,6 +4,8 @@
#include "log.h"
#include "sys-mmap.h"
#include <setjmp.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
@ -23,6 +25,15 @@ off_t mmap_align_offset(off_t start) {
#if defined(USE_MMAP)
static volatile int sigbus_jmp_valid;
static sigjmp_buf sigbus_jmp;
static void sigbus_handler(int sig) {
UNUSED(sig);
if (sigbus_jmp_valid) siglongjmp(sigbus_jmp, 1);
log_failed_assert(__FILE__, __LINE__, "SIGBUS");
}
#if 0
/* read mmap()ed data into local buffer */
#define LOCAL_BUFFERING 1
@ -51,6 +62,24 @@ int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkque
if (0 != network_open_file_chunk(srv, con, cq)) return -1;
/* setup SIGBUS handler, but don't activate sigbus_jmp_valid yet */
if (0 != sigsetjmp(sigbus_jmp, 1)) {
sigbus_jmp_valid = 0;
log_error_write(srv, __FILE__, __LINE__, "sbd", "SIGBUS in mmap:",
c->file.name, c->file.fd);
munmap(c->file.mmap.start, c->file.mmap.length);
c->file.mmap.start = MAP_FAILED;
#ifdef LOCAL_BUFFERING
buffer_reset(c->mem);
#endif
return -1;
}
signal(SIGBUS, sigbus_handler);
/* mmap the buffer if offset is outside old mmap area or not mapped at all */
if (MAP_FAILED == c->file.mmap.start
|| offset < c->file.mmap.offset
@ -97,7 +126,9 @@ int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkque
}
#if defined(LOCAL_BUFFERING)
sigbus_jmp_valid = 1;
buffer_copy_string_len(c->mem, c->file.mmap.start, c->file.mmap.length);
sigbus_jmp_valid = 0;
#else
# if defined(HAVE_MADVISE)
/* don't advise files < 64Kb */
@ -124,8 +155,16 @@ int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkque
data = c->file.mmap.start + mmap_offset;
#endif
sigbus_jmp_valid = 1;
#if defined(__WIN32)
r = send(fd, data, toSend, 0);
#else /* __WIN32 */
r = write(fd, data, toSend);
#endif /* __WIN32 */
sigbus_jmp_valid = 0;
#if defined(__WIN32)
if ((r = send(fd, data, toSend, 0)) < 0) {
if (r < 0) {
int lastError = WSAGetLastError();
switch (lastError) {
case WSAEINTR:
@ -142,7 +181,7 @@ int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkque
}
}
#else /* __WIN32 */
if ((r = write(fd, data, toSend)) < 0) {
if (r < 0) {
switch (errno) {
case EAGAIN:
case EINTR:

Loading…
Cancel
Save