Browse Source

[network] add darwin-sendfile backend (fixes #2687)

The FreeBSD version of sendfile is already supported.  Starting
with OS X 10.5, Darwin also supports sendfile, but using a
slightly different argument list even though much of the
implementation is likely taken from FreeBSD just like the man
page is.

Add support for darwin's sendfile by introducing a new
network_darwin_sendfile.c file that's just a copy of the
network_freebsd_sendfile.c file except with the arguments
adjusted to compensate for the minor API difference (FreeBSD
has separate in and out byte count arguments whereas Darwin
has a combined in/out byte count argument).

Signed-off-by: Kyle J. McKay <mackyle@gmail.com>

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3060 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.38
Kyle J. McKay 6 years ago
committed by Stefan Bühler
parent
commit
159ca0c15d
  1. 1
      NEWS
  2. 2
      src/CMakeLists.txt
  3. 2
      src/Makefile.am
  4. 2
      src/SConscript
  5. 8
      src/network_backends.h
  6. 61
      src/network_darwin_sendfile.c
  7. 5
      src/server.c

1
NEWS

@ -18,6 +18,7 @@ NEWS
* [core] encode path with ENCODING_REL_URI in redirect to directory (fixes #2661, thx gstrauss)
* [mod_secdownload] add required algorithm option; old behaviour available as "md5", new options "hmac-sha1" and "hmac-sha256"
* [mod_fastcgi/mod_scgi] zero sockaddr structs before use (fixes #2691, thx Kyle J. McKay)
* [network] add darwin-sendfile backend (fixes #2687, thx Kyle J. McKay)
- 1.4.37 - 2015-08-30
* [mod_proxy] remove debug log line from error log (fixes #2659)

2
src/CMakeLists.txt

@ -494,7 +494,7 @@ set(COMMON_SRC
network_write.c network_linux_sendfile.c
network_freebsd_sendfile.c
network_solaris_sendfilev.c network_openssl.c
status_counter.c safe_memclear.c
status_counter.c safe_memclear.c network_darwin_sendfile.c
)
if(WIN32)

2
src/Makefile.am

@ -76,7 +76,7 @@ common_src=base64.c buffer.c log.c \
network_freebsd_sendfile.c network_writev.c \
network_solaris_sendfilev.c network_openssl.c \
splaytree.c status_counter.c \
safe_memclear.c
safe_memclear.c network_darwin_sendfile.c
src = server.c response.c connections.c network.c \
configfile.c configparser.c request.c proc_open.c

2
src/SConscript

@ -28,7 +28,7 @@ common_src = Split("base64.c buffer.c log.c \
network_write.c network_linux_sendfile.c \
network_freebsd_sendfile.c \
network_solaris_sendfilev.c network_openssl.c \
status_counter.c safe_memclear.c \
status_counter.c safe_memclear.c network_darwin_sendfile.c \
")
src = Split("server.c response.c connections.c network.c \

8
src/network_backends.h

@ -25,6 +25,14 @@
# define USE_FREEBSD_SENDFILE
#endif
#if defined HAVE_SENDFILE && defined(__APPLE__)
# ifdef USE_SENDFILE
# error "can't have more than one sendfile implementation"
# endif
# define USE_SENDFILE "darwin-sendfile"
# define USE_DARWIN_SENDFILE
#endif
#if defined HAVE_SYS_SENDFILE_H && defined HAVE_SENDFILEV && defined(__sun)
# ifdef USE_SENDFILE
# error "can't have more than one sendfile implementation"

61
src/network_darwin_sendfile.c

@ -0,0 +1,61 @@
#include "network_backends.h"
#if defined(USE_DARWIN_SENDFILE)
#include "network.h"
#include "log.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <errno.h>
#include <string.h>
int network_write_file_chunk_sendfile(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes) {
chunk* const c = cq->first;
off_t offset, written = 0;
off_t toSend;
int r;
force_assert(NULL != c);
force_assert(FILE_CHUNK == c->type);
force_assert(c->offset >= 0 && c->offset <= c->file.length);
offset = c->file.start + c->offset;
toSend = c->file.length - c->offset;
if (toSend > *p_max_bytes) toSend = *p_max_bytes;
if (0 == toSend) {
chunkqueue_remove_finished_chunks(cq);
return 0;
}
if (0 != network_open_file_chunk(srv, con, cq)) return -1;
/* Darwin sendfile() */
written = toSend;
if (-1 == (r = sendfile(c->file.fd, fd, offset, &written, NULL, 0))) {
switch(errno) {
case EAGAIN:
case EINTR:
/* for EAGAIN/EINTR written still contains the sent bytes */
break; /* try again later */
case EPIPE:
case ENOTCONN:
return -2;
default:
log_error_write(srv, __FILE__, __LINE__, "ssd", "sendfile: ", strerror(errno), errno);
return -1;
}
}
if (written >= 0) {
chunkqueue_mark_written(cq, written);
*p_max_bytes -= written;
}
return (r >= 0 && written == toSend) ? 0 : -3;
}
#endif /* USE_DARWIN_SENDFILE */

5
src/server.c

@ -422,6 +422,11 @@ static void show_features (void) {
#else
"\t- freebsd-sendfile\n"
#endif
#if defined USE_DARWIN_SENDFILE
"\t+ darwin-sendfile\n"
#else
"\t- darwin-sendfile\n"
#endif
#if defined USE_SOLARIS_SENDFILEV
"\t+ solaris-sendfilev\n"
#else

Loading…
Cancel
Save