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