diff --git a/configure.ac b/configure.ac index e1959472..c8576a19 100644 --- a/configure.ac +++ b/configure.ac @@ -608,7 +608,7 @@ AM_CONDITIONAL(HAVE_SPDYLAY, [test "x$have_spdylay" = "xyes"]) # large file support (> 4 GB) AC_SYS_LARGEFILE AC_FUNC_FSEEKO -AC_CHECK_FUNCS([_lseeki64 lseek64]) +AC_CHECK_FUNCS([_lseeki64 lseek64 sendfile64]) # optional: have error messages ? AC_MSG_CHECKING(whether to generate error messages) diff --git a/src/include/platform.h b/src/include/platform.h index 22dddddf..472696b6 100644 --- a/src/include/platform.h +++ b/src/include/platform.h @@ -78,6 +78,10 @@ #endif /* !WIN32_LEAN_AND_MEAN */ #endif // _WIN32 +#if LINUX+0 && (defined(HAVE_SENDFILE64) || defined(HAVE_LSEEK64)) && ! defined(_LARGEFILE64_SOURCE) +#define _LARGEFILE64_SOURCE 1 +#endif + #include #include #include @@ -202,4 +206,12 @@ typedef MHD_socket MHD_pipe; #define IPPROTO_IPV6 IPPROTO_IPV6 #endif +#ifndef OFF_T_MAX +#define OFF_T_MAX ((off_t) ~(((uint64_t) 1) << (8 * sizeof(off_t) - 1))) +#endif + +#if defined(_LARGEFILE64_SOURCE) && !defined(OFF64_T_MAX) +#define OFF64_T_MAX ((off64_t) ~(((uint64_t) 1) << (8 * sizeof(off64_t) - 1))) +#endif + #endif diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 161d1011..b2a057b2 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c @@ -117,6 +117,10 @@ #define EPOLL_CLOEXEC 0 #endif +#ifndef INT32_MAX +#define INT32_MAX ((int32_t)0x7FFFFFFF) +#endif /* !INT32_MAX */ + /** * Default implementation of the panic function, @@ -1078,8 +1082,6 @@ send_param_adapter (struct MHD_Connection *connection, const size_t requested_size = i; #if LINUX MHD_socket fd; - off_t offset; - off_t left; #endif if ( (MHD_INVALID_SOCKET == connection->socket_fd) || @@ -1105,14 +1107,27 @@ send_param_adapter (struct MHD_Connection *connection, (-1 != (fd = connection->response->fd)) ) { /* can use sendfile */ - offset = (off_t) connection->response_write_position + connection->response->fd_off; + uint64_t left; +#ifndef HAVE_SENDFILE64 + uint64_t offsetu64; + off_t offset; +#else /* HAVE_SENDFILE64 */ + uint64_t offsetu64; + off64_t offset; +#endif /* HAVE_SENDFILE64 */ + offsetu64 = connection->response_write_position + connection->response->fd_off; left = connection->response->total_size - connection->response_write_position; if (i > left) i = left; - if (0 < (ret = sendfile (connection->socket_fd, - fd, - &offset, - i))) +#ifndef HAVE_SENDFILE64 + offset = (off_t) offsetu64; + if ( (offsetu64 <= (uint64_t)OFF_T_MAX) && + 0 < (ret = sendfile (connection->socket_fd, fd, &offset, i))) +#else /* HAVE_SENDFILE64 */ + offset = (off64_t) offsetu64; + if ( (offsetu64 <= (uint64_t)OFF64_T_MAX) && + 0 < (ret = sendfile64 (connection->socket_fd, fd, &offset, i))) +#endif /* HAVE_SENDFILE64 */ { #if EPOLL_SUPPORT if (requested_size > (size_t) ret)