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:
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