Deleted Added
full compact
cat.c (59239) cat.c (78732)
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kevin Fall.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38static char const copyright[] =
39"@(#) Copyright (c) 1989, 1993\n\
40 The Regents of the University of California. All rights reserved.\n";
41#endif /* not lint */
42
43#ifndef lint
44#if 0
45static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95";
46#endif
47static const char rcsid[] =
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kevin Fall.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38static char const copyright[] =
39"@(#) Copyright (c) 1989, 1993\n\
40 The Regents of the University of California. All rights reserved.\n";
41#endif /* not lint */
42
43#ifndef lint
44#if 0
45static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95";
46#endif
47static const char rcsid[] =
48 "$FreeBSD: head/bin/cat/cat.c 59239 2000-04-14 21:01:35Z asmodai $";
48 "$FreeBSD: head/bin/cat/cat.c 78732 2001-06-24 23:04:23Z dd $";
49#endif /* not lint */
50
51#include <sys/param.h>
52#include <sys/stat.h>
53
54#include <ctype.h>
55#include <err.h>
56#include <fcntl.h>
57#include <locale.h>
58#include <stdio.h>
59#include <stdlib.h>
49#endif /* not lint */
50
51#include <sys/param.h>
52#include <sys/stat.h>
53
54#include <ctype.h>
55#include <err.h>
56#include <fcntl.h>
57#include <locale.h>
58#include <stdio.h>
59#include <stdlib.h>
60#include <string.h>
60#include <unistd.h>
61
62int bflag, eflag, nflag, sflag, tflag, vflag;
63int rval;
64const char *filename;
65
66void cook_args __P((char *argv[]));
67void cook_buf __P((FILE *));
68int main __P((int argc, char *argv[]));
69void raw_args __P((char *argv[]));
70void raw_cat __P((int));
71
72int
73main(argc, argv)
74 int argc;
75 char *argv[];
76{
77 int ch;
78
79 setlocale(LC_CTYPE, "");
80
81 while ((ch = getopt(argc, argv, "benstuv")) != -1)
82 switch (ch) {
83 case 'b':
84 bflag = nflag = 1; /* -b implies -n */
85 break;
86 case 'e':
87 eflag = vflag = 1; /* -e implies -v */
88 break;
89 case 'n':
90 nflag = 1;
91 break;
92 case 's':
93 sflag = 1;
94 break;
95 case 't':
96 tflag = vflag = 1; /* -t implies -v */
97 break;
98 case 'u':
99 setbuf(stdout, NULL);
100 break;
101 case 'v':
102 vflag = 1;
103 break;
104 default:
105 (void)fprintf(stderr,
106 "usage: cat [-benstuv] [-] [file ...]\n");
107 exit(1);
108 }
109 argv += optind;
110
111 if (bflag || eflag || nflag || sflag || tflag || vflag)
112 cook_args(argv);
113 else
114 raw_args(argv);
115 if (fclose(stdout))
116 err(1, "stdout");
117 exit(rval);
118}
119
120void
121cook_args(argv)
122 char **argv;
123{
124 register FILE *fp;
125
126 fp = stdin;
127 filename = "stdin";
128 do {
129 if (*argv) {
130 if (!strcmp(*argv, "-"))
131 fp = stdin;
132 else if ((fp = fopen(*argv, "r")) == NULL) {
133 warn("%s", *argv);
134 rval = 1;
135 ++argv;
136 continue;
137 }
138 filename = *argv++;
139 }
140 cook_buf(fp);
141 if (fp != stdin)
142 (void)fclose(fp);
143 } while (*argv);
144}
145
146void
147cook_buf(fp)
148 register FILE *fp;
149{
150 register int ch, gobble, line, prev;
151
152 line = gobble = 0;
153 for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
154 if (prev == '\n') {
155 if (ch == '\n') {
156 if (sflag) {
157 if (!gobble && putchar(ch) == EOF)
158 break;
159 gobble = 1;
160 continue;
161 }
162 if (nflag && !bflag) {
163 (void)fprintf(stdout, "%6d\t", ++line);
164 if (ferror(stdout))
165 break;
166 }
167 } else if (nflag) {
168 (void)fprintf(stdout, "%6d\t", ++line);
169 if (ferror(stdout))
170 break;
171 }
172 }
173 gobble = 0;
174 if (ch == '\n') {
175 if (eflag)
176 if (putchar('$') == EOF)
177 break;
178 } else if (ch == '\t') {
179 if (tflag) {
180 if (putchar('^') == EOF || putchar('I') == EOF)
181 break;
182 continue;
183 }
184 } else if (vflag) {
185 if (!isascii(ch) && !isprint(ch)) {
186 if (putchar('M') == EOF || putchar('-') == EOF)
187 break;
188 ch = toascii(ch);
189 }
190 if (iscntrl(ch)) {
191 if (putchar('^') == EOF ||
192 putchar(ch == '\177' ? '?' :
193 ch | 0100) == EOF)
194 break;
195 continue;
196 }
197 }
198 if (putchar(ch) == EOF)
199 break;
200 }
201 if (ferror(fp)) {
202 warn("%s", filename);
203 rval = 1;
204 clearerr(fp);
205 }
206 if (ferror(stdout))
207 err(1, "stdout");
208}
209
210void
211raw_args(argv)
212 char **argv;
213{
214 register int fd;
215
216 fd = fileno(stdin);
217 filename = "stdin";
218 do {
219 if (*argv) {
220 if (!strcmp(*argv, "-"))
221 fd = fileno(stdin);
222 else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
223 warn("%s", *argv);
224 rval = 1;
225 ++argv;
226 continue;
227 }
228 filename = *argv++;
229 }
230 raw_cat(fd);
231 if (fd != fileno(stdin))
232 (void)close(fd);
233 } while (*argv);
234}
235
236void
237raw_cat(rfd)
238 register int rfd;
239{
240 register int off, wfd;
241 ssize_t nr, nw;
242 static size_t bsize;
243 static char *buf;
244 struct stat sbuf;
245
246 wfd = fileno(stdout);
247 if (buf == NULL) {
248 if (fstat(wfd, &sbuf))
249 err(1, "%s", filename);
250 bsize = MAX(sbuf.st_blksize, 1024);
251 if ((buf = malloc(bsize)) == NULL)
252 err(1, "buffer");
253 }
254 while ((nr = read(rfd, buf, bsize)) > 0)
255 for (off = 0; nr; nr -= nw, off += nw)
256 if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
257 err(1, "stdout");
258 if (nr < 0) {
259 warn("%s", filename);
260 rval = 1;
261 }
262}
61#include <unistd.h>
62
63int bflag, eflag, nflag, sflag, tflag, vflag;
64int rval;
65const char *filename;
66
67void cook_args __P((char *argv[]));
68void cook_buf __P((FILE *));
69int main __P((int argc, char *argv[]));
70void raw_args __P((char *argv[]));
71void raw_cat __P((int));
72
73int
74main(argc, argv)
75 int argc;
76 char *argv[];
77{
78 int ch;
79
80 setlocale(LC_CTYPE, "");
81
82 while ((ch = getopt(argc, argv, "benstuv")) != -1)
83 switch (ch) {
84 case 'b':
85 bflag = nflag = 1; /* -b implies -n */
86 break;
87 case 'e':
88 eflag = vflag = 1; /* -e implies -v */
89 break;
90 case 'n':
91 nflag = 1;
92 break;
93 case 's':
94 sflag = 1;
95 break;
96 case 't':
97 tflag = vflag = 1; /* -t implies -v */
98 break;
99 case 'u':
100 setbuf(stdout, NULL);
101 break;
102 case 'v':
103 vflag = 1;
104 break;
105 default:
106 (void)fprintf(stderr,
107 "usage: cat [-benstuv] [-] [file ...]\n");
108 exit(1);
109 }
110 argv += optind;
111
112 if (bflag || eflag || nflag || sflag || tflag || vflag)
113 cook_args(argv);
114 else
115 raw_args(argv);
116 if (fclose(stdout))
117 err(1, "stdout");
118 exit(rval);
119}
120
121void
122cook_args(argv)
123 char **argv;
124{
125 register FILE *fp;
126
127 fp = stdin;
128 filename = "stdin";
129 do {
130 if (*argv) {
131 if (!strcmp(*argv, "-"))
132 fp = stdin;
133 else if ((fp = fopen(*argv, "r")) == NULL) {
134 warn("%s", *argv);
135 rval = 1;
136 ++argv;
137 continue;
138 }
139 filename = *argv++;
140 }
141 cook_buf(fp);
142 if (fp != stdin)
143 (void)fclose(fp);
144 } while (*argv);
145}
146
147void
148cook_buf(fp)
149 register FILE *fp;
150{
151 register int ch, gobble, line, prev;
152
153 line = gobble = 0;
154 for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
155 if (prev == '\n') {
156 if (ch == '\n') {
157 if (sflag) {
158 if (!gobble && putchar(ch) == EOF)
159 break;
160 gobble = 1;
161 continue;
162 }
163 if (nflag && !bflag) {
164 (void)fprintf(stdout, "%6d\t", ++line);
165 if (ferror(stdout))
166 break;
167 }
168 } else if (nflag) {
169 (void)fprintf(stdout, "%6d\t", ++line);
170 if (ferror(stdout))
171 break;
172 }
173 }
174 gobble = 0;
175 if (ch == '\n') {
176 if (eflag)
177 if (putchar('$') == EOF)
178 break;
179 } else if (ch == '\t') {
180 if (tflag) {
181 if (putchar('^') == EOF || putchar('I') == EOF)
182 break;
183 continue;
184 }
185 } else if (vflag) {
186 if (!isascii(ch) && !isprint(ch)) {
187 if (putchar('M') == EOF || putchar('-') == EOF)
188 break;
189 ch = toascii(ch);
190 }
191 if (iscntrl(ch)) {
192 if (putchar('^') == EOF ||
193 putchar(ch == '\177' ? '?' :
194 ch | 0100) == EOF)
195 break;
196 continue;
197 }
198 }
199 if (putchar(ch) == EOF)
200 break;
201 }
202 if (ferror(fp)) {
203 warn("%s", filename);
204 rval = 1;
205 clearerr(fp);
206 }
207 if (ferror(stdout))
208 err(1, "stdout");
209}
210
211void
212raw_args(argv)
213 char **argv;
214{
215 register int fd;
216
217 fd = fileno(stdin);
218 filename = "stdin";
219 do {
220 if (*argv) {
221 if (!strcmp(*argv, "-"))
222 fd = fileno(stdin);
223 else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
224 warn("%s", *argv);
225 rval = 1;
226 ++argv;
227 continue;
228 }
229 filename = *argv++;
230 }
231 raw_cat(fd);
232 if (fd != fileno(stdin))
233 (void)close(fd);
234 } while (*argv);
235}
236
237void
238raw_cat(rfd)
239 register int rfd;
240{
241 register int off, wfd;
242 ssize_t nr, nw;
243 static size_t bsize;
244 static char *buf;
245 struct stat sbuf;
246
247 wfd = fileno(stdout);
248 if (buf == NULL) {
249 if (fstat(wfd, &sbuf))
250 err(1, "%s", filename);
251 bsize = MAX(sbuf.st_blksize, 1024);
252 if ((buf = malloc(bsize)) == NULL)
253 err(1, "buffer");
254 }
255 while ((nr = read(rfd, buf, bsize)) > 0)
256 for (off = 0; nr; nr -= nw, off += nw)
257 if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
258 err(1, "stdout");
259 if (nr < 0) {
260 warn("%s", filename);
261 rval = 1;
262 }
263}