Fix pipe transport to not use a socket-only syscall. Bug 2257
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 20 Mar 2018 17:54:47 +0000 (17:54 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 20 Mar 2018 18:06:04 +0000 (18:06 +0000)
Broken-by: 42055a3385
doc/doc-txt/ChangeLog
src/src/macros.h
src/src/transport.c
src/src/transports/appendfile.c
src/src/transports/autoreply.c
src/src/transports/pipe.c

index 1dff01fb5bce44aac3d2b7c09975e11c1bb84357..236ccae8b54ad6abbb1d698f6d783c35f0084f96 100644 (file)
@@ -163,6 +163,8 @@ JH/29 Bug 2250: Fix a longstanding bug in heavily-pipelined SMTP input (such
 JH/30 The (EXPERIMENTAL_DMARC) variable $dmarc_ar_header is withdrawn, being
       replaced by the ${authresults } expansion.
 
+JH/31 Bug 2257: Fix pipe transport to not use a socket-only syscall.
+
 
 Exim version 4.90
 -----------------
index beab72a28433023ffa057372e70482a802531825..85ceb0acb3b6a924ee62ed91470b8a46d231bf12 100644 (file)
@@ -864,6 +864,7 @@ enum {
 #define topt_use_bdat          0x100  /* prepend chunks with RFC3030 BDAT header */
 #define topt_output_string     0x200  /* create string rather than write to fd */
 #define topt_continuation      0x400  /* do not reset buffer */
+#define topt_not_socket                0x800  /* cannot do socket-only syscalls */
 
 /* Options for smtp_write_command */
 
index d598e5aab374b5aa920b07f2302e4962d0628eb6..073c4ad651c4923bf07ebfad16e2d4f05b1f1553 100644 (file)
@@ -245,7 +245,8 @@ for (i = 0; i < 100; i++)
        tls_out.active == fd ? tls_write(FALSE, block, len, more) :
 #endif
 #ifdef MSG_MORE
-       more ? send(fd, block, len, MSG_MORE) :
+       more && !(tctx->options & topt_not_socket)
+         ? send(fd, block, len, MSG_MORE) :
 #endif
        write(fd, block, len);
     save_errno = errno;
index 37f994fac92736f5d18023f63410efd429c54f80..321dbc9475a1af2d7604436ee3f2c04dc0b5ef90 100644 (file)
@@ -945,9 +945,7 @@ copy_mbx_message(int to_fd, int from_fd, off_t saved_size)
 int used;
 off_t size;
 struct stat statbuf;
-transport_ctx tctx = {{0}};
-
-tctx.u.fd = to_fd;
+transport_ctx tctx = { .u={.fd = to_fd}, .options = topt_not_socket };
 
 /* If the current mailbox size is zero, write a header block */
 
@@ -2921,12 +2919,12 @@ at initialization time. */
 if (yield == OK)
   {
   transport_ctx tctx = {
-    {fd},
-    tblock,
-    addr,
-    ob->check_string,
-    ob->escape_string,
-    ob->options
+    .u = {.fd=fd},
+    .tblock = tblock,
+    .addr = addr,
+    .check_string = ob->check_string,
+    .escape_string = ob->escape_string,
+    .options =  ob->options | topt_not_socket
   };
   if (!transport_write_message(&tctx, 0))
     yield = DEFER;
index f85bc4739fe4a8b56fd1b87747b2f99625c920b5..c3ed16962e87d595aa67943030212bbd90bf675e 100644 (file)
@@ -694,15 +694,17 @@ if (return_message)
     :
     US"------ This is a copy of the message, including all the headers.\n";
   transport_ctx tctx = {
-    {fileno(f)},
-    tblock,
-    addr,
-    NULL, NULL,
-    (tblock->body_only ? topt_no_headers : 0) |
-    (tblock->headers_only ? topt_no_body : 0) |
-    (tblock->return_path_add ? topt_add_return_path : 0) |
-    (tblock->delivery_date_add ? topt_add_delivery_date : 0) |
-    (tblock->envelope_to_add ? topt_add_envelope_to : 0)
+    .u = {.fd = fileno(f)},
+    .tblock = tblock,
+    .addr = addr,
+    .check_string = NULL,
+    .escape_string =  NULL,
+    .options = (tblock->body_only ? topt_no_headers : 0)
+       | (tblock->headers_only ? topt_no_body : 0)
+       | (tblock->return_path_add ? topt_add_return_path : 0)
+       | (tblock->delivery_date_add ? topt_add_delivery_date : 0)
+       | (tblock->envelope_to_add ? topt_add_envelope_to : 0)
+       | topt_not_socket
   };
 
   if (bounce_return_size_limit > 0 && !tblock->headers_only)
index 1ae5a70d99540daef5a1e08f9fe9017ad43cafc1..5470c72ded944e80fd486d6d7141f33693cff2e6 100644 (file)
@@ -566,12 +566,11 @@ const uschar *envlist = ob->environment;
 uschar *cmd, *ss;
 uschar *eol = ob->use_crlf ? US"\r\n" : US"\n";
 transport_ctx tctx = {
-  {0},
-  tblock,
-  addr,
-  ob->check_string,
-  ob->escape_string,
-  ob->options /* set at initialization time */
+  .tblock = tblock,
+  .addr = addr,
+  .check_string = ob->check_string,
+  .escape_string = ob->escape_string,
+  ob->options | topt_not_socket /* set at initialization time */
 };
 
 DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);