Skip to content

Instantly share code, notes, and snippets.

@bmanojlovic
Last active December 22, 2015 20:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmanojlovic/6529848 to your computer and use it in GitHub Desktop.
Save bmanojlovic/6529848 to your computer and use it in GitHub Desktop.
support for freebsd sendfile based on http://www.ioremap.net/node/192/ copy dnet_sendfile.m4 into ZoneMinder dir run autoreconf -i . run ./configure as usual
diff --git a/ac_check_sendfile.m4 b/ac_check_sendfile.m4
new file mode 100644
index 0000000..f2aac5a
--- /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 <sys/sendfile.h>
+ #include <stdio.h>],
+ [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 <sys/socket.h>
+ #include <stdio.h>],
+ [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 <sys/socket.h>
+ #include <stdio.h>
+ #include <sys/uio.h>],
+ [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/bootstrap.sh b/bootstrap.sh
index 681d5b3..ad7a154 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-aclocal
-autoheader
-automake --add-missing
-autoconf
+aclocal -I.
+autoheader -I.
+automake --add-missing --copy
+autoconf -I.
diff --git a/configure.ac b/configure.ac
index 1cb327e..4982b8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -250,7 +250,8 @@ AC_FUNC_STRTOD
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday memmove memset mkdir munmap posix_memalign putenv select sendfile socket sqrt strcasecmp strchr strcspn strerror strncasecmp strrchr strsignal strspn strstr strtol strtoull])
AC_CHECK_FUNCS([syscall sleep usleep ioctl ioctlsocket sigaction])
-
+# this is required for freebsd to compile
+AC_CHECK_SENDFILE
# Other programs
AC_CHECK_PROG(OPT_FFMPEG,ffmpeg,yes,no)
AC_PATH_PROG(PATH_FFMPEG,ffmpeg)
diff --git a/src/Makefile.am b/src/Makefile.am
index 9f111bf..6592f3c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -113,7 +113,8 @@ noinst_HEADERS = \
zm_timer.h \
zm_user.h \
zm_utils.h \
- zm_zone.h
+ zm_zone.h \
+ zm_sendfile.h
EXTRA_DIST = \
zm_config.h.in \
diff --git a/src/zm_event.cpp b/src/zm_event.cpp
index a43f31a..fac4713 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
@@ -1292,7 +1298,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 0000000..50c7501
--- /dev/null
+++ b/src/zm_sendfile.h
@@ -0,0 +1,31 @@
+#ifdef HAVE_SENDFILE4_SUPPORT
+#include <sys/sendfile.h>
+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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+int zm_sendfile(int out_fd, int in_fd, off_t *offset, size_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
@connortechnology
Copy link

So... I googled for an autoconf sendfile fix for freebsd and I came across this... which I will attempt to use! If it works, I will be merging it to our master branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment