From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id D0BB0158087 for ; Mon, 13 Dec 2021 08:39:45 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 600E42BC032; Mon, 13 Dec 2021 08:39:44 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 400892BC040 for ; Mon, 13 Dec 2021 08:39:44 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 35785343538 for ; Mon, 13 Dec 2021 08:39:41 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id E16EA22B for ; Mon, 13 Dec 2021 08:39:39 +0000 (UTC) From: "Fabian Groffen" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Fabian Groffen" Message-ID: <1639379824.53d7d24872527a69501f4c74a44e16e29aa3bb4a.grobian@gentoo> Subject: [gentoo-commits] proj/portage-utils:master commit in: libq/ X-VCS-Repository: proj/portage-utils X-VCS-Files: libq/copy_file.c X-VCS-Directories: libq/ X-VCS-Committer: grobian X-VCS-Committer-Name: Fabian Groffen X-VCS-Revision: 53d7d24872527a69501f4c74a44e16e29aa3bb4a X-VCS-Branch: master Date: Mon, 13 Dec 2021 08:39:39 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: d6a23f84-f721-433e-b367-0c08f12f574e X-Archives-Hash: c17787f5fee41a3b4761c573fefef16d commit: 53d7d24872527a69501f4c74a44e16e29aa3bb4a Author: Fabian Groffen gentoo org> AuthorDate: Mon Dec 13 07:17:04 2021 +0000 Commit: Fabian Groffen gentoo org> CommitDate: Mon Dec 13 07:17:04 2021 +0000 URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=53d7d248 libq/copy_file: employ sendfile() if possible Signed-off-by: Fabian Groffen gentoo.org> libq/copy_file.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/libq/copy_file.c b/libq/copy_file.c index e4619ce..955fd78 100644 --- a/libq/copy_file.c +++ b/libq/copy_file.c @@ -1,29 +1,85 @@ /* - * Copyright 2005-2019 Gentoo Foundation + * Copyright 2005-2021 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2011-2016 Mike Frysinger - + * Copyright 2021- Fabian Groffen - */ #include "main.h" #include "safe_io.h" #include "copy_file.h" +/* includes for when sendfile is available */ +#include +#include +#include +#include +#if defined(HAVE_SENDFILE4_SUPPORT) +/* Linux/Solaris */ +# include +#elif defined(HAVE_SENDFILE6_SUPPORT) || defined(HAVE_SENDFILE7_SUPPORT) +/* macOS (since Darwin 9) + FreeBSD */ +# include +# include +#endif + int copy_file_fd(int fd_src, int fd_dst) { - ssize_t rcnt, wcnt; - char buf[64 * 1024]; +#if defined(HAVE_SENDFILE4_SUPPORT) || \ + defined(HAVE_SENDFILE6_SUPPORT) || \ + defined(HAVE_SENDFILE7_SUPPORT) + struct stat stat_buf; + ssize_t ret; + size_t len; + off_t offset = 0; - while (1) { - rcnt = safe_read(fd_src, buf, sizeof(buf)); - if (rcnt < 0) - return -1; - else if (rcnt == 0) + if (fstat(fd_src, &stat_buf) != -1) { + len = (size_t)stat_buf.st_size; + +#if defined(HAVE_SENDFILE4_SUPPORT) + /* Linux/Solaris */ + ret = sendfile(fd_dst, fd_src, &offset, len); + /* everything looks fine, return success */ + if (ret == (ssize_t)len) return 0; +#elif defined(HAVE_SENDFILE6_SUPPORT) + /* macOS (since Darwin 9) */ + offset = len; + ret = (ssize_t)sendfile(fd_src, fd_dst, 0, &offset, NULL, 0); + /* everything looks fine, return success */ + if (offset == (off_t)len) + return 0; +#elif defined(HAVE_SENDFILE7_SUPPORT) + /* FreeBSD */ + ret = (ssize_t)sendfile(fd_src, fd_dst, offset, len, NULL, &offset, 0); + /* everything looks fine, return success */ + if (offset == (off_t)len) + return 0; +#endif - wcnt = safe_write(fd_dst, buf, rcnt); - if (wcnt == -1) - return -1; + /* fall back to read/write, rewind the fd */ + lseek(fd_src, 0, SEEK_SET); + } +#endif /* HAVE_SENDFILE */ + + /* fallback, keep in its own scope, so we avoid 64K stack alloc if + * sendfile works properly */ + { + ssize_t rcnt, wcnt; + char buf[64 * 1024]; + + while (1) { + rcnt = safe_read(fd_src, buf, sizeof(buf)); + if (rcnt < 0) + return -1; + else if (rcnt == 0) + return 0; + + wcnt = safe_write(fd_dst, buf, rcnt); + if (wcnt == -1) + return -1; + } } }