From 4e38e959a1ecfaa5fa5f3571599a60ab0a88c712 Mon Sep 17 00:00:00 2001
From: Lukas Larsson <lukas@erlang.org>
Date: Mon, 22 May 2017 11:25:20 +0200
Subject: erts: Fix sendfile closeduring scenario on sunos

On Solaris, giving a too long sfv_len results in an
EINVAL error, but data is still transmitted and len is
correctly. So we translate this to a success with that
amount of data sent. This may hide some other errors
that causes EINVAL, but it is the best we can do for now.
---
 erts/emulator/drivers/unix/unix_efile.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

(limited to 'erts')

diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 0acc2432a7..f8341f788a 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -969,17 +969,21 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,
 	fdrec.sfv_len = SENDFILE_CHUNK_SIZE;
       else
 	fdrec.sfv_len = *nbytes;
+
       retval = sendfilev(out_fd, &fdrec, 1, &len);
 
-      /* Sometimes sendfilev can return -1 and still send data. 
-         When that happens we just pretend that no error happend. */
-      if (retval != -1 || errno == EAGAIN || errno == EINTR ||
-	  len != 0) {
+      if (retval == -1 && errno == EINVAL) {
+          /* On some solaris versions (I've seen it on SunOS 5.10),
+             using a sfv_len larger then a filesize will result in
+             a -1 && errno == EINVAL return. We translate this so
+             a successful send of the data.*/
+          retval = len;
+      }
+
+      if (retval != -1 || errno == EAGAIN || errno == EINTR) {
         *offset += len;
 	*nbytes -= len;
 	written += len;
-	if (errno != EAGAIN && errno != EINTR && len != 0)
-	  retval = len;
       }
     } while (len == SENDFILE_CHUNK_SIZE);
 #elif defined(__DARWIN__)
-- 
cgit v1.2.3