logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
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:

MMakefile6++++--
Mcmd/cat.c87++++++++++++++-----------------------------------------------------------------
Mtest-cmd/cat.sh2+-
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