xref: /original-bsd/usr.bin/tee/tee.c (revision 55330032)
1 static char *sccsid = "@(#)tee.c	4.1 (Berkeley) 10/01/80";
2 /*
3  * tee-- pipe fitting
4  */
5 
6 #include <signal.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <errno.h>
10 #include <pagsiz.h>
11 
12 #define	BUFSIZ	BSIZE
13 int openf[20] = { 1 };
14 int n = 1;
15 int t = 0;
16 int aflag;
17 
18 char in[BUFSIZ];
19 
20 char out[BUFSIZ];
21 
22 extern errno;
23 long	lseek();
24 
25 main(argc,argv)
26 char **argv;
27 {
28 	int register r,w,p;
29 	struct stat buf;
30 	while(argc>1&&argv[1][0]=='-') {
31 		switch(argv[1][1]) {
32 		case 'a':
33 			aflag++;
34 			break;
35 		case 'i':
36 		case 0:
37 			signal(SIGINT, SIG_IGN);
38 		}
39 		argv++;
40 		argc--;
41 	}
42 	fstat(1,&buf);
43 	t = (buf.st_mode&S_IFMT)==S_IFCHR;
44 	if(lseek(1,0L,1)==-1&&errno==ESPIPE)
45 		t++;
46 	while(argc-->1) {
47 		if(aflag) {
48 			openf[n] = open(argv[1],1);
49 			if(openf[n] < 0)
50 				openf[n] = creat(argv[1],0666);
51 			lseek(openf[n++],0L,2);
52 		} else
53 			openf[n++] = creat(argv[1],0666);
54 		if(stat(argv[1],&buf)>=0) {
55 			if((buf.st_mode&S_IFMT)==S_IFCHR)
56 				t++;
57 		} else {
58 			puts("tee: cannot open ");
59 			puts(argv[1]);
60 			puts("\n");
61 			n--;
62 		}
63 		argv++;
64 	}
65 	r = w = 0;
66 	for(;;) {
67 		for(p=0;p<BUFSIZ;) {
68 			if(r>=w) {
69 				if(t>0&&p>0) break;
70 				w = read(0,in,BUFSIZ);
71 				r = 0;
72 				if(w<=0) {
73 					stash(p);
74 					return;
75 				}
76 			}
77 			out[p++] = in[r++];
78 		}
79 		stash(p);
80 	}
81 }
82 
83 stash(p)
84 {
85 	int k;
86 	int i;
87 	int d;
88 	d = t ? 16 : p;
89 	for(i=0; i<p; i+=d)
90 		for(k=0;k<n;k++)
91 			write(openf[k], out+i, d<p-i?d:p-i);
92 }
93 
94 puts(s)
95 char *s;
96 {
97 	while(*s)
98 		write(2,s++,1);
99 }
100