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:
M | cmd/cat.c | 36 | ++++++++++++++++++++++++++++++++++-- |
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;
}