1/* See LICENSE file for copyright and license details. */
2
3
4
5#include <fcntl.h>
6#include <string.h>
7#include <unistd.h>
8
9#include "util.h"
10
11static void
12usage(void)
13{
14 eprintf("usage: %s [-u] [file ...]\n", argv0);
15}
16
17// ?man cat: concatenate files and print to standard output
18// ?man arguments: file ...
19// ?man cat reads each file in sequence and writes it to standard output
20// ?man if no file is given, or a file is -, standard input is read
21int
22main(int argc, char *argv[])
23{
24 int fd, ret = 0;
25
26 ARGBEGIN {
27 // ?man -u: specify u option
28 case 'u':
29 // ?man -u: ignored; accepted for posix compatibility; output is always unbuffered
30 break;
31 default:
32 usage();
33 } ARGEND
34
35 if (!argc) {
36 if (concat(0, "<stdin>", 1, "<stdout>") < 0)
37 ret = 1;
38 } else {
39 for (; *argv; argc--, argv++) {
40 if (!strcmp(*argv, "-")) {
41 *argv = "<stdin>";
42 fd = 0;
43 } else if ((fd = open(*argv, O_RDONLY)) < 0) {
44 weprintf("open %s:", *argv);
45 ret = 1;
46 continue;
47 }
48 switch (concat(fd, *argv, 1, "<stdout>")) {
49 case -1:
50 ret = 1;
51 break;
52 case -2:
53 return 1; /* exit on write error */
54 }
55 if (fd != 0)
56 close(fd);
57 }
58 }
59
60 // ?man
61 // ?man ## Exit status
62 // ?man
63 // ?man cat exits 0 on success, and >0 if an error occurs reading any file
64 // ?man or writing to standard output
65 // ?man
66 // ?man ## See also
67 // ?man
68 // ?man cp(1), dd(1)
69 // ?man
70
71 return ret;
72}