commit: 8ee8d7b92bfdda109c83d24151c468a487ab0a8d
parent f5476d2af4cdd3e3a7973e9028b59178bb48b63d
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Fri, 27 Sep 2024 10:17:59 +0200
cmd/cat: use auto_fd_copy
Diffstat:
3 files changed, 20 insertions(+), 75 deletions(-)
diff --git a/Makefile b/Makefile
@@ -78,8 +78,6 @@ format: $(C_SOURCES)
lib/sys_signame.c: lib/sys_signame.sh
lib/sys_signame.sh >|lib/sys_signame.c
-cmd/cat: cmd/cat.c config.mk Makefile
-
cmd/date: cmd/date.c lib/iso_parse.c Makefile
$(RM) -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
$(CC) -std=c99 $(CFLAGS) -o $@ cmd/date.c lib/iso_parse.c $(LDFLAGS) $(LDSTATIC)
@@ -183,6 +181,10 @@ cmd/expr: cmd/expr.tab.c Makefile
$(RM) -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
$(CC) -std=c99 $(CFLAGS) -D_POSIX_C_SOURCE=200809L -o $@ cmd/expr.tab.c $(LDFLAGS) $(LDSTATIC)
+cmd/cat: cmd/cat.c lib/fs.c lib/fs.h Makefile config.mk
+ $(RM) -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
+ $(CC) -std=c99 $(CFLAGS) -o $@ cmd/cat.c lib/fs.c $(LDFLAGS) $(LDSTATIC)
+
cmd/install: cmd/install.c lib/mode.c lib/user_group_parse.c lib/user_group_parse.h lib/fs.c lib/fs.h lib/lib_mkdir.c lib/lib_mkdir.h Makefile config.mk
$(RM) -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
$(CC) -std=c99 $(CFLAGS) -o $@ cmd/install.c lib/mode.c lib/user_group_parse.c lib/fs.c lib/lib_mkdir.c $(LDFLAGS) $(LDSTATIC)
diff --git a/cmd/cat.c b/cmd/cat.c
@@ -3,11 +3,12 @@
// SPDX-License-Identifier: MPL-2.0
#define _POSIX_C_SOURCE 200809L
-#define _GNU_SOURCE // splice
+#include "../lib/fs.h"
+
#include <assert.h>
#include <errno.h>
-#include <fcntl.h> // open, O_RDONLY, splice
-#include <stdint.h> // SIZE_MAX
+#include <fcntl.h> // open, O_RDONLY
+#include <limits.h> // SSIZE_MAX
#include <stdio.h> // fprintf, BUFSIZ
#include <stdlib.h> // abort
#include <string.h> // strerror, strncmp
@@ -15,72 +16,6 @@
const char *argv0 = "cat";
-static int
-concat(int fd, const char *fdname)
-{
- ssize_t c;
- char buf[BUFSIZ];
-
- assert(errno == 0);
- while((c = read(fd, buf, sizeof(buf))) > 0)
- {
- assert(errno == 0);
- if(write(STDOUT_FILENO, buf, (size_t)c) < 0)
- {
- fprintf(stderr, "%s: error: Failed writing: %s\n", argv0, strerror(errno));
- errno = 0;
- return 1;
- }
- }
-
- if(c < 0)
- {
- fprintf(
- stderr, "%s: error: Failed reading from file '%s': %s\n", argv0, fdname, strerror(errno));
- errno = 0;
- return 1;
- }
-
- return 0;
-}
-
-#ifdef HAS_SPLICE
-#define FD_COPY_SPLICE_FLAGS SPLICE_F_MOVE | SPLICE_F_NONBLOCK | SPLICE_F_MORE
-static int
-fd_copy(int fd, const char *fdname)
-{
- while(1)
- {
- assert(errno == 0);
- ssize_t ret = splice(fd, NULL, STDOUT_FILENO, NULL, SIZE_MAX, FD_COPY_SPLICE_FLAGS);
-
- if(ret == 0) break;
-
- if(ret < 0)
- {
- switch(errno)
- {
- case EINVAL:
- errno = 0;
- return concat(fd, fdname);
- case EAGAIN:
- errno = 0;
- continue;
- default:
- fprintf(
- stderr, "%s: error: Failed copying file '%s': %s\n", argv0, fdname, strerror(errno));
- errno = 0;
- return 1;
- }
- }
- }
-
- return 0;
-}
-#else // HAS_SPLICE
-#define fd_copy concat
-#endif // HAS_SPLICE
-
static void
usage(void)
{
@@ -116,8 +51,9 @@ main(int argc, char *argv[])
if(argc < 1)
{
- if(fd_copy(STDIN_FILENO, "<stdin>") != 0)
+ if(auto_fd_copy(STDIN_FILENO, STDOUT_FILENO, SSIZE_MAX) < 0)
{
+ fprintf(stderr, "%s: error: Failed copying data from <stdin>: %s\n", argv0, strerror(errno));
return 1;
}
}
@@ -127,8 +63,10 @@ main(int argc, char *argv[])
{
if(strncmp(argv[argi], "-", 2) == 0)
{
- if(fd_copy(STDIN_FILENO, "<stdin>") != 0)
+ if(auto_fd_copy(STDIN_FILENO, STDOUT_FILENO, SSIZE_MAX) < 0)
{
+ fprintf(
+ stderr, "%s: error: Failed copying data from <stdin>: %s\n", argv0, strerror(errno));
return 1;
}
}
@@ -147,8 +85,13 @@ main(int argc, char *argv[])
return 1;
}
- if(fd_copy(fd, argv[argi]) != 0)
+ if(auto_fd_copy(fd, STDOUT_FILENO, SSIZE_MAX) < 0)
{
+ fprintf(stderr,
+ "%s: error: Failed copying data from file '%s': %s\n",
+ argv0,
+ argv[argi],
+ strerror(errno));
return 1;
}
diff --git a/test-cmd/cat.sh b/test-cmd/cat.sh
@@ -38,7 +38,7 @@ fi
if [ "$(uname -s)" = "NetBSD" ]; then
skip readslash "NetBSD allows to read directories"
else
- t --exit=1 readslash / "cat: error: Failed reading from file '/': Is a directory
+ t --exit=1 readslash / "cat: error: Failed copying data from file '/': Is a directory
"
fi