aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/drivers/unix/unix_efile.c
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2011-11-15 10:32:03 +0100
committerLukas Larsson <[email protected]>2011-12-01 14:10:04 +0100
commita508d712553761d3cdc69d5e14c09ba3a6530d7a (patch)
tree034da8b7bad3879135a38f7b4afc4b27dbefbdca /erts/emulator/drivers/unix/unix_efile.c
parent23d62043ebf4bfad900935c650e8fcb3f2e6f88c (diff)
downloadotp-a508d712553761d3cdc69d5e14c09ba3a6530d7a.tar.gz
otp-a508d712553761d3cdc69d5e14c09ba3a6530d7a.tar.bz2
otp-a508d712553761d3cdc69d5e14c09ba3a6530d7a.zip
Fix freebsd support for sendfile
Diffstat (limited to 'erts/emulator/drivers/unix/unix_efile.c')
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 911ec63588..14b7a5cffa 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -1511,9 +1511,22 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,
*nbytes = written;
return check_error(retval, errInfo);
#elif defined(__FreeBSD__) || defined(__DragonFly__)
- off_t len = 0;
- int retval = sendfile(in_fd, out_fd, *offset, *nbytes, NULL, &len, 0);
- *nbytes = len;
+#define SENDFILE_CHUNK_SIZE ((1 << (8*SIZEOF_SIZE_T)) - 1)
+ off_t len;
+ int retval;
+ do {
+ if (*nbytes > SENDFILE_CHUNK_SIZE)
+ retval = sendfile(in_fd, out_fd, *offset, SENDFILE_CHUNK_SIZE,
+ NULL, &len, 0);
+ else
+ retval = sendfile(in_fd, out_fd, *offset, *nbytes, NULL, &len, 0);
+ if (retval != -1 || errno == EAGAIN || errno == EINTR) {
+ *offset += len;
+ *nbytes -= len;
+ written += len;
+ }
+ } while(len == SENDFILE_CHUNK_SIZE);
+ *nbytes = written;
return check_error(retval, errInfo);
#endif
}