[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
This commit is contained in:
parent
68284bd7f1
commit
0b02cd2690
1
NEWS
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
|
||||
|
|
|
@ -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)
|
||||
if ((r = send(fd, data, toSend, 0)) < 0) {
|
||||
r = send(fd, data, toSend, 0);
|
||||
#else /* __WIN32 */
|
||||
r = write(fd, data, toSend);
|
||||
#endif /* __WIN32 */
|
||||
sigbus_jmp_valid = 0;
|
||||
|
||||
#if defined(__WIN32)
|
||||
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…
Reference in New Issue