From 8b90faff6c55cc4bfbc19f0aec655b89fa7283be Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Thu, 18 Jun 2015 17:05:55 +0200 Subject: [PATCH] fs: fix bug in sendfile for DragonFly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code made an implicit assumption that the 'len` variable passed to the sendfile(2) syscall is not modified by the operating system in case of an error other than EAGAIN or EINTR. The man page leaves this unspecified on FreeBSD, DragonFly and Darwin, so better check the error code which returns a valid value in `len` explicitly (only EAGAIN and EINTR). This fixes the test case for sendfile on DragonFly. PR-URL: https://github.com/libuv/libuv/pull/466 Reviewed-By: Ben Noordhuis Reviewed-By: Saúl Ibarra Corretgé --- src/unix/fs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/unix/fs.c b/src/unix/fs.c index 52082e93..d739c282 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -574,7 +574,14 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) { r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0); #endif - if (r != -1 || len != 0) { + /* + * The man page for sendfile(2) on DragonFly states that `len` contains + * a meaningful value ONLY in case of EAGAIN and EINTR. + * Nothing is said about it's value in case of other errors, so better + * not depend on the potential wrong assumption that is was not modified + * by the syscall. + */ + if (r == 0 || ((errno == EAGAIN || errno == EINTR) && len != 0)) { req->off += len; return (ssize_t) len; }