From dff7ebe4f0bac1fdbcd6dec9eec72882597c78ca Mon Sep 17 00:00:00 2001 From: Andreas Hauptmann Date: Sun, 20 Aug 2017 14:42:22 +0200 Subject: [PATCH] unix: handle partial sends in uv_fs_copyfile() uv_fs_sendfile() is used as the fallback for uv_fs_copyfile(). However, sendfile() does not necessarily send all of the bytes in one call. This commit adds a loop to ensure all data is sent. Fixes: https://github.com/libuv/libuv/issues/1517 PR-URL: https://github.com/libuv/libuv/pull/1494 Reviewed-By: Santiago Gimeno Reviewed-By: Colin Ihrig --- src/unix/fs.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/unix/fs.c b/src/unix/fs.c index 3b816ecad..5a172cc78 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -791,6 +791,8 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { int dst_flags; int result; int err; + size_t bytes_to_send; + int64_t in_offset; dstfd = -1; @@ -826,14 +828,22 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { goto out; } - err = uv_fs_sendfile(NULL, - &fs_req, - dstfd, - srcfd, - 0, - statsbuf.st_size, - NULL); - uv_fs_req_cleanup(&fs_req); + bytes_to_send = statsbuf.st_size; + in_offset = 0; + while (bytes_to_send != 0) { + err = uv_fs_sendfile(NULL, + &fs_req, + dstfd, + srcfd, + in_offset, + bytes_to_send, + NULL); + uv_fs_req_cleanup(&fs_req); + if (err < 0) + break; + bytes_to_send -= fs_req.result; + in_offset += fs_req.result; + } out: if (err < 0)