cat(1) sizes its I/O buffer according to the st_blksize of the first file it processes. We don't do this very often in the tree. I'm not sure if we should trust st_blksize.
It would be simpler to just choose a value that works in practice and always use it. 64K works well. We settled on that for tee(1) recently. Thoughts? Index: cat.c =================================================================== RCS file: /cvs/src/bin/cat/cat.c,v retrieving revision 1.32 diff -u -p -r1.32 cat.c --- cat.c 24 Oct 2021 21:24:21 -0000 1.32 +++ cat.c 13 Dec 2021 00:57:48 -0000 @@ -33,9 +33,6 @@ * SUCH DAMAGE. */ -#include <sys/types.h> -#include <sys/stat.h> - #include <ctype.h> #include <err.h> #include <errno.h> @@ -45,7 +42,7 @@ #include <string.h> #include <unistd.h> -#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) +#define BSIZE (64 * 1024) int bflag, eflag, nflag, sflag, tflag, vflag; int rval; @@ -221,26 +218,20 @@ raw_args(char **argv) void raw_cat(int rfd, const char *filename) { - int wfd; + char *buf; ssize_t nr, nw, off; - static size_t bsize; - static char *buf = NULL; - struct stat sbuf; + int wfd; wfd = fileno(stdout); - if (buf == NULL) { - if (fstat(wfd, &sbuf) == -1) - err(1, "stdout"); - bsize = MAXIMUM(sbuf.st_blksize, BUFSIZ); - if ((buf = malloc(bsize)) == NULL) - err(1, NULL); - } - while ((nr = read(rfd, buf, bsize)) != -1 && nr != 0) { + if ((buf = malloc(BSIZE)) == NULL) + err(1, NULL); + while ((nr = read(rfd, buf, BSIZE)) != -1 && nr != 0) { for (off = 0; nr; nr -= nw, off += nw) { if ((nw = write(wfd, buf + off, nr)) == -1 || nw == 0) err(1, "stdout"); } } + free(buf); if (nr == -1) { warn("%s", filename); rval = 1;