|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif /* not lint */
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)cat.c 5.3 (Berkeley) 4/24/88";
15: #endif /* not lint */
16:
17: /*
18: * Concatenate files.
19: */
20:
21: #include <stdio.h>
22: #include <sys/types.h>
23: #include <sys/stat.h>
24:
25: /* #define OPTSIZE BUFSIZ /* define this only if not 4.2 BSD or beyond */
26:
27: int bflg, eflg, nflg, sflg, tflg, uflg, vflg;
28: int spaced, col, lno, inaline, ibsize, obsize;
29:
30: main(argc, argv)
31: char **argv;
32: {
33: int fflg = 0;
34: register FILE *fi;
35: register c;
36: int dev, ino = -1;
37: struct stat statb;
38: int retval = 0;
39:
40: lno = 1;
41: for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
42: switch(argv[1][1]) {
43: case 0:
44: break;
45: case 'u':
46: setbuf(stdout, (char *)NULL);
47: uflg++;
48: continue;
49: case 'n':
50: nflg++;
51: continue;
52: case 'b':
53: bflg++;
54: nflg++;
55: continue;
56: case 'v':
57: vflg++;
58: continue;
59: case 's':
60: sflg++;
61: continue;
62: case 'e':
63: eflg++;
64: vflg++;
65: continue;
66: case 't':
67: tflg++;
68: vflg++;
69: continue;
70: }
71: break;
72: }
73: if (fstat(fileno(stdout), &statb) == 0) {
74: statb.st_mode &= S_IFMT;
75: if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
76: dev = statb.st_dev;
77: ino = statb.st_ino;
78: }
79: #ifndef OPTSIZE
80: obsize = statb.st_blksize;
81: #endif
82: }
83: else
84: obsize = 0;
85: if (argc < 2) {
86: argc = 2;
87: fflg++;
88: }
89: while (--argc > 0) {
90: if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
91: fi = stdin;
92: else {
93: if ((fi = fopen(*argv, "r")) == NULL) {
94: perror(*argv);
95: retval = 1;
96: continue;
97: }
98: }
99: if (fstat(fileno(fi), &statb) == 0) {
100: if ((statb.st_mode & S_IFMT) == S_IFREG &&
101: statb.st_dev==dev && statb.st_ino==ino) {
102: fprintf(stderr, "cat: input %s is output\n",
103: fflg?"-": *argv);
104: fclose(fi);
105: retval = 1;
106: continue;
107: }
108: #ifndef OPTSIZE
109: ibsize = statb.st_blksize;
110: #endif
111: }
112: else
113: ibsize = 0;
114: if (nflg||sflg||vflg)
115: copyopt(fi);
116: else if (uflg) {
117: while ((c = getc(fi)) != EOF)
118: putchar(c);
119: } else
120: retval |= fastcat(fileno(fi)); /* no flags specified */
121: if (fi!=stdin)
122: fclose(fi);
123: else
124: clearerr(fi); /* reset sticky eof */
125: if (ferror(stdout)) {
126: fprintf(stderr, "cat: output write error\n");
127: retval = 1;
128: break;
129: }
130: }
131: exit(retval);
132: }
133:
134: copyopt(f)
135: register FILE *f;
136: {
137: register int c;
138:
139: top:
140: c = getc(f);
141: if (c == EOF)
142: return;
143: if (c == '\n') {
144: if (inaline == 0) {
145: if (sflg && spaced)
146: goto top;
147: spaced = 1;
148: }
149: if (nflg && bflg==0 && inaline == 0)
150: printf("%6d\t", lno++);
151: if (eflg)
152: putchar('$');
153: putchar('\n');
154: inaline = 0;
155: goto top;
156: }
157: if (nflg && inaline == 0)
158: printf("%6d\t", lno++);
159: inaline = 1;
160: if (vflg) {
161: if (tflg==0 && c == '\t')
162: putchar(c);
163: else {
164: if (c > 0177) {
165: printf("M-");
166: c &= 0177;
167: }
168: if (c < ' ')
169: printf("^%c", c+'@');
170: else if (c == 0177)
171: printf("^?");
172: else
173: putchar(c);
174: }
175: } else
176: putchar(c);
177: spaced = 0;
178: goto top;
179: }
180:
181: fastcat(fd)
182: register int fd;
183: {
184: register int buffsize, n, nwritten, offset;
185: register char *buff;
186: struct stat statbuff;
187: char *malloc();
188:
189: #ifndef OPTSIZE
190: if (obsize)
191: buffsize = obsize; /* common case, use output blksize */
192: else if (ibsize)
193: buffsize = ibsize;
194: else
195: buffsize = BUFSIZ;
196: #else
197: buffsize = OPTSIZE;
198: #endif
199:
200: if ((buff = malloc(buffsize)) == NULL) {
201: perror("cat: no memory");
202: return (1);
203: }
204:
205: /*
206: * Note that on some systems (V7), very large writes to a pipe
207: * return less than the requested size of the write.
208: * In this case, multiple writes are required.
209: */
210: while ((n = read(fd, buff, buffsize)) > 0) {
211: offset = 0;
212: do {
213: nwritten = write(fileno(stdout), &buff[offset], n);
214: if (nwritten <= 0) {
215: perror("cat: write error");
216: exit(2);
217: }
218: offset += nwritten;
219: } while ((n -= nwritten) > 0);
220: }
221:
222: free(buff);
223: if (n < 0) {
224: perror("cat: read error");
225: return (1);
226: }
227: return (0);
228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.