Enable use of sendfile on FreeBSD
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 6 May 2017 19:19:31 +0000 (20:19 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 6 May 2017 20:04:11 +0000 (21:04 +0100)
doc/doc-txt/ChangeLog
src/OS/os.c-FreeBSD [new file with mode: 0644]
src/OS/os.c-Linux
src/OS/os.h-FreeBSD
src/OS/os.h-Linux
src/src/dkim_transport.c
src/src/receive.c
src/src/transport.c

index aca12ea00d785f12e831a31c69bee0ef1d9c8aae..2078b352189c8dccabdd1a62b285cc5362a1074e 100644 (file)
@@ -63,7 +63,7 @@ JH/09 Avoid using a temporary file during transport using dkim.  Unless a
 
 JH/10 Enable use of sendfile in Linux builds as default.  It was disabled in
       4.77 as the kernel support then wasn't solid, having issues in 64bit
-      mode.  Now, it's been long enough.
+      mode.  Now, it's been long enough.  Add support for FreeBSD also.
 
 JH/11 Bug 2104: Fix continued use of a transport connection with TLS.  In the
       case where the routing stage had gathered several addresses to send to
diff --git a/src/OS/os.c-FreeBSD b/src/OS/os.c-FreeBSD
new file mode 100644 (file)
index 0000000..a892e59
--- /dev/null
@@ -0,0 +1,25 @@
+/*************************************************
+*     Exim - an Internet mail transport agent    *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2017 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* FreeBSD-specific code. This is concatenated onto the generic
+src/os.c file. */
+
+
+/*************
+* Sendfile   *
+*************/
+#include <sys/sendfile.h>
+
+ssize_t
+os_sendfile(int out, int in, off_t * off, size_t cnt)
+{
+off_t written;
+return sendfile(in, out, *off, cnt, NULL, &written, 0) < 0
+  ? (ssize_t) -1 : (ssize_t) written;
+}
+
+/* End of os.c-Linux */
index 4bca77615d5f2d5b6aabffa885885b4dc9e0c9d6..dd65c8b3930cfbe71326db9c3cbcfc1be29962f3 100644 (file)
@@ -150,4 +150,16 @@ return yield;
 
 #endif  /* FIND_RUNNING_INTERFACES */
 
+
+/*************
+* Sendfile   *
+*************/
+#include <sys/sendfile.h>
+
+ssize_t
+os_sendfile(int out, int in, off_t * off, size_t cnt)
+{
+return sendfile(out, in, off, cnt);
+}
+
 /* End of os.c-Linux */
index bf43e0a3cec0415c6681db719e063a2e5b9cd89a..9b47de3d10b62929a5cd3c89f4d9e636b049d71c 100644 (file)
@@ -1,5 +1,7 @@
 /* Exim: OS-specific C header file for FreeBSD */
 
+#include <sys/types.h>
+
 #define HAVE_BSD_GETLOADAVG
 #define HAVE_SETCLASSRESOURCES
 #define HAVE_MMAP
@@ -34,4 +36,11 @@ typedef struct flock flock_t;
 /* for more specific version constraints, include <sys/param.h> and look at
  * __FreeBSD_version */
 
+
+/* When using DKIM, setting OS_SENDFILE can increase
+performance on outgoing mail a bit. */
+
+#define OS_SENDFILE
+extern ssize_t os_sendfile(int, int, off_t *, size_t);
+
 /* End */
index 3e9303cab8a28a36403b8b0a91c2b8529c87636c..57034649c6909e7422f724caad23caf8031c5704 100644 (file)
@@ -5,6 +5,7 @@ does not pull in <features.h>.  Best to just pull it in now and have done
 with the issue. */
 
 #include <features.h>
+#include <sys/types.h>
 
 
 #define CRYPT_H
@@ -15,13 +16,14 @@ with the issue. */
 #define NO_IP_VAR_H
 #define SIG_IGN_WORKS
 
-/* When using the DKIM, setting HAVE_LINUX_SENDFILE can increase
+/* When using DKIM, setting OS_SENDFILE can increase
 performance on outgoing mail a bit. Note: With older glibc versions
 this setting will conflict with the _FILE_OFFSET_BITS=64 setting
 defined as part of the Linux CFLAGS.  As of 2017 those are declared
 to be too old to build by default. */
 
-#define HAVE_LINUX_SENDFILE
+#define OS_SENDFILE
+extern ssize_t os_sendfile(int, int, off_t *, size_t);
 
 #define F_FREESP     O_TRUNC
 typedef struct flock flock_t;
@@ -30,8 +32,8 @@ typedef struct flock flock_t;
 #define OS_STRSIGNAL
 
 #if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD_kernel__)
-#define SIOCGIFCONF_GIVES_ADDR
-#define HAVE_SYS_MOUNT_H
+# define SIOCGIFCONF_GIVES_ADDR
+# define HAVE_SYS_MOUNT_H
 #endif
 
 #if defined(__linux__)
index 882fc877296bb7b45eba57b431430f8a154ea0b8..95e750e5edd630edbb6292a9df444f6feebc648d 100644 (file)
 
 #ifndef DISABLE_DKIM   /* rest of file */
 
-#ifdef HAVE_LINUX_SENDFILE
-# include <sys/sendfile.h>
-#endif
-
 
 static BOOL
 dkt_sign_fail(struct ob_dkim * dkim, int * errp)
@@ -47,7 +43,7 @@ DEBUG(D_transport) debug_printf("send file fd=%d size=%u\n", out_fd, (unsigned)(
 
 /*XXX should implement timeout, like transport_write_block_fd() ? */
 
-#ifdef HAVE_LINUX_SENDFILE
+#ifdef OS_SENDFILE
 /* We can use sendfile() to shove the file contents
    to the socket. However only if we don't use TLS,
    as then there's another layer of indirection
@@ -57,7 +53,7 @@ if (tls_out.active != out_fd)
   ssize_t copied = 0;
 
   while(copied >= 0 && off < size)
-    copied = sendfile(out_fd, in_fd, &off, size - off);
+    copied = os_sendfile(out_fd, in_fd, &off, size - off);
   if (copied < 0)
     return FALSE;
   }
@@ -255,7 +251,7 @@ else if (!(rc = dkt_sign_fail(dkim, &save_errno)))
   goto CLEANUP;
   }
 
-#ifndef HAVE_LINUX_SENDFILE
+#ifndef OS_SENDFILE
 if (options & topt_use_bdat)
 #endif
   if ((k_file_size = lseek(dkim_fd, 0, SEEK_END)) < 0)
index f8320bd2059117064f5a8db0d90e097b15c88573..6316ff9613ae87689e2fa20f6f6cc61a5d19b0aa 100644 (file)
@@ -919,7 +919,7 @@ BOOL fix_nl = FALSE;
 
 for(;;)
   {
-  switch ((ch = (bdat_getc)(GETC_BUFFER_UNLIMITED)))
+  switch ((ch = bdat_getc(GETC_BUFFER_UNLIMITED)))
     {
     case EOF:  return END_EOF;
     case ERR:  return END_PROTOCOL;
index 0dc8785cb4b15b95803428de2a697cd7cf9a9822..5bcf8c1ae7f5357b6f6885d8e330d224acff16d6 100644 (file)
@@ -11,10 +11,6 @@ transports. */
 
 #include "exim.h"
 
-#ifdef HAVE_LINUX_SENDFILE
-# include <sys/sendfile.h>
-#endif
-
 /* Structure for keeping list of addresses that have been added to
 Envelope-To:, in order to avoid duplication. */
 
@@ -1065,7 +1061,7 @@ then we can just dump it using sendfile.
 This should get used for CHUNKING output and also for writing the -K file for
 dkim signing,  when we had CHUNKING input.  */
 
-#ifdef HAVE_LINUX_SENDFILE
+#ifdef OS_SENDFILE
 if (  spool_file_wireformat
    && !(tctx->options & (topt_no_body | topt_end_dot))
    && !nl_check_length
@@ -1088,7 +1084,7 @@ if (  spool_file_wireformat
 
   while(size > 0)
     {
-    if ((copied = sendfile(tctx->u.fd, deliver_datafile, &offset, size)) <= 0) break;
+    if ((copied = os_sendfile(tctx->u.fd, deliver_datafile, &offset, size)) <= 0) break;
     size -= copied;
     }
   return copied >= 0;