From 0bea3815109784fd632e8cb31f44c833ef4a8670 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 24 Feb 2015 09:20:55 -0500 Subject: [PATCH] sendfile tricks --- ac_check_sendfile.m4 | 63 ++++++++++++++++++++++++++++++++++++++++++++ src/zm_event.cpp | 8 +++++- src/zm_sendfile.h | 31 ++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 ac_check_sendfile.m4 create mode 100644 src/zm_sendfile.h diff --git a/ac_check_sendfile.m4 b/ac_check_sendfile.m4 new file mode 100644 index 000000000..12605d588 --- /dev/null +++ b/ac_check_sendfile.m4 @@ -0,0 +1,63 @@ +AC_DEFUN([AC_CHECK_SENDFILE],[ +AC_MSG_CHECKING([whether sendfile() is supported and what prototype it has]) + +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror-implicit-function-declaration" +ac_sendfile_supported=no +AC_TRY_LINK([#include + #include ], + [sendfile(1, 1, NULL, 0);], + [ + AC_DEFINE(HAVE_SENDFILE4_SUPPORT, 1, + [Define this if Linux/Solaris sendfile() is supported]) + AC_MSG_RESULT([Linux sendfile()]) + ac_sendfile_supported=yes + ], []) + +if test x$ac_sendfile_supported = xno; then + dnl Checking wether we need libsendfile + dnl Presumably on Solaris + AC_CHECK_LIB(sendfile, sendfile, + [ + AC_DEFINE(HAVE_SENDFILE4_SUPPORT, 1, + [Define this if Linux/Solaris sendfile() is supported]) + SENDFILE_LIBS="-lsendfile" + AC_SUBST(SENDFILE_LIBS) + AC_MSG_RESULT([Solaris sendfile()]) + ac_sendfile_supported=yes + ], []) +fi + +if test x$ac_sendfile_supported = xno; then + dnl Checking wether we have FreeBSD-like sendfile() support. + AC_TRY_LINK([#include + #include ], + [sendfile(1, 1, 0, 0, NULL, NULL, 0);], + [ + AC_DEFINE(HAVE_SENDFILE7_SUPPORT, 1, + [Define this if FreeBSD sendfile() is supported]) + AC_MSG_RESULT([FreeBSD sendfile()]) + ac_sendfile_supported=yes + ], []) +fi + +if test x$ac_sendfile_supported = xno; then + dnl Checking wether we have MacOS-like sendfile() support. + AC_TRY_LINK([#include + #include + #include ], + [sendfile(1, 1, 0, NULL, NULL, 0);], + [ + AC_DEFINE(HAVE_SENDFILE6_SUPPORT, 1, + [Define this if MacOS sendfile() is supported]) + AC_MSG_RESULT([MacOS sendfile()]) + ac_sendfile_supported=yes + ], []) +fi + +CFLAGS="$saved_CFLAGS" + +if test x$ac_sendfile_supported = xno; then + AC_MSG_RESULT([no sendfile() support, using read/send]) +fi +]) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 1c7e13e7d..464fe7e56 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -36,6 +36,12 @@ #include "zm_event.h" #include "zm_monitor.h" +// sendfile tricks +extern "C" +{ +#include "zm_sendfile.h" +} + #include "zmf.h" #if HAVE_SYS_SENDFILE_H @@ -1309,7 +1315,7 @@ bool EventStream::sendFrame( int delta_us ) if(send_raw) { #if HAVE_SENDFILE fprintf( stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size ); - if(sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size) { + if(zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size) { /* sendfile() failed, use standard way instead */ img_buffer_size = fread( img_buffer, 1, sizeof(temp_img_buffer), fdj ); if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) { diff --git a/src/zm_sendfile.h b/src/zm_sendfile.h new file mode 100644 index 000000000..ce3405d66 --- /dev/null +++ b/src/zm_sendfile.h @@ -0,0 +1,31 @@ +#ifdef HAVE_SENDFILE4_SUPPORT +#include +int zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { + int err; + + err = sendfile(out_fd, in_fd, offset, size); + if (err < 0) + return -errno; + + return err; +} +#elif HAVE_SENDFILE7_SUPPORT +#include +#include +#include +int zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) { + int err; + err = sendfile(in_fd, out_fd, *offset, size, NULL, &size, 0); + if (err && errno != EAGAIN) + return -errno; + + if (size) { + *offset += size; + return size; + } + + return -EAGAIN; +} +#else +#error "Your platform does not support sendfile. Sorry." +#endif