]> pd.if.org Git - pdutils/blob - utils/cat/cat.c
Added implementations from pdcore
[pdutils] / utils / cat / cat.c
1 /*
2  * cat.c - concatenate file(s) to standard output
3  *
4  * Version: 2008-1.01
5  * Build:   c89 -o cat cat.c
6  * Source:  <http://pdcore.sourceforge.net/>
7  * Spec:    <http://www.opengroup.org/onlinepubs/9699919799/utilities/cat.html>
8  *
9  * This is free and unencumbered software released into the public domain,
10  * provided "as is", without warranty of any kind, express or implied. See the
11  * file UNLICENSE and the website <http://unlicense.org> for further details.
12  */
13
14
15 #define _POSIX_SOURCE
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <locale.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #define USAGE   "usage: cat [-u] [file ...]\n"
26 #define BUFSIZE 4096
27
28 static void catfile(int fd, char *fn);
29 static void error(char *s);
30
31 static int exitstatus;
32 static int optu;
33
34
35 int main(int argc, char **argv)
36 {
37     extern int opterr, optind;
38     int c, fd;
39     char *fn;
40
41     setlocale(LC_ALL, "");
42     opterr = 0;
43
44     while ((c = getopt(argc, argv, "u")) != -1)
45         switch (c)
46         {
47         case 'u':
48             optu = 1;
49             break;
50         default:
51             fprintf(stderr, USAGE);
52             return(1);
53         }
54
55     if (optind >= argc)
56         catfile(STDIN_FILENO, "stdin");
57     else
58         while (optind < argc)
59         {
60             fn = argv[optind++];
61
62             if (strcmp(fn, "-") == 0)
63                 catfile(STDIN_FILENO, "stdin");
64             else
65                 if ((fd = open(fn, O_RDONLY)) == -1)
66                     error(fn);
67                 else
68                 {
69                     catfile(fd, fn);
70                     if (close(fd) == -1)
71                         error(fn);
72                 }
73         }
74
75     return(exitstatus);
76 }
77
78
79 void catfile(int fd, char *fn)
80 {
81     unsigned char buf[BUFSIZE];
82     ssize_t n;
83
84     while ((n = read(fd, buf, (optu ? 1 : BUFSIZE))) > 0)
85         if (write(STDOUT_FILENO, buf, (size_t)n) != n)
86         {
87             error("stdout");
88             break;
89         }
90
91     if (n < 0)
92         error(fn);
93 }
94
95
96 void error(char *s)
97 {
98     fprintf(stderr, "cat: %s: %s\n", s, strerror(errno));
99     exitstatus = 1;
100 }