summaryrefslogtreecommitdiff
path: root/source3/lib/sendfile.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2004-11-24 22:05:59 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:53:26 -0500
commit314ec086f3a015f97cc5dafc3038b3bf782d92af (patch)
tree50d6e0e4a3015b061df736298ff22e808a9ccd47 /source3/lib/sendfile.c
parent3bd5c9a8385576c3201580233e521b9de11918ab (diff)
downloadsamba-314ec086f3a015f97cc5dafc3038b3bf782d92af.tar.gz
samba-314ec086f3a015f97cc5dafc3038b3bf782d92af.tar.bz2
samba-314ec086f3a015f97cc5dafc3038b3bf782d92af.zip
r3944: Fix the problem we get on Linux where sendfile fails, but we've already sent the
header using send(). As our implementation of sendfile can't return EINTR (it restarts in that case) use an errno of EINTR to signal the linux sendfile fail after header case. When that happens send the rest of the data and then turn off sendfile. Sendfile should be safe to enable on all systems now (even though it may not help in all performance cases). Jeremy. (This used to be commit 78236382f7ffe08d7924907be49493779521837f)
Diffstat (limited to 'source3/lib/sendfile.c')
-rw-r--r--source3/lib/sendfile.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/source3/lib/sendfile.c b/source3/lib/sendfile.c
index 4aa76a0c74..75fb635fa2 100644
--- a/source3/lib/sendfile.c
+++ b/source3/lib/sendfile.c
@@ -65,8 +65,20 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
nwritten = sendfile(tofd, fromfd, &offset, total);
#endif
} while (nwritten == -1 && errno == EINTR);
- if (nwritten == -1)
+ if (nwritten == -1) {
+ if (errno == ENOSYS) {
+ /* Ok - we're in a world of pain here. We just sent
+ * the header, but the sendfile failed. We have to
+ * emulate the sendfile at an upper layer before we
+ * disable it's use. So we do something really ugly.
+ * We set the errno to a strange value so we can detect
+ * this at the upper level and take care of it without
+ * layer violation. JRA.
+ */
+ errno = EINTR; /* Normally we can never return this. */
+ }
return -1;
+ }
if (nwritten == 0)
return -1; /* I think we're at EOF here... */
total -= nwritten;
@@ -131,8 +143,20 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
do {
nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
} while (nwritten == -1 && errno == EINTR);
- if (nwritten == -1)
+ if (nwritten == -1) {
+ if (errno == ENOSYS) {
+ /* Ok - we're in a world of pain here. We just sent
+ * the header, but the sendfile failed. We have to
+ * emulate the sendfile at an upper layer before we
+ * disable it's use. So we do something really ugly.
+ * We set the errno to a strange value so we can detect
+ * this at the upper level and take care of it without
+ * layer violation. JRA.
+ */
+ errno = EINTR; /* Normally we can never return this. */
+ }
return -1;
+ }
if (nwritten == 0)
return -1; /* I think we're at EOF here... */
small_total -= nwritten;