logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
commit: 361d28d269624ab1e14398a756db02930dafce6f
parent c49f4e6caf8610b51b4b475023bc5a28e732d569
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Tue,  5 Nov 2024 21:29:27 +0100

cmd/wc: always use fstat in '-c' only mode

This allows to avoid a read-loop for cases like `wc -c </etc/passwd`

Diffstat:

Mcmd/wc.c40++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/cmd/wc.c b/cmd/wc.c @@ -95,8 +95,26 @@ wc_file_bytes(int fd, char *filename) } else { - while((nread = read(fd, buf, WC_BUFSIZ)) > 0) - bytes += nread; + struct stat status; + if(fstat(fd, &status) < 0) + { + fprintf(stderr, + "%s: error: Failed getting status for file '%s': %s\n", + argv0, + filename, + strerror(errno)); + return 1; + } + + if(S_ISREG(status.st_mode) && status.st_size != 0) + { + bytes += status.st_size; + } + else + { + while((nread = read(fd, buf, WC_BUFSIZ)) > 0) + bytes += nread; + } } if(nread < 0 && errno != 0) @@ -292,24 +310,6 @@ main(int argc, char *argv[]) argv0, path); - if(wc_opts == WC_OPT_C && wc_file == wc_file_bytes) - { - struct stat status; - if(stat(path, &status) < 0) - { - fprintf(stderr, - "%s: error: Failed getting status for file '%s': %s\n", - argv0, - path, - strerror(errno)); - return 1; - } - - printf("%ld %s\n", status.st_size, path); - total_bytes += status.st_size; - continue; - } - int arg_fd = open(path, O_RDONLY | O_NOCTTY); if(arg_fd < 0) {