xref: /plan9/sys/src/cmd/tee.c (revision 54c2bd792d4fd2b6c8a639d9ff9cb2b057113e00)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * tee-- pipe fitting
33e12c5d1SDavid du Colombier  */
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier #include <u.h>
63e12c5d1SDavid du Colombier #include <libc.h>
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier int	uflag;
93e12c5d1SDavid du Colombier int	aflag;
10*54c2bd79SDavid du Colombier int	*openf;
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier char in[8192];
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier int	intignore(void*, char*);
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier void
main(int argc,char ** argv)173e12c5d1SDavid du Colombier main(int argc, char **argv)
183e12c5d1SDavid du Colombier {
197dd7cddfSDavid du Colombier 	int i;
203e12c5d1SDavid du Colombier 	int r, n;
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier 	ARGBEGIN {
233e12c5d1SDavid du Colombier 	case 'a':
243e12c5d1SDavid du Colombier 		aflag++;
253e12c5d1SDavid du Colombier 		break;
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier 	case 'i':
283e12c5d1SDavid du Colombier 		atnotify(intignore, 1);
293e12c5d1SDavid du Colombier 		break;
303e12c5d1SDavid du Colombier 
313e12c5d1SDavid du Colombier 	case 'u':
323e12c5d1SDavid du Colombier 		uflag++;
337dd7cddfSDavid du Colombier 		/* uflag is ignored and undocumented; it's a relic from Unix */
343e12c5d1SDavid du Colombier 		break;
357dd7cddfSDavid du Colombier 
367dd7cddfSDavid du Colombier 	default:
377dd7cddfSDavid du Colombier 		fprint(2, "usage: tee [-ai] [file ...]\n");
387dd7cddfSDavid du Colombier 		exits("usage");
397dd7cddfSDavid du Colombier 	} ARGEND
403e12c5d1SDavid du Colombier 
41*54c2bd79SDavid du Colombier 	openf = malloc((1+argc)*sizeof(int));
42*54c2bd79SDavid du Colombier 	if(openf == nil)
43*54c2bd79SDavid du Colombier 		sysfatal("out of memory: %r");
44*54c2bd79SDavid du Colombier 
453e12c5d1SDavid du Colombier 	n = 0;
463e12c5d1SDavid du Colombier 	while(*argv) {
473e12c5d1SDavid du Colombier 		if(aflag) {
483e12c5d1SDavid du Colombier 			openf[n] = open(argv[0], OWRITE);
493e12c5d1SDavid du Colombier 			if(openf[n] < 0)
503e12c5d1SDavid du Colombier 				openf[n] = create(argv[0], OWRITE, 0666);
513e12c5d1SDavid du Colombier 			seek(openf[n], 0L, 2);
523e12c5d1SDavid du Colombier 		} else
533e12c5d1SDavid du Colombier 			openf[n] = create(argv[0], OWRITE, 0666);
543e12c5d1SDavid du Colombier 		if(openf[n] < 0) {
557dd7cddfSDavid du Colombier 			fprint(2, "tee: cannot open %s: %r\n", argv[0]);
563e12c5d1SDavid du Colombier 		} else
573e12c5d1SDavid du Colombier 			n++;
583e12c5d1SDavid du Colombier 		argv++;
593e12c5d1SDavid du Colombier 	}
603e12c5d1SDavid du Colombier 	openf[n++] = 1;
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier 	for(;;) {
633e12c5d1SDavid du Colombier 		r = read(0, in, sizeof in);
643e12c5d1SDavid du Colombier 		if(r <= 0)
657dd7cddfSDavid du Colombier 			exits(nil);
663e12c5d1SDavid du Colombier 		for(i=0; i<n; i++)
673e12c5d1SDavid du Colombier 			write(openf[i], in, r);
683e12c5d1SDavid du Colombier 	}
693e12c5d1SDavid du Colombier }
703e12c5d1SDavid du Colombier 
713e12c5d1SDavid du Colombier int
intignore(void * a,char * msg)723e12c5d1SDavid du Colombier intignore(void *a, char *msg)
733e12c5d1SDavid du Colombier {
743e12c5d1SDavid du Colombier 	USED(a);
753e12c5d1SDavid du Colombier 	if(strcmp(msg, "interrupt") == 0)
763e12c5d1SDavid du Colombier 		return 1;
773e12c5d1SDavid du Colombier 	return 0;
783e12c5d1SDavid du Colombier }
79