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