summaryrefslogtreecommitdiffstats
path: root/source/lib
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-09-14 00:34:46 +0000
committerJeremy Allison <jra@samba.org>2002-09-14 00:34:46 +0000
commit872dfd87cda585c33c3823b06580cb301567a9b9 (patch)
treed78d9e83f90078163d0aff6a600dba8839b69109 /source/lib
parenteda0e7589f2591edc29e6c1eef44aa21628977be (diff)
downloadsamba-872dfd87cda585c33c3823b06580cb301567a9b9.tar.gz
samba-872dfd87cda585c33c3823b06580cb301567a9b9.tar.xz
samba-872dfd87cda585c33c3823b06580cb301567a9b9.zip
Added fix for broken Linux (no sendfile64). When offset + count > 2GB
then return ENOSYS and let the upper layer handle it. Jeremy
Diffstat (limited to 'source/lib')
-rw-r--r--source/lib/sendfile.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/source/lib/sendfile.c b/source/lib/sendfile.c
index 6e093c31ffb..2707495d5b3 100644
--- a/source/lib/sendfile.c
+++ b/source/lib/sendfile.c
@@ -74,6 +74,63 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of
return count + hdr_len;
}
+#elif defined(LINUX_BROKEN_SENDFILE_API)
+
+#include <sys/sendfile.h>
+
+#ifndef MSG_MORE
+#define MSG_MORE 0x8000
+#endif
+
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count)
+{
+ size_t total=0;
+ ssize_t ret;
+ ssize_t hdr_len = 0;
+
+ /*
+ * Fix for broken Linux 2.4 systems with no working sendfile64().
+ * If the offset+count > 2 GB then pretend we don't have the
+ * system call sendfile at all. The upper later catches this
+ * and uses a normal read. JRA.
+ */
+
+ if ((sizeof(SMB_OFF_T) >= 8) && (offset + count > (SMB_OFF_T)0x7FFFFFFF)) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ /*
+ * Send the header first.
+ * Use MSG_MORE to cork the TCP output until sendfile is called.
+ */
+
+ if (header) {
+ hdr_len = header->length;
+ while (total < hd_len) {
+ ret = sys_send(tofd, header->data + total,hdr_len - total, MSG_MORE);
+ if (ret == -1)
+ return -1;
+ total += ret;
+ }
+ }
+
+ total = count;
+ while (total) {
+ ssize_t nwritten;
+ do {
+ nwritten = sendfile(tofd, fromfd, &offset, total);
+ } while (nwritten == -1 && errno == EINTR);
+ if (nwritten == -1)
+ return -1;
+ if (nwritten == 0)
+ return -1; /* I think we're at EOF here... */
+ total -= nwritten;
+ }
+ return count + hdr_len;
+}
+
+
#elif defined(SOLARIS_SENDFILE_API)
ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count)