1/*
2 * cat replacement
3 *
4 * no options - the way cat was intended
5 */
6
7#include <fcntl.h>
8#include <errno.h>
9
10#include "builtins.h"
11#include "shell.h"
12
13#ifndef errno
14extern int errno;
15#endif
16
17extern char *strerror ();
18extern char **make_builtin_argv ();
19
20static int
21fcopy(fd)
22int	fd;
23{
24	char	buf[1024], *s;
25	int	n, w, e;
26
27	while (n = read(fd, buf, sizeof (buf))) {
28		w = write(1, buf, n);
29		if (w != n) {
30			e = errno;
31			write(2, "cat: write error: ", 18);
32			s = strerror(e);
33			write(2, s, strlen(s));
34			write(2, "\n", 1);
35			return 1;
36		}
37	}
38	return 0;
39}
40
41cat_main (argc, argv)
42int	argc;
43char	**argv;
44{
45	int	i, fd, r;
46	char	*s;
47
48	if (argc == 1)
49		return (fcopy(0));
50
51	for (i = r = 1; i < argc; i++) {
52		if (argv[i][0] == '-' && argv[i][1] == '\0')
53			fd = 0;
54		else {
55			fd = open(argv[i], O_RDONLY, 0666);
56			if (fd < 0) {
57				s = strerror(errno);
58				write(2, "cat: cannot open ", 17);
59				write(2, argv[i], strlen(argv[i]));
60				write(2, ": ", 2);
61				write(2, s, strlen(s));
62				write(2, "\n", 1);
63				continue;
64			}
65		}
66		r = fcopy(fd);
67		if (fd != 0)
68			close(fd);
69	}
70	return (r);
71}
72
73cat_builtin(list)
74WORD_LIST *list;
75{
76	char	**v;
77	int	c, r;
78
79	v = make_builtin_argv(list, &c);
80	r = cat_main(c, v);
81	free(v);
82
83	return r;
84}
85
86char *cat_doc[] = {
87	"Read each FILE and display it on the standard output.   If any",
88	"FILE is `-' or if no FILE argument is given, the standard input",
89	"is read.",
90	(char *)0
91};
92
93struct builtin cat_struct = {
94	"cat",
95	cat_builtin,
96	BUILTIN_ENABLED,
97	cat_doc,
98	"cat [-] [file ...]",
99	0
100};
101