1 /* baseutils: `cat.c` - con`cat`enate and print files.
2 Copyright (c) 2022, Yusuf
3 See `LICENSE` for copyright and license details */
5 #define _POSIX_C_SOURCE 200809L
8 /* for splice() support */
18 #include <sys/param.h>
21 static const char *usage
= "cat [-u] [file...]";
23 /* amount of bytes to transfer in one iteration */
24 #define BUF_SIZE 16384
29 static char* buffer
= NULL
;
30 static int buf_sz
= 0;
35 if (fstat(file_fd
, &sbuf
) < 0) {
40 buf_sz
= MAX(BUF_SIZE
, sbuf
.st_blksize
);
41 if ((buffer
= malloc(buf_sz
)) == NULL
) {
49 n_bytes
= read(file_fd
, (void *)buffer
, buf_sz
);
53 write(fileno(stdout
), buffer
, n_bytes
);
64 // we make the assumption here that
65 // STDOUT_FD == 1, which is true on linux...
66 result
= splice(file_fd
, NULL
, 1, NULL
, BUF_SIZE
* 4, 0);
72 #define fastcat(fd) cat(fd)
76 process_file(const char* name
, int unbuf
)
80 if (strcmp(name
, "-") == 0) {
82 if (setvbuf(stdin
, NULL
, _IONBF
, 0) == EOF
)
83 fputs("cat: -u: unbuffer request failed\n", stderr
);
87 fd
= open(name
, O_RDONLY
);
92 } else if (!isatty(fd
)) {
102 main(int argc
, char *argv
[])
105 int status
, i
, u
, fd
;
107 status
= EXIT_SUCCESS
;
109 while ((ch
= getopt(argc
, argv
, "u")) != -1) {
112 if (setvbuf(stdout
, NULL
, _IONBF
, 0) == EOF
)
113 fputs("cat: -u: unbuffer request failed\n", stderr
);
118 fprintf(stderr
, "Usage:\n\t%s\n", usage
);
128 return process_file("-", u
);
131 for (i
= 0; i
< argc
; i
++) {
132 status
= process_file(argv
[i
], u
);