logo

utils

~/.local/bin tools and git-hooks git clone https://hacktivis.me/git/utils.git
commit: 5915894ac5e44873a510c511e58056391cefea66
parent 29bcecfe0cf7ee999aa592c2d0da02358a357987
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Fri, 28 Jul 2023 07:24:59 +0200

cmd/cat: Add sendfile(2)-based optimisation

Diffstat:

Mcmd/cat.c36++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/cmd/cat.c b/cmd/cat.c @@ -1,5 +1,5 @@ // Collection of Unix tools, comparable to coreutils -// SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +// SPDX-FileCopyrightText: 2017-2023 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only #define _POSIX_C_SOURCE 200809L @@ -33,6 +33,38 @@ concat(int fd, const char *fdname) return 0; } +// FreeBSD also has sendfile(2) but it's only for sockets +#ifdef __linux__ +#include <sys/sendfile.h> +// Grabbed from /usr/src/hare/stdlib/io/+linux/platform_file.ha +#ifndef SENDFILE_MAX +#define SENDFILE_MAX 2147479552 +#endif // SENDFILE_MAX +int +fd_copy(int fd, const char *fdname) +{ + ssize_t c = 0; + off_t off = 0; + + while((c = sendfile(1, fd, &off, SENDFILE_MAX)) > 0) + ; + + if(c < 0) + { + if(errno == EINVAL && off == 0) + { + return concat(fd, fdname); + } + fprintf(stderr, "cat: Error copying ā€˜%sā€™: %s\n", fdname, strerror(errno)); + return 1; + } + + return 0; +} +#else // __linux__ +#define fd_copy concat +#endif // __linux__ + int main(int argc, char *argv[]) { @@ -63,7 +95,7 @@ main(int argc, char *argv[]) return 1; } - if(concat(fd, argv[argi]) != 0) + if(fd_copy(fd, argv[argi]) != 0) { return 1; }