libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit ec204f59a7466ca6f4f91b4db1a42e0e0c525907
parent 73da168180856c913ae2bb32a5780d9c06112e8d
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Mon,  6 Nov 2017 23:31:26 +0300

Added support for Solaris-style sendfile

Diffstat:
Mconfigure.ac | 47+++++++++++++++++++++++++++++++++++++++++++++++
Msrc/include/mhd_options.h | 4++++
Msrc/microhttpd/connection.c | 44++++++++++++++++++++++++++++++--------------
Msrc/microhttpd/internal.h | 4++--
4 files changed, 83 insertions(+), 16 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -1312,6 +1312,53 @@ int sendfile(int, int, off_t, size_t, ] ) +AS_VAR_IF([[found_sendfile]], [["no"]], + [ + AC_MSG_CHECKING([[for Solaris-style sendfile(3)]]) + SAVE_LIBS="$LIBS" + LIBS="$LIBS -lsendfile" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/sendfile.h> + +static void empty_func(void) +{ +/* Check for declaration */ + (void)sendfile; +} +/* Declare again to check form match */ +ssize_t sendfile(int out_fd, int in_fd, + off_t *off, size_t len); + ]], + [[ + int fd1=0, fd2=1; + off_t o = 0; + size_t l = 5; + ssize_t r; + r = sendfile (fd1, fd2, &o, l); + if (r) + empty_func(); + ]] + ) + ], + [ + AC_DEFINE([HAVE_SOLARIS_SENDFILE], [1], [Define to 1 if you have Solaris-style sendfile(3).]) + found_sendfile="yes, Solaris-style" + MHD_LIBDEPS="-lsendfile $MHD_LIBDEPS" + MHD_LIBDEPS_PKGCFG="-lsendfile $MHD_LIBDEPS_PKGCFG" + AC_MSG_RESULT([[yes]]) + AC_CHECK_FUNCS([sendfile64]) + ], + [AC_MSG_RESULT([[no]]) + ] + ) + LIBS="$SAVE_LIBS" + ] +) + # optional: have error messages ? AC_MSG_CHECKING([[whether to generate error messages]]) AC_ARG_ENABLE([messages], diff --git a/src/include/mhd_options.h b/src/include/mhd_options.h @@ -65,6 +65,10 @@ #define _MHD_FD_SETSIZE_IS_DEFAULT 1 #endif /* !FD_SETSIZE && !WinSock*/ +#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_SOLARIS_SENDFILE) +#define MHD_LINUX_SOLARIS_SENDFILE 1 +#endif /* HAVE_LINUX_SENDFILE || HAVE_SOLARIS_SENDFILE */ + #if OS390 #define _OPEN_THREADS #define _OPEN_SYS_SOCK_IPV6 diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -36,9 +36,9 @@ #include "mhd_sockets.h" #include "mhd_compat.h" #include "mhd_itc.h" -#ifdef HAVE_LINUX_SENDFILE +#ifdef MHD_LINUX_SOLARIS_SENDFILE #include <sys/sendfile.h> -#endif /* HAVE_LINUX_SENDFILE */ +#endif /* MHD_LINUX_SOLARIS_SENDFILE */ #ifdef HAVE_FREEBSD_SENDFILE #include <sys/types.h> #include <sys/socket.h> @@ -272,7 +272,7 @@ send_param_adapter (struct MHD_Connection *connection, } -#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) +#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) /** * Function for sending responses backed by file FD. * @@ -291,13 +291,13 @@ sendfile_adapter (struct MHD_Connection *connection) #else /* HAVE_SENDFILE64 */ const uint64_t max_off_t = (uint64_t)OFF64_T_MAX; #endif /* HAVE_SENDFILE64 */ -#ifdef HAVE_LINUX_SENDFILE +#ifdef MHD_LINUX_SOLARIS_SENDFILE #ifndef HAVE_SENDFILE64 off_t offset; #else /* HAVE_SENDFILE64 */ off64_t offset; #endif /* HAVE_SENDFILE64 */ -#endif /* HAVE_LINUX_SENDFILE */ +#endif /* MHD_LINUX_SOLARIS_SENDFILE */ #ifdef HAVE_FREEBSD_SENDFILE off_t sent_bytes; int flags = 0; @@ -317,7 +317,7 @@ sendfile_adapter (struct MHD_Connection *connection) connection->resp_sender = MHD_resp_sender_std; return MHD_ERR_AGAIN_; } -#ifdef HAVE_LINUX_SENDFILE +#ifdef MHD_LINUX_SOLARIS_SENDFILE #ifndef HAVE_SENDFILE64 offset = (off_t) offsetu64; ret = sendfile (connection->socket_fd, @@ -344,6 +344,7 @@ sendfile_adapter (struct MHD_Connection *connection) } if (MHD_SCKT_ERR_IS_EINTR_ (err)) return MHD_ERR_AGAIN_; +#ifdef HAVE_LINUX_SENDFILE if (MHD_SCKT_ERR_IS_(err, MHD_SCKT_EBADF_)) return MHD_ERR_BADF_; @@ -354,6 +355,21 @@ sendfile_adapter (struct MHD_Connection *connection) http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */ connection->resp_sender = MHD_resp_sender_std; return MHD_ERR_AGAIN_; +#else /* HAVE_SOLARIS_SENDFILE */ + if ( (EAFNOSUPPORT == err) || + (EINVAL == err) || + (EOPNOTSUPP == err) ) + { /* Retry with standard file reader. */ + connection->resp_sender = MHD_resp_sender_std; + return MHD_ERR_AGAIN_; + } + if ( (ENOTCONN == err) || + (EPIPE == err) ) + { + return MHD_ERR_CONNRESET_; + } + return MHD_ERR_BADF_; /* Fail hard */ +#endif /* HAVE_SOLARIS_SENDFILE */ } #ifdef EPOLL_SUPPORT else if (send_size > (size_t)ret) @@ -394,7 +410,7 @@ sendfile_adapter (struct MHD_Connection *connection) #endif /* HAVE_FREEBSD_SENDFILE */ return ret; } -#endif /* HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE */ +#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */ /** @@ -1026,13 +1042,13 @@ try_ready_normal_body (struct MHD_Connection *connection) (response->data_size + response->data_start > connection->response_write_position) ) return MHD_YES; /* response already ready */ -#if defined(HAVE_LINUX_SENDFILE) || defined (HAVE_FREEBSD_SENDFILE) +#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined (HAVE_FREEBSD_SENDFILE) if (MHD_resp_sender_sendfile == connection->resp_sender) { /* will use sendfile, no need to bother response crc */ return MHD_YES; } -#endif /* HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE */ +#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */ ret = response->crc (response->crc_cls, connection->response_write_position, @@ -2970,15 +2986,15 @@ MHD_connection_handle_write (struct MHD_Connection *connection) /* mutex was already unlocked by try_ready_normal_body */ return; } -#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) +#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) if (MHD_resp_sender_sendfile == connection->resp_sender) { ret = sendfile_adapter (connection); } else -#else /* ! (HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE) */ +#else /* ! (MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE) */ if (1) -#endif /* ! (HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE) */ +#endif /* ! (MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE) */ { data_write_offset = connection->response_write_position - response->data_start; @@ -3918,13 +3934,13 @@ MHD_queue_response (struct MHD_Connection *connection, MHD_increment_response_rc (response); connection->response = response; connection->responseCode = status_code; -#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) +#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) if ( (response->fd == -1) || (0 != (connection->daemon->options & MHD_USE_TLS)) ) connection->resp_sender = MHD_resp_sender_std; else connection->resp_sender = MHD_resp_sender_sendfile; -#endif /* HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE */ +#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */ if ( ( (NULL != connection->method) && (MHD_str_equal_caseless_ (connection->method, diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -806,13 +806,13 @@ struct MHD_Connection */ uint64_t response_write_position; -#if defined(HAVE_LINUX_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) +#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) enum MHD_resp_sender_ { MHD_resp_sender_std = 0, MHD_resp_sender_sendfile } resp_sender; -#endif /* HAVE_LINUX_SENDFILE || HAVE_FREEBSD_SENDFILE */ +#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */ /** * Position in the 100 CONTINUE message that