Unix Tools

Implementations of common Unix command-line utilities written in C.


unix-tools / cat.c

cat.c raw | download
1#define _POSIX_C_SOURCE 200809L
2#include <fcntl.h>
3#include <unistd.h>
4#include <errno.h>
5#include <stdio.h>
6#include <string.h>
7
8static int
9cat(int fd, const char *name)
10{
11 char buf[8192];
12 for (;;) {
13 ssize_t n = read(fd, buf, sizeof(buf));
14 size_t used = 0;
15 if (n < 0 && errno == EINTR) continue;
16 if (n < 0) { perror(name); return 1; }
17 if (n == 0) return 0;
18 while (used < (size_t)n) {
19 ssize_t written = write(STDOUT_FILENO, buf + used, (size_t)n - used);
20 if (written < 0 && errno == EINTR) continue;
21 if (written <= 0) { perror("cat: stdout"); return 1; }
22 used += (size_t)written;
23 }
24 }
25}
26
27int
28main(int argc, char **argv)
29{
30 int i, status = 0;
31 if (argc == 1) return cat(STDIN_FILENO, "cat: stdin");
32 for (i = 1; i < argc; ++i) {
33 int fd = strcmp(argv[i], "-") == 0 ? STDIN_FILENO : open(argv[i], O_RDONLY);
34 if (fd < 0) { perror(argv[i]); status = 1; continue; }
35 status |= cat(fd, argv[i]);
36 if (fd != STDIN_FILENO && close(fd) < 0) { perror(argv[i]); status = 1; }
37 }
38 return status;
39}